Back to index

tetex-bin  3.0
Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes
JPXStream Class Reference

#include <JPXStream.h>

Inheritance diagram for JPXStream:
Inheritance graph
[legend]
Collaboration diagram for JPXStream:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 JPXStream (Stream *strA)
virtual ~JPXStream ()
virtual StreamKind getKind ()
virtual void reset ()
virtual int getChar ()
virtual int lookChar ()
virtual GStringgetPSFilter (int psLevel, char *indent)
virtual GBool isBinary (GBool last=gTrue)
virtual void close ()
virtual int getPos ()
virtual void setPos (Guint pos, int dir=0)
virtual BaseStreamgetBaseStream ()
virtual DictgetDict ()
virtual void ignoreLength ()
int incRef ()
int decRef ()
virtual int getRawChar ()
virtual char * getLine (char *buf, int size)
virtual GBool isEncoder ()
StreamaddFilters (Object *dict)

Protected Attributes

Streamstr

Private Member Functions

void fillReadBuf ()
GBool readBoxes ()
GBool readColorSpecBox (Guint dataLen)
GBool readCodestream (Guint len)
GBool readTilePart ()
GBool readTilePartData (Guint tileIdx, Guint tilePartLen, GBool tilePartToEOC)
GBool readCodeBlockData (JPXTileComp *tileComp, JPXResLevel *resLevel, JPXPrecinct *precinct, JPXSubband *subband, Guint res, Guint sb, JPXCodeBlock *cb)
void inverseTransform (JPXTileComp *tileComp)
void inverseTransformLevel (JPXTileComp *tileComp, Guint r, JPXResLevel *resLevel, Guint nx0, Guint ny0, Guint nx1, Guint ny1)
void inverseTransform1D (JPXTileComp *tileComp, int *data, Guint stride, Guint i0, Guint i1)
GBool inverseMultiCompAndDC (JPXTile *tile)
GBool readBoxHdr (Guint *boxType, Guint *boxLen, Guint *dataLen)
int readMarkerHdr (int *segType, Guint *segLen)
GBool readUByte (Guint *x)
GBool readByte (int *x)
GBool readUWord (Guint *x)
GBool readULong (Guint *x)
GBool readNBytes (int nBytes, GBool signd, int *x)
GBool readBits (int nBits, Guint *x)
void clearBitBuf ()

Private Attributes

Guint nComps
Guintbpc
Guint width
Guint height
GBool haveImgHdr
JPXColorSpec cs
GBool haveCS
JPXPalette palette
GBool havePalette
JPXCompMap compMap
GBool haveCompMap
JPXChannelDefn channelDefn
GBool haveChannelDefn
JPXImage img
Guint bitBuf
int bitBufLen
GBool bitBufSkip
Guint byteCount
Guint curX
Guint curY
Guint curComp
Guint readBuf
Guint readBufLen

Detailed Description

Definition at line 267 of file JPXStream.h.


Constructor & Destructor Documentation

JPXStream::~JPXStream ( ) [virtual]

Definition at line 197 of file JPXStream.cc.

                      {
  JPXTile *tile;
  JPXTileComp *tileComp;
  JPXResLevel *resLevel;
  JPXPrecinct *precinct;
  JPXSubband *subband;
  JPXCodeBlock *cb;
  Guint comp, i, k, r, pre, sb;

  gfree(bpc);
  if (havePalette) {
    gfree(palette.bpc);
    gfree(palette.c);
  }
  if (haveCompMap) {
    gfree(compMap.comp);
    gfree(compMap.type);
    gfree(compMap.pComp);
  }
  if (haveChannelDefn) {
    gfree(channelDefn.idx);
    gfree(channelDefn.type);
    gfree(channelDefn.assoc);
  }

  if (img.tiles) {
    for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
      tile = &img.tiles[i];
      if (tile->tileComps) {
       for (comp = 0; comp < img.nComps; ++comp) {
         tileComp = &tile->tileComps[comp];
         gfree(tileComp->quantSteps);
         gfree(tileComp->data);
         gfree(tileComp->buf);
         if (tileComp->resLevels) {
           for (r = 0; r <= tileComp->nDecompLevels; ++r) {
             resLevel = &tileComp->resLevels[r];
             if (resLevel->precincts) {
              for (pre = 0; pre < 1; ++pre) {
                precinct = &resLevel->precincts[pre];
                if (precinct->subbands) {
                  for (sb = 0; sb < (r == 0 ? 1 : 3); ++sb) {
                    subband = &precinct->subbands[sb];
                    gfree(subband->inclusion);
                    gfree(subband->zeroBitPlane);
                    if (subband->cbs) {
                     for (k = 0; k < subband->nXCBs * subband->nYCBs; ++k) {
                       cb = &subband->cbs[k];
                       gfree(cb->coeffs);
                       if (cb->stats) {
                         delete cb->stats;
                       }
                     }
                     gfree(subband->cbs);
                    }
                  }
                  gfree(precinct->subbands);
                }
              }
              gfree(img.tiles[i].tileComps[comp].resLevels[r].precincts);
             }
           }
           gfree(img.tiles[i].tileComps[comp].resLevels);
         }
       }
       gfree(img.tiles[i].tileComps);
      }
    }
    gfree(img.tiles);
  }
  delete str;
}

Here is the call graph for this function:


Member Function Documentation

Stream * Stream::addFilters ( Object dict) [inherited]

Definition at line 92 of file Stream.cc.

                                       {
  Object obj, obj2;
  Object params, params2;
  Stream *str;
  int i;

  str = this;
  dict->dictLookup("Filter", &obj);
  if (obj.isNull()) {
    obj.free();
    dict->dictLookup("F", &obj);
  }
  dict->dictLookup("DecodeParms", &params);
  if (params.isNull()) {
    params.free();
    dict->dictLookup("DP", &params);
  }
  if (obj.isName()) {
    str = makeFilter(obj.getName(), str, &params);
  } else if (obj.isArray()) {
    for (i = 0; i < obj.arrayGetLength(); ++i) {
      obj.arrayGet(i, &obj2);
      if (params.isArray())
       params.arrayGet(i, &params2);
      else
       params2.initNull();
      if (obj2.isName()) {
       str = makeFilter(obj2.getName(), str, &params2);
      } else {
       error(getPos(), "Bad filter name");
       str = new EOFStream(str);
      }
      obj2.free();
      params2.free();
    }
  } else if (!obj.isNull()) {
    error(getPos(), "Bad 'Filter' attribute in stream");
  }
  obj.free();
  params.free();

  return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2818 of file JPXStream.cc.

Here is the caller graph for this function:

void FilterStream::close ( ) [virtual, inherited]

Reimplemented from Stream.

Definition at line 306 of file Stream.cc.

                         {
  str->close();
}

Here is the call graph for this function:

int Stream::decRef ( ) [inline, inherited]

Definition at line 58 of file Stream.h.

{ return --ref; }

Definition at line 322 of file JPXStream.cc.

                            {
  JPXTileComp *tileComp;
  Guint tileIdx, tx, ty;
  int pix, pixBits;

  do {
    if (curY >= img.ySize) {
      return;
    }
    tileIdx = ((curY - img.yTileOffset) / img.yTileSize) * img.nXTiles
              + (curX - img.xTileOffset) / img.xTileSize;
#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
    tileComp = &img.tiles[tileIdx].tileComps[curComp];
#else
    tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
#endif
    tx = jpxCeilDiv((curX - img.xTileOffset) % img.xTileSize, tileComp->hSep);
    ty = jpxCeilDiv((curY - img.yTileOffset) % img.yTileSize, tileComp->vSep);
    pix = (int)tileComp->data[ty * (tileComp->x1 - tileComp->x0) + tx];
    pixBits = tileComp->prec;
#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
    if (++curComp == img.nComps) {
#else
    if (havePalette) {
      if (pix >= 0 && pix < palette.nEntries) {
       pix = palette.c[pix * palette.nComps + curComp];
      } else {
       pix = 
      pixBits = palette.bpc[curComp];
    }
    if (++curComp == (Guint)(havePalette ? palette.nComps : img.nComps)) {
#endif
      curComp = 0;
      if (++curX == img.xSize) {
       curX = img.xOffset;
       ++curY;
      }
    }
    if (pixBits == 8) {
      readBuf = (readBuf << 8) | (pix & 0xff);
    } else {
      readBuf = (readBuf << pixBits) | (pix & ((1 << pixBits) - 1));
    }
    readBufLen += pixBits;
  } while (readBufLen < 8);
}

Here is the caller graph for this function:

virtual BaseStream* FilterStream::getBaseStream ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 174 of file Stream.h.

{ return str->getBaseStream(); }

Here is the call graph for this function:

int JPXStream::getChar ( ) [virtual]

Implements Stream.

Definition at line 283 of file JPXStream.cc.

                       {
  int c;

  if (readBufLen < 8) {
    fillReadBuf();
  }
  if (readBufLen == 8) {
    c = readBuf & 0xff;
    readBufLen = 0;
  } else if (readBufLen > 8) {
    c = (readBuf >> (readBufLen - 8)) & 0xff;
    readBufLen -= 8;
  } else if (readBufLen == 0) {
    c = EOF;
  } else {
    c = (readBuf << (8 - readBufLen)) & 0xff;
    readBufLen = 0;
  }
  return c;
}

Here is the call graph for this function:

virtual Dict* FilterStream::getDict ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 175 of file Stream.h.

{ return str->getDict(); }

Here is the call graph for this function:

virtual StreamKind JPXStream::getKind ( ) [inline, virtual]

Implements Stream.

Definition at line 272 of file JPXStream.h.

{ return strJPX; }
char * Stream::getLine ( char *  buf,
int  size 
) [virtual, inherited]

Definition at line 67 of file Stream.cc.

                                         {
  int i;
  int c;

  if (lookChar() == EOF)
    return NULL;
  for (i = 0; i < size - 1; ++i) {
    c = getChar();
    if (c == EOF || c == '\n')
      break;
    if (c == '\r') {
      if ((c = lookChar()) == '\n')
       getChar();
      break;
    }
    buf[i] = c;
  }
  buf[i] = '\0';
  return buf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual int FilterStream::getPos ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 172 of file Stream.h.

{ return str->getPos(); }

Here is the call graph for this function:

GString * JPXStream::getPSFilter ( int  psLevel,
char *  indent 
) [virtual]

Reimplemented from Stream.

Definition at line 369 of file JPXStream.cc.

                                                         {
  return NULL;
}
int Stream::getRawChar ( ) [virtual, inherited]

Reimplemented in FlateStream, and LZWStream.

Definition at line 62 of file Stream.cc.

                       {
  error(-1, "Internal: called getRawChar() on non-predictor stream");
  return EOF;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void FilterStream::ignoreLength ( ) [inline, virtual, inherited]

Reimplemented from Stream.

Definition at line 176 of file Stream.h.

{ str->ignoreLength(); }

Here is the call graph for this function:

int Stream::incRef ( ) [inline, inherited]

Definition at line 57 of file Stream.h.

{ return ++ref; }

Definition at line 2579 of file JPXStream.cc.

                                                    {
  JPXTileComp *tileComp;
  int coeff, d0, d1, d2, minVal, maxVal, zeroVal;
  int *dataPtr;
  Guint j, comp, x, y;

  //----- inverse multi-component transform

  if (tile->multiComp == 1) {
    if (img.nComps < 3 ||
       tile->tileComps[0].hSep != tile->tileComps[1].hSep ||
       tile->tileComps[0].vSep != tile->tileComps[1].vSep ||
       tile->tileComps[1].hSep != tile->tileComps[2].hSep ||
       tile->tileComps[1].vSep != tile->tileComps[2].vSep) {
      return gFalse;
    }

    // inverse irreversible multiple component transform
    if (tile->tileComps[0].transform == 0) {
      j = 0;
      for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
       for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
         d0 = tile->tileComps[0].data[j];
         d1 = tile->tileComps[1].data[j];
         d2 = tile->tileComps[2].data[j];
         tile->tileComps[0].data[j] = (int)(d0 + 1.402 * d2 + 0.5);
         tile->tileComps[1].data[j] =
             (int)(d0 - 0.34413 * d1 - 0.71414 * d2 + 0.5);
         tile->tileComps[2].data[j] = (int)(d0 + 1.772 * d1 + 0.5);
         ++j;
       }
      }

    // inverse reversible multiple component transform
    } else {
      j = 0;
      for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
       for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
         d0 = tile->tileComps[0].data[j];
         d1 = tile->tileComps[1].data[j];
         d2 = tile->tileComps[2].data[j];
         tile->tileComps[0].data[j] = d0 - ((d2 + d1) >> 2);
         tile->tileComps[1].data[j] = d2 - d1;
         tile->tileComps[2].data[j] = d0 - d1;
         ++j;
       }
      }
    }
  }

  //----- DC level shift
  for (comp = 0; comp < img.nComps; ++comp) {
    tileComp = &tile->tileComps[comp];

    // signed: clip
    if (tileComp->sgned) {
      minVal = -(1 << (tileComp->prec - 1));
      maxVal = (1 << (tileComp->prec - 1)) - 1;
      dataPtr = tileComp->data;
      for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) {
       for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
         coeff = *dataPtr;
         if (tileComp->transform == 0) {
           coeff >>= fracBits;
         }
         if (coeff < minVal) {
           coeff = minVal;
         } else if (coeff > maxVal) {
           coeff = maxVal;
         }
         *dataPtr++ = coeff;
       }
      }

    // unsigned: inverse DC level shift and clip
    } else {
      maxVal = (1 << tileComp->prec) - 1;
      zeroVal = 1 << (tileComp->prec - 1);
      dataPtr = tileComp->data;
      for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) {
       for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
         coeff = *dataPtr;
         if (tileComp->transform == 0) {
           coeff >>= fracBits;
         }
         coeff += zeroVal;
         if (coeff < 0) {
           coeff = 0;
         } else if (coeff > maxVal) {
           coeff = maxVal;
         }
         *dataPtr++ = coeff;
       }
      }
    }
  }

  return gTrue;
}

Here is the caller graph for this function:

void JPXStream::inverseTransform ( JPXTileComp tileComp) [private]

Definition at line 2263 of file JPXStream.cc.

                                                      {
  JPXResLevel *resLevel;
  JPXPrecinct *precinct;
  JPXSubband *subband;
  JPXCodeBlock *cb;
  JPXCoeff *coeff0, *coeff;
  Guint qStyle, guard, eps, shift, shift2;
  double mu;
  int val;
  int *dataPtr;
  Guint nx0, ny0, nx1, ny1;
  Guint r, cbX, cbY, x, y;

  //----- (NL)LL subband (resolution level 0)

  resLevel = &tileComp->resLevels[0];
  precinct = &resLevel->precincts[0];
  subband = &precinct->subbands[0];

  // i-quant parameters
  qStyle = tileComp->quantStyle & 0x1f;
  guard = (tileComp->quantStyle >> 5) & 7;
  if (qStyle == 0) {
    eps = (tileComp->quantSteps[0] >> 3) & 0x1f;
    shift = guard + eps - 1;
    mu = 0; // make gcc happy
  } else {
    shift = guard - 1 + tileComp->prec;
    mu = (double)(0x800 + (tileComp->quantSteps[0] & 0x7ff)) / 2048.0;
  }
  if (tileComp->transform == 0) {
    shift += fracBits;
  }

  // copy (NL)LL into the upper-left corner of the data array, doing
  // the fixed point adjustment and dequantization along the way
  cb = subband->cbs;
  for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
    for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
      for (y = cb->y0, coeff0 = cb->coeffs;
          y < cb->y1;
          ++y, coeff0 += tileComp->cbW) {
       dataPtr = &tileComp->data[(y - subband->y0)
                              * (tileComp->x1 - tileComp->x0)
                              + (cb->x0 - subband->x0)];
       for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) {
         val = (int)coeff->mag;
         if (val != 0) {
           shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
           if (shift2 > 0) {
             val = (val << shift2) + (1 << (shift2 - 1));
           } else {
             val >>= -shift2;
           }
           if (qStyle == 0) {
             if (tileComp->transform == 0) {
              val &= -1 << fracBits;
             }
           } else {
             val = (int)((double)val * mu);
           }
           if (coeff->flags & jpxCoeffSign) {
             val = -val;
           }
         }
         *dataPtr++ = val;
       }
      }
      ++cb;
    }
  }

  //----- IDWT for each level

  for (r = 1; r <= tileComp->nDecompLevels; ++r) {
    resLevel = &tileComp->resLevels[r];

    // (n)LL is already in the upper-left corner of the
    // tile-component data array -- interleave with (n)HL/LH/HH
    // and inverse transform to get (n-1)LL, which will be stored
    // in the upper-left corner of the tile-component data array
    if (r == tileComp->nDecompLevels) {
      nx0 = tileComp->x0;
      ny0 = tileComp->y0;
      nx1 = tileComp->x1;
      ny1 = tileComp->y1;
    } else {
      nx0 = tileComp->resLevels[r+1].x0;
      ny0 = tileComp->resLevels[r+1].y0;
      nx1 = tileComp->resLevels[r+1].x1;
      ny1 = tileComp->resLevels[r+1].y1;
    }
    inverseTransformLevel(tileComp, r, resLevel, nx0, ny0, nx1, ny1);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JPXStream::inverseTransform1D ( JPXTileComp tileComp,
int data,
Guint  stride,
Guint  i0,
Guint  i1 
) [private]

Definition at line 2475 of file JPXStream.cc.

                                                   {
  int *buf;
  Guint offset, end, i;

  //----- special case for length = 1
  if (i1 - i0 == 1) {
    if (i0 & 1) {
      *data >>= 1;
    }

  } else {

    // choose an offset: this makes even buf[] indexes correspond to
    // odd values of i, and vice versa
    offset = 3 + (i0 & 1);
    end = offset + i1 - i0;

    //----- gather
    buf = tileComp->buf;
    for (i = 0; i < i1 - i0; ++i) {
      buf[offset + i] = data[i * stride];
    }

    //----- extend right
    buf[end] = buf[end - 2];
    if (i1 - i0 == 2) {
      buf[end+1] = buf[offset + 1];
      buf[end+2] = buf[offset];
      buf[end+3] = buf[offset + 1];
    } else {
      buf[end+1] = buf[end - 3];
      if (i1 - i0 == 3) {
       buf[end+2] = buf[offset + 1];
       buf[end+3] = buf[offset + 2];
      } else {
       buf[end+2] = buf[end - 4];
       if (i1 - i0 == 4) {
         buf[end+3] = buf[offset + 1];
       } else {
         buf[end+3] = buf[end - 5];
       }
      }
    }

    //----- extend left
    buf[offset - 1] = buf[offset + 1];
    buf[offset - 2] = buf[offset + 2];
    buf[offset - 3] = buf[offset + 3];
    if (offset == 4) {
      buf[0] = buf[offset + 4];
    }

    //----- 9-7 irreversible filter

    if (tileComp->transform == 0) {
      // step 1 (even)
      for (i = 1; i <= end + 2; i += 2) {
       buf[i] = (int)(idwtKappa * buf[i]);
      }
      // step 2 (odd)
      for (i = 0; i <= end + 3; i += 2) {
       buf[i] = (int)(idwtIKappa * buf[i]);
      }
      // step 3 (even)
      for (i = 1; i <= end + 2; i += 2) {
       buf[i] = (int)(buf[i] - idwtDelta * (buf[i-1] + buf[i+1]));
      }
      // step 4 (odd)
      for (i = 2; i <= end + 1; i += 2) {
       buf[i] = (int)(buf[i] - idwtGamma * (buf[i-1] + buf[i+1]));
      }
      // step 5 (even)
      for (i = 3; i <= end; i += 2) {
       buf[i] = (int)(buf[i] - idwtBeta * (buf[i-1] + buf[i+1]));
      }
      // step 6 (odd)
      for (i = 4; i <= end - 1; i += 2) {
       buf[i] = (int)(buf[i] - idwtAlpha * (buf[i-1] + buf[i+1]));
      }

    //----- 5-3 reversible filter

    } else {
      // step 1 (even)
      for (i = 3; i <= end; i += 2) {
       buf[i] -= (buf[i-1] + buf[i+1] + 2) >> 2;
      }
      // step 2 (odd)
      for (i = 4; i < end; i += 2) {
       buf[i] += (buf[i-1] + buf[i+1]) >> 1;
      }
    }

    //----- scatter
    for (i = 0; i < i1 - i0; ++i) {
      data[i * stride] = buf[offset + i];
    }
  }
}

Here is the caller graph for this function:

void JPXStream::inverseTransformLevel ( JPXTileComp tileComp,
Guint  r,
JPXResLevel resLevel,
Guint  nx0,
Guint  ny0,
Guint  nx1,
Guint  ny1 
) [private]

Definition at line 2363 of file JPXStream.cc.

                                                        {
  JPXPrecinct *precinct;
  JPXSubband *subband;
  JPXCodeBlock *cb;
  JPXCoeff *coeff0, *coeff;
  Guint qStyle, guard, eps, shift, shift2, t;
  double mu;
  int val;
  int *dataPtr;
  Guint xo, yo;
  Guint x, y, sb, cbX, cbY;
  int xx, yy;

  //----- interleave

  // spread out LL
  for (yy = resLevel->y1 - 1; yy >= (int)resLevel->y0; --yy) {
    for (xx = resLevel->x1 - 1; xx >= (int)resLevel->x0; --xx) {
      tileComp->data[(2 * yy - ny0) * (tileComp->x1 - tileComp->x0)
                   + (2 * xx - nx0)] =
         tileComp->data[(yy - resLevel->y0) * (tileComp->x1 - tileComp->x0)
                      + (xx - resLevel->x0)];
    }
  }

  // i-quant parameters
  qStyle = tileComp->quantStyle & 0x1f;
  guard = (tileComp->quantStyle >> 5) & 7;

  // interleave HL/LH/HH
  precinct = &resLevel->precincts[0];
  for (sb = 0; sb < 3; ++sb) {

    // i-quant parameters
    if (qStyle == 0) {
      eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f;
      shift = guard + eps - 1;
      mu = 0; // make gcc happy
    } else {
      shift = guard + tileComp->prec;
      if (sb == 2) {
       ++shift;
      }
      t = tileComp->quantSteps[qStyle == 1 ? 0 : (3*r - 2 + sb)];
      mu = (double)(0x800 + (t & 0x7ff)) / 2048.0;
    }
    if (tileComp->transform == 0) {
      shift += fracBits;
    }

    // copy the subband coefficients into the data array, doing the
    // fixed point adjustment and dequantization along the way
    xo = (sb & 1) ? 0 : 1;
    yo = (sb > 0) ? 1 : 0;
    subband = &precinct->subbands[sb];
    cb = subband->cbs;
    for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
      for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
       for (y = cb->y0, coeff0 = cb->coeffs;
            y < cb->y1;
            ++y, coeff0 += tileComp->cbW) {
         dataPtr = &tileComp->data[(2 * y + yo - ny0)
                                * (tileComp->x1 - tileComp->x0)
                                + (2 * cb->x0 + xo - nx0)];
         for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) {
           val = (int)coeff->mag;
           if (val != 0) {
             shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
             if (shift2 > 0) {
              val = (val << shift2) + (1 << (shift2 - 1));
             } else {
              val >>= -shift2;
             }
             if (qStyle == 0) {
              if (tileComp->transform == 0) {
                val &= -1 << fracBits;
              }
             } else {
              val = (int)((double)val * mu);
             }
             if (coeff->flags & jpxCoeffSign) {
              val = -val;
             }
           }
           *dataPtr = val;
           dataPtr += 2;
         }
       }
       ++cb;
      }
    }
  }

  //----- horizontal (row) transforms
  dataPtr = tileComp->data;
  for (y = 0; y < ny1 - ny0; ++y) {
    inverseTransform1D(tileComp, dataPtr, 1, nx0, nx1);
    dataPtr += tileComp->x1 - tileComp->x0;
  }

  //----- vertical (column) transforms
  dataPtr = tileComp->data;
  for (x = 0; x < nx1 - nx0; ++x) {
    inverseTransform1D(tileComp, dataPtr,
                     tileComp->x1 - tileComp->x0, ny0, ny1);
    ++dataPtr;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::isBinary ( GBool  last = gTrue) [virtual]

Implements Stream.

Definition at line 373 of file JPXStream.cc.

                                    {
  return str->isBinary(gTrue);
}

Here is the call graph for this function:

virtual GBool Stream::isEncoder ( ) [inline, virtual, inherited]

Reimplemented in RunLengthEncoder, ASCII85Encoder, ASCIIHexEncoder, and FixedLengthEncoder.

Definition at line 103 of file Stream.h.

{ return gFalse; }

Here is the caller graph for this function:

int JPXStream::lookChar ( ) [virtual]

Implements Stream.

Definition at line 304 of file JPXStream.cc.

                        {
  int c;

  if (readBufLen < 8) {
    fillReadBuf();
  }
  if (readBufLen == 8) {
    c = readBuf & 0xff;
  } else if (readBufLen > 8) {
    c = (readBuf >> (readBufLen - 8)) & 0xff;
  } else if (readBufLen == 0) {
    c = EOF;
  } else {
    c = (readBuf << (8 - readBufLen)) & 0xff;
  }
  return c;
}

Here is the call graph for this function:

GBool JPXStream::readBits ( int  nBits,
Guint x 
) [private]

Definition at line 2796 of file JPXStream.cc.

                                             {
  int c;

  while (bitBufLen < nBits) {
    if ((c = str->getChar()) == EOF) {
      return gFalse;
    }
    ++byteCount;
    if (bitBufSkip) {
      bitBuf = (bitBuf << 7) | (c & 0x7f);
      bitBufLen += 7;
    } else {
      bitBuf = (bitBuf << 8) | (c & 0xff);
      bitBufLen += 8;
    }
    bitBufSkip = c == 0xff;
  }
  *x = (bitBuf >> (bitBufLen - nBits)) & ((1 << nBits) - 1);
  bitBufLen -= nBits;
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readBoxes ( ) [private]

Definition at line 377 of file JPXStream.cc.

                           {
  Guint boxType, boxLen, dataLen;
  Guint bpc1, compression, unknownColorspace, ipr;
  Guint i, j;

  haveImgHdr = gFalse;

  // check for a naked JPEG 2000 codestream (without the JP2/JPX
  // wrapper) -- this appears to be a violation of the PDF spec, but
  // Acrobat allows it
  if (str->lookChar() == 0xff) {
    error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
    readCodestream(0);
    nComps = img.nComps;
    bpc = (Guint *)gmalloc(nComps * sizeof(Guint));
    for (i = 0; i < nComps; ++i) {
      bpc[i] = img.tiles[0].tileComps[i].prec;
    }
    width = img.xSize - img.xOffset;
    height = img.ySize - img.yOffset;
    return gTrue;
  }

  while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
    switch (boxType) {
    case 0x6a703268:        // JP2 header
      // this is a grouping box ('superbox') which has no real
      // contents and doesn't appear to be used consistently, i.e.,
      // some things which should be subboxes of the JP2 header box
      // show up outside of it - so we simply ignore the JP2 header
      // box
      break;
    case 0x69686472:        // image header
      if (!readULong(&height) ||
         !readULong(&width) ||
         !readUWord(&nComps) ||
         !readUByte(&bpc1) ||
         !readUByte(&compression) ||
         !readUByte(&unknownColorspace) ||
         !readUByte(&ipr)) {
       error(getPos(), "Unexpected EOF in JPX stream");
       return gFalse;
      }
      if (compression != 7) {
       error(getPos(), "Unknown compression type in JPX stream");
       return gFalse;
      }
      bpc = (Guint *)gmalloc(nComps * sizeof(Guint));
      for (i = 0; i < nComps; ++i) {
       bpc[i] = bpc1;
      }
      haveImgHdr = gTrue;
      break;
    case 0x62706363:        // bits per component
      if (!haveImgHdr) {
       error(getPos(), "Found bits per component box before image header box in JPX stream");
       return gFalse;
      }
      if (dataLen != nComps) {
       error(getPos(), "Invalid bits per component box in JPX stream");
       return gFalse;
      }
      for (i = 0; i < nComps; ++i) {
       if (!readUByte(&bpc[i])) {
         error(getPos(), "Unexpected EOF in JPX stream");
         return gFalse;
       }
      }
      break;
    case 0x636F6C72:        // color specification
      if (!readColorSpecBox(dataLen)) {
       return gFalse;
      }
      break;
    case 0x70636c72:        // palette
      if (!readUWord(&palette.nEntries) ||
         !readUByte(&palette.nComps)) {
       error(getPos(), "Unexpected EOF in JPX stream");
       return gFalse;
      }
      palette.bpc = (Guint *)gmalloc(palette.nComps * sizeof(Guint));
      palette.c =
          (int *)gmalloc(palette.nEntries * palette.nComps * sizeof(int));
      for (i = 0; i < palette.nComps; ++i) {
       if (!readUByte(&palette.bpc[i])) {
         error(getPos(), "Unexpected EOF in JPX stream");
         return gFalse;
       }
       ++palette.bpc[i];
      }
      for (i = 0; i < palette.nEntries; ++i) {
       for (j = 0; j < palette.nComps; ++j) {
         if (!readNBytes(((palette.bpc[j] & 0x7f) + 7) >> 3,
                       (palette.bpc[j] & 0x80) ? gTrue : gFalse,
                       &palette.c[i * palette.nComps + j])) {
           error(getPos(), "Unexpected EOF in JPX stream");
           return gFalse;
         }
       }
      }
      havePalette = gTrue;
      break;
    case 0x636d6170:        // component mapping
      compMap.nChannels = dataLen / 4;
      compMap.comp = (Guint *)gmalloc(compMap.nChannels * sizeof(Guint));
      compMap.type = (Guint *)gmalloc(compMap.nChannels * sizeof(Guint));
      compMap.pComp = (Guint *)gmalloc(compMap.nChannels * sizeof(Guint));
      for (i = 0; i < compMap.nChannels; ++i) {
       if (!readUWord(&compMap.comp[i]) ||
           !readUByte(&compMap.type[i]) ||
           !readUByte(&compMap.pComp[i])) {
         error(getPos(), "Unexpected EOF in JPX stream");
         return gFalse;
       }
      }
      haveCompMap = gTrue;
      break;
    case 0x63646566:        // channel definition
      if (!readUWord(&channelDefn.nChannels)) {
       error(getPos(), "Unexpected EOF in JPX stream");
       return gFalse;
      }
      channelDefn.idx =
         (Guint *)gmalloc(channelDefn.nChannels * sizeof(Guint));
      channelDefn.type =
         (Guint *)gmalloc(channelDefn.nChannels * sizeof(Guint));
      channelDefn.assoc =
         (Guint *)gmalloc(channelDefn.nChannels * sizeof(Guint));
      for (i = 0; i < channelDefn.nChannels; ++i) {
       if (!readUWord(&channelDefn.idx[i]) ||
           !readUWord(&channelDefn.type[i]) ||
           !readUWord(&channelDefn.assoc[i])) {
         error(getPos(), "Unexpected EOF in JPX stream");
         return gFalse;
       }
      }
      haveChannelDefn = gTrue;
      break;
    case 0x6A703263:        // contiguous codestream
      if (!bpc) {
       error(getPos(), "JPX stream is missing the image header box");
       return gFalse;
      }
      if (!haveCS) {
       error(getPos(), "JPX stream has no supported color spec");
       return gFalse;
      }
      if (!readCodestream(dataLen)) {
       return gFalse;
      }
      break;
    default:
      for (i = 0; i < dataLen; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Unexpected EOF in JPX stream");
         return gFalse;
       }
      }
      break;
    }
  }
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readBoxHdr ( Guint boxType,
Guint boxLen,
Guint dataLen 
) [private]

Definition at line 2679 of file JPXStream.cc.

                                                                         {
  Guint len, lenH;

  if (!readULong(&len) ||
      !readULong(boxType)) {
    return gFalse;
  }
  if (len == 1) {
    if (!readULong(&lenH) || !readULong(&len)) {
      return gFalse;
    }
    if (lenH) {
      error(getPos(), "JPX stream contains a box larger than 2^32 bytes");
      return gFalse;
    }
    *boxLen = len;
    *dataLen = len - 16;
  } else if (len == 0) {
    *boxLen = 0;
    *dataLen = 0;
  } else {
    *boxLen = len;
    *dataLen = len - 8;
  }
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readByte ( int x) [private]

Definition at line 2740 of file JPXStream.cc.

                                {
 int c0;

  if ((c0 = str->getChar()) == EOF) {
    return gFalse;
  }
  *x = c0;
  if (c0 & 0x80) {
    *x |= -1 - 0xff;
  }
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readCodeBlockData ( JPXTileComp tileComp,
JPXResLevel resLevel,
JPXPrecinct precinct,
JPXSubband subband,
Guint  res,
Guint  sb,
JPXCodeBlock cb 
) [private]

Definition at line 1959 of file JPXStream.cc.

                                                 {
  JPXCoeff *coeff0, *coeff1, *coeff;
  JArithmeticDecoder *arithDecoder;
  Guint horiz, vert, diag, all, cx, xorBit;
  int horizSign, vertSign;
  Guint i, x, y0, y1, y2;

  arithDecoder = new JArithmeticDecoder();
  arithDecoder->setStream(str, cb->dataLen);
  arithDecoder->start();

  for (i = 0; i < cb->nCodingPasses; ++i) {
    switch (cb->nextPass) {

    //----- significance propagation pass
    case jpxPassSigProp:
      for (y0 = cb->y0, coeff0 = cb->coeffs;
          y0 < cb->y1;
          y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
       for (x = cb->x0, coeff1 = coeff0;
            x < cb->x1;
            ++x, ++coeff1) {
         for (y1 = 0, coeff = coeff1;
              y1 < 4 && y0+y1 < cb->y1;
              ++y1, coeff += tileComp->cbW) {
           if (!(coeff->flags & jpxCoeffSignificant)) {
             horiz = vert = diag = 0;
             horizSign = vertSign = 2;
             if (x > cb->x0) {
              if (coeff[-1].flags & jpxCoeffSignificant) {
                ++horiz;
                horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1;
              }
              if (y0+y1 > cb->y0) {
                diag += (coeff[-tileComp->cbW - 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
              if (y0+y1 < cb->y1 - 1) {
                diag += (coeff[tileComp->cbW - 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
             }
             if (x < cb->x1 - 1) {
              if (coeff[1].flags & jpxCoeffSignificant) {
                ++horiz;
                horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1;
              }
              if (y0+y1 > cb->y0) {
                diag += (coeff[-tileComp->cbW + 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
              if (y0+y1 < cb->y1 - 1) {
                diag += (coeff[tileComp->cbW + 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
             }
             if (y0+y1 > cb->y0) {
              if (coeff[-tileComp->cbW].flags & jpxCoeffSignificant) {
                ++vert;
                vertSign += (coeff[-tileComp->cbW].flags & jpxCoeffSign)
                            ? -1 : 1;
              }
             }
             if (y0+y1 < cb->y1 - 1) {
              if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) {
                ++vert;
                vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign)
                            ? -1 : 1;
              }
             }
             cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
             if (cx != 0) {
              if (arithDecoder->decodeBit(cx, cb->stats)) {
                coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
                coeff->mag = (coeff->mag << 1) | 1;
                cx = signContext[horizSign][vertSign][0];
                xorBit = signContext[horizSign][vertSign][1];
                if (arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
                  coeff->flags |= jpxCoeffSign;
                }
              }
              ++coeff->len;
              coeff->flags |= jpxCoeffTouched;
             }
           }
         }
       }
      }
      ++cb->nextPass;
      break;

    //----- magnitude refinement pass
    case jpxPassMagRef:
      for (y0 = cb->y0, coeff0 = cb->coeffs;
          y0 < cb->y1;
          y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
       for (x = cb->x0, coeff1 = coeff0;
            x < cb->x1;
            ++x, ++coeff1) {
         for (y1 = 0, coeff = coeff1;
              y1 < 4 && y0+y1 < cb->y1;
              ++y1, coeff += tileComp->cbW) {
           if ((coeff->flags & jpxCoeffSignificant) &&
              !(coeff->flags & jpxCoeffTouched)) {
             if (coeff->flags & jpxCoeffFirstMagRef) {
              all = 0;
              if (x > cb->x0) {
                all += (coeff[-1].flags >> jpxCoeffSignificantB) & 1;
                if (y0+y1 > cb->y0) {
                  all += (coeff[-tileComp->cbW - 1].flags
                         >> jpxCoeffSignificantB) & 1;
                }
                if (y0+y1 < cb->y1 - 1) {
                  all += (coeff[tileComp->cbW - 1].flags
                         >> jpxCoeffSignificantB) & 1;
                }
              }
              if (x < cb->x1 - 1) {
                all += (coeff[1].flags >> jpxCoeffSignificantB) & 1;
                if (y0+y1 > cb->y0) {
                  all += (coeff[-tileComp->cbW + 1].flags
                         >> jpxCoeffSignificantB) & 1;
                }
                if (y0+y1 < cb->y1 - 1) {
                  all += (coeff[tileComp->cbW + 1].flags
                         >> jpxCoeffSignificantB) & 1;
                }
              }
              if (y0+y1 > cb->y0) {
                all += (coeff[-tileComp->cbW].flags
                       >> jpxCoeffSignificantB) & 1;
              }
              if (y0+y1 < cb->y1 - 1) {
                all += (coeff[tileComp->cbW].flags
                       >> jpxCoeffSignificantB) & 1;
              }
              cx = all ? 15 : 14;
             } else {
              cx = 16;
             }
             coeff->mag = (coeff->mag << 1) |
                         arithDecoder->decodeBit(cx, cb->stats);
             ++coeff->len;
             coeff->flags |= jpxCoeffTouched;
             coeff->flags &= ~jpxCoeffFirstMagRef;
           }
         }
       }
      }
      ++cb->nextPass;
      break;

    //----- cleanup pass
    case jpxPassCleanup:
      for (y0 = cb->y0, coeff0 = cb->coeffs;
          y0 < cb->y1;
          y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
       for (x = cb->x0, coeff1 = coeff0;
            x < cb->x1;
            ++x, ++coeff1) {
         y1 = 0;
         if (y0 + 3 < cb->y1 &&
             !(coeff1->flags & jpxCoeffTouched) &&
             !(coeff1[tileComp->cbW].flags & jpxCoeffTouched) &&
             !(coeff1[2 * tileComp->cbW].flags & jpxCoeffTouched) &&
             !(coeff1[3 * tileComp->cbW].flags & jpxCoeffTouched) &&
             (x == cb->x0 || y0 == cb->y0 ||
              !(coeff1[-tileComp->cbW - 1].flags
               & jpxCoeffSignificant)) &&
             (y0 == cb->y0 ||
              !(coeff1[-tileComp->cbW].flags & jpxCoeffSignificant)) &&
             (x == cb->x1 - 1 || y0 == cb->y0 ||
              !(coeff1[-tileComp->cbW + 1].flags & jpxCoeffSignificant)) &&
             (x == cb->x0 ||
              (!(coeff1[-1].flags & jpxCoeffSignificant) &&
              !(coeff1[tileComp->cbW - 1].flags
                & jpxCoeffSignificant) &&
              !(coeff1[2 * tileComp->cbW - 1].flags
                & jpxCoeffSignificant) && 
              !(coeff1[3 * tileComp->cbW - 1].flags
                & jpxCoeffSignificant))) &&
             (x == cb->x1 - 1 ||
              (!(coeff1[1].flags & jpxCoeffSignificant) &&
              !(coeff1[tileComp->cbW + 1].flags
                & jpxCoeffSignificant) &&
              !(coeff1[2 * tileComp->cbW + 1].flags
                & jpxCoeffSignificant) &&
              !(coeff1[3 * tileComp->cbW + 1].flags
                & jpxCoeffSignificant))) &&
             (x == cb->x0 || y0+4 == cb->y1 ||
              !(coeff1[4 * tileComp->cbW - 1].flags & jpxCoeffSignificant)) &&
             (y0+4 == cb->y1 ||
              !(coeff1[4 * tileComp->cbW].flags & jpxCoeffSignificant)) &&
             (x == cb->x1 - 1 || y0+4 == cb->y1 ||
              !(coeff1[4 * tileComp->cbW + 1].flags
               & jpxCoeffSignificant))) {
           if (arithDecoder->decodeBit(jpxContextRunLength, cb->stats)) {
             y1 = arithDecoder->decodeBit(jpxContextUniform, cb->stats);
             y1 = (y1 << 1) |
                 arithDecoder->decodeBit(jpxContextUniform, cb->stats);
             for (y2 = 0, coeff = coeff1;
                 y2 < y1;
                 ++y2, coeff += tileComp->cbW) {
              ++coeff->len;
             }
             coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
             coeff->mag = (coeff->mag << 1) | 1;
             ++coeff->len;
             cx = signContext[2][2][0];
             xorBit = signContext[2][2][1];
             if (arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
              coeff->flags |= jpxCoeffSign;
             }
             ++y1;
           } else {
             for (y1 = 0, coeff = coeff1;
                 y1 < 4;
                 ++y1, coeff += tileComp->cbW) {
              ++coeff->len;
             }
             y1 = 4;
           }
         }
         for (coeff = &coeff1[y1 << tileComp->codeBlockW];
              y1 < 4 && y0 + y1 < cb->y1;
              ++y1, coeff += tileComp->cbW) {
           if (!(coeff->flags & jpxCoeffTouched)) {
             horiz = vert = diag = 0;
             horizSign = vertSign = 2;
             if (x > cb->x0) {
              if (coeff[-1].flags & jpxCoeffSignificant) {
                ++horiz;
                horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1;
              }
              if (y0+y1 > cb->y0) {
                diag += (coeff[-tileComp->cbW - 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
              if (y0+y1 < cb->y1 - 1) {
                diag += (coeff[tileComp->cbW - 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
             }
             if (x < cb->x1 - 1) {
              if (coeff[1].flags & jpxCoeffSignificant) {
                ++horiz;
                horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1;
              }
              if (y0+y1 > cb->y0) {
                diag += (coeff[-tileComp->cbW + 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
              if (y0+y1 < cb->y1 - 1) {
                diag += (coeff[tileComp->cbW + 1].flags
                        >> jpxCoeffSignificantB) & 1;
              }
             }
             if (y0+y1 > cb->y0) {
              if (coeff[-tileComp->cbW].flags & jpxCoeffSignificant) {
                ++vert;
                vertSign += (coeff[-tileComp->cbW].flags & jpxCoeffSign)
                            ? -1 : 1;
              }
             }
             if (y0+y1 < cb->y1 - 1) {
              if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) {
                ++vert;
                vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign)
                            ? -1 : 1;
              }
             }
             cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
             if (arithDecoder->decodeBit(cx, cb->stats)) {
              coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
              coeff->mag = (coeff->mag << 1) | 1;
              cx = signContext[horizSign][vertSign][0];
              xorBit = signContext[horizSign][vertSign][1];
              if (arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
                coeff->flags |= jpxCoeffSign;
              }
             }
             ++coeff->len;
           } else {
             coeff->flags &= ~jpxCoeffTouched;
           }
         }
       }
      }
      cb->nextPass = jpxPassSigProp;
      break;
    }
  }

  delete arithDecoder;
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 663 of file JPXStream.cc.

                                         {
  JPXTile *tile;
  JPXTileComp *tileComp;
  int segType;
  GBool haveSIZ, haveCOD, haveQCD, haveSOT;
  Guint precinctSize, style;
  Guint segLen, capabilities, comp, i, j, r;

  //----- main header
  haveSIZ = haveCOD = haveQCD = haveSOT = gFalse;
  do {
    if (!readMarkerHdr(&segType, &segLen)) {
      error(getPos(), "Error in JPX codestream");
      return gFalse;
    }
    switch (segType) {
    case 0x4f:                     // SOC - start of codestream
      // marker only
      break;
    case 0x51:                     // SIZ - image and tile size
      if (!readUWord(&capabilities) ||
         !readULong(&img.xSize) ||
         !readULong(&img.ySize) ||
         !readULong(&img.xOffset) ||
         !readULong(&img.yOffset) ||
         !readULong(&img.xTileSize) ||
         !readULong(&img.yTileSize) ||
         !readULong(&img.xTileOffset) ||
         !readULong(&img.yTileOffset) ||
         !readUWord(&img.nComps)) {
       error(getPos(), "Error in JPX SIZ marker segment");
       return gFalse;
      }
      if (haveImgHdr && img.nComps != nComps) {
       error(getPos(), "Different number of components in JPX SIZ marker segment");
       return gFalse;
      }
      img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
                   / img.xTileSize;
      img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
                   / img.yTileSize;
      img.tiles = (JPXTile *)gmalloc(img.nXTiles * img.nYTiles *
                                 sizeof(JPXTile));
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
       img.tiles[i].tileComps = (JPXTileComp *)gmalloc(img.nComps *
                                                 sizeof(JPXTileComp));
       for (comp = 0; comp < img.nComps; ++comp) {
         img.tiles[i].tileComps[comp].quantSteps = NULL;
         img.tiles[i].tileComps[comp].data = NULL;
         img.tiles[i].tileComps[comp].buf = NULL;
         img.tiles[i].tileComps[comp].resLevels = NULL;
       }
      }
      for (comp = 0; comp < img.nComps; ++comp) {
       if (!readUByte(&img.tiles[0].tileComps[comp].prec) ||
           !readUByte(&img.tiles[0].tileComps[comp].hSep) ||
           !readUByte(&img.tiles[0].tileComps[comp].vSep)) {
         error(getPos(), "Error in JPX SIZ marker segment");
         return gFalse;
       }
       img.tiles[0].tileComps[comp].sgned =
           (img.tiles[0].tileComps[comp].prec & 0x80) ? gTrue : gFalse;
       img.tiles[0].tileComps[comp].prec =
           (img.tiles[0].tileComps[comp].prec & 0x7f) + 1;
       for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
         img.tiles[i].tileComps[comp] = img.tiles[0].tileComps[comp];
       }
      }
      haveSIZ = gTrue;
      break;
    case 0x52:                     // COD - coding style default
      if (!readUByte(&img.tiles[0].tileComps[0].style) ||
         !readUByte(&img.tiles[0].progOrder) ||
         !readUWord(&img.tiles[0].nLayers) ||
         !readUByte(&img.tiles[0].multiComp) ||
         !readUByte(&img.tiles[0].tileComps[0].nDecompLevels) ||
         !readUByte(&img.tiles[0].tileComps[0].codeBlockW) ||
         !readUByte(&img.tiles[0].tileComps[0].codeBlockH) ||
         !readUByte(&img.tiles[0].tileComps[0].codeBlockStyle) ||
         !readUByte(&img.tiles[0].tileComps[0].transform)) {
       error(getPos(), "Error in JPX COD marker segment");
       return gFalse;
      }
      img.tiles[0].tileComps[0].codeBlockW += 2;
      img.tiles[0].tileComps[0].codeBlockH += 2;
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
       if (i != 0) {
         img.tiles[i].progOrder = img.tiles[0].progOrder;
         img.tiles[i].nLayers = img.tiles[0].nLayers;
         img.tiles[i].multiComp = img.tiles[0].multiComp;
       }
       for (comp = 0; comp < img.nComps; ++comp) {
         if (!(i == 0 && comp == 0)) {
           img.tiles[i].tileComps[comp].style =
               img.tiles[0].tileComps[0].style;
           img.tiles[i].tileComps[comp].nDecompLevels =
               img.tiles[0].tileComps[0].nDecompLevels;
           img.tiles[i].tileComps[comp].codeBlockW =
               img.tiles[0].tileComps[0].codeBlockW;
           img.tiles[i].tileComps[comp].codeBlockH =
               img.tiles[0].tileComps[0].codeBlockH;
           img.tiles[i].tileComps[comp].codeBlockStyle =
               img.tiles[0].tileComps[0].codeBlockStyle;
           img.tiles[i].tileComps[comp].transform =
               img.tiles[0].tileComps[0].transform;
         }
         img.tiles[i].tileComps[comp].resLevels =
             (JPXResLevel *)gmalloc(
                   (img.tiles[i].tileComps[comp].nDecompLevels + 1) *
                   sizeof(JPXResLevel));
         for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
           img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
         }
       }
      }
      for (r = 0; r <= img.tiles[0].tileComps[0].nDecompLevels; ++r) {
       if (img.tiles[0].tileComps[0].style & 0x01) {
         if (!readUByte(&precinctSize)) {
           error(getPos(), "Error in JPX COD marker segment");
           return gFalse;
         }
         img.tiles[0].tileComps[0].resLevels[r].precinctWidth =
             precinctSize & 0x0f;
         img.tiles[0].tileComps[0].resLevels[r].precinctHeight =
             (precinctSize >> 4) & 0x0f;
       } else {
         img.tiles[0].tileComps[0].resLevels[r].precinctWidth = 15;
         img.tiles[0].tileComps[0].resLevels[r].precinctHeight = 15;
       }
      }
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
       for (comp = 0; comp < img.nComps; ++comp) {
         if (!(i == 0 && comp == 0)) {
           for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
             img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
                img.tiles[0].tileComps[0].resLevels[r].precinctWidth;
             img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
                img.tiles[0].tileComps[0].resLevels[r].precinctHeight;
           }
         }
       }
      }
      haveCOD = gTrue;
      break;
    case 0x53:                     // COC - coding style component
      if (!haveCOD) {
       error(getPos(), "JPX COC marker segment before COD segment");
       return gFalse;
      }
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&style) ||
         !readUByte(&img.tiles[0].tileComps[comp].nDecompLevels) ||
         !readUByte(&img.tiles[0].tileComps[comp].codeBlockW) ||
         !readUByte(&img.tiles[0].tileComps[comp].codeBlockH) ||
         !readUByte(&img.tiles[0].tileComps[comp].codeBlockStyle) ||
         !readUByte(&img.tiles[0].tileComps[comp].transform)) {
       error(getPos(), "Error in JPX COC marker segment");
       return gFalse;
      }
      img.tiles[0].tileComps[comp].style =
         (img.tiles[0].tileComps[comp].style & ~1) | (style & 1);
      img.tiles[0].tileComps[comp].codeBlockW += 2;
      img.tiles[0].tileComps[comp].codeBlockH += 2;
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
       if (i != 0) {
         img.tiles[i].tileComps[comp].style =
             img.tiles[0].tileComps[comp].style;
         img.tiles[i].tileComps[comp].nDecompLevels =
             img.tiles[0].tileComps[comp].nDecompLevels;
         img.tiles[i].tileComps[comp].codeBlockW =
             img.tiles[0].tileComps[comp].codeBlockW;
         img.tiles[i].tileComps[comp].codeBlockH =
             img.tiles[0].tileComps[comp].codeBlockH;
         img.tiles[i].tileComps[comp].codeBlockStyle =
             img.tiles[0].tileComps[comp].codeBlockStyle;
         img.tiles[i].tileComps[comp].transform =
             img.tiles[0].tileComps[comp].transform;
       }
       img.tiles[i].tileComps[comp].resLevels =
           (JPXResLevel *)grealloc(
                   img.tiles[i].tileComps[comp].resLevels,
                   (img.tiles[i].tileComps[comp].nDecompLevels + 1) *
                     sizeof(JPXResLevel));
       for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
         img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
       }
      }
      for (r = 0; r <= img.tiles[0].tileComps[comp].nDecompLevels; ++r) {
       if (img.tiles[0].tileComps[comp].style & 0x01) {
         if (!readUByte(&precinctSize)) {
           error(getPos(), "Error in JPX COD marker segment");
           return gFalse;
         }
         img.tiles[0].tileComps[comp].resLevels[r].precinctWidth =
             precinctSize & 0x0f;
         img.tiles[0].tileComps[comp].resLevels[r].precinctHeight =
             (precinctSize >> 4) & 0x0f;
       } else {
         img.tiles[0].tileComps[comp].resLevels[r].precinctWidth = 15;
         img.tiles[0].tileComps[comp].resLevels[r].precinctHeight = 15;
       }
      }
      for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
       for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
         img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
             img.tiles[0].tileComps[comp].resLevels[r].precinctWidth;
         img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
             img.tiles[0].tileComps[comp].resLevels[r].precinctHeight;
       }
      }
      break;
    case 0x5c:                     // QCD - quantization default
      if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) {
       error(getPos(), "Error in JPX QCD marker segment");
       return gFalse;
      }
      if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x00) {
       img.tiles[0].tileComps[0].nQuantSteps = segLen - 3;
       img.tiles[0].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[0].quantSteps,
                           img.tiles[0].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
         if (!readUByte(&img.tiles[0].tileComps[0].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x01) {
       img.tiles[0].tileComps[0].nQuantSteps = 1;
       img.tiles[0].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[0].quantSteps,
                           img.tiles[0].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[0])) {
         error(getPos(), "Error in JPX QCD marker segment");
         return gFalse;
       }
      } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x02) {
       img.tiles[0].tileComps[0].nQuantSteps = (segLen - 3) / 2;
       img.tiles[0].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[0].quantSteps,
                           img.tiles[0].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
         if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else {
       error(getPos(), "Error in JPX QCD marker segment");
       return gFalse;
      }
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
       for (comp = 0; comp < img.nComps; ++comp) {
         if (!(i == 0 && comp == 0)) {
           img.tiles[i].tileComps[comp].quantStyle =
               img.tiles[0].tileComps[0].quantStyle;
           img.tiles[i].tileComps[comp].nQuantSteps =
               img.tiles[0].tileComps[0].nQuantSteps;
           img.tiles[i].tileComps[comp].quantSteps = 
               (Guint *)grealloc(img.tiles[i].tileComps[comp].quantSteps,
                              img.tiles[0].tileComps[0].nQuantSteps *
                                sizeof(Guint));
           for (j = 0; j < img.tiles[0].tileComps[0].nQuantSteps; ++j) {
             img.tiles[i].tileComps[comp].quantSteps[j] =
                img.tiles[0].tileComps[0].quantSteps[j];
           }
         }
       }
      }
      haveQCD = gTrue;
      break;
    case 0x5d:                     // QCC - quantization component
      if (!haveQCD) {
       error(getPos(), "JPX QCC marker segment before QCD segment");
       return gFalse;
      }
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&img.tiles[0].tileComps[comp].quantStyle)) {
       error(getPos(), "Error in JPX QCC marker segment");
       return gFalse;
      }
      if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x00) {
       img.tiles[0].tileComps[comp].nQuantSteps =
           segLen - (img.nComps > 256 ? 5 : 4);
       img.tiles[0].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[comp].quantSteps,
                           img.tiles[0].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
         if (!readUByte(&img.tiles[0].tileComps[comp].quantSteps[i])) {
           error(getPos(), "Error in JPX QCC marker segment");
           return gFalse;
         }
       }
      } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x01) {
       img.tiles[0].tileComps[comp].nQuantSteps = 1;
       img.tiles[0].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[comp].quantSteps,
                           img.tiles[0].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[0])) {
         error(getPos(), "Error in JPX QCC marker segment");
         return gFalse;
       }
      } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x02) {
       img.tiles[0].tileComps[comp].nQuantSteps =
           (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
       img.tiles[0].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[0].tileComps[comp].quantSteps,
                           img.tiles[0].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
         if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else {
       error(getPos(), "Error in JPX QCC marker segment");
       return gFalse;
      }
      for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
       img.tiles[i].tileComps[comp].quantStyle =
           img.tiles[0].tileComps[comp].quantStyle;
       img.tiles[i].tileComps[comp].nQuantSteps =
           img.tiles[0].tileComps[comp].nQuantSteps;
       img.tiles[i].tileComps[comp].quantSteps = 
           (Guint *)grealloc(img.tiles[i].tileComps[comp].quantSteps,
                           img.tiles[0].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       for (j = 0; j < img.tiles[0].tileComps[comp].nQuantSteps; ++j) {
         img.tiles[i].tileComps[comp].quantSteps[j] =
             img.tiles[0].tileComps[comp].quantSteps[j];
       }
      }
      break;
    case 0x5e:                     // RGN - region of interest
#if 1 //~ ROI is unimplemented
      fprintf(stderr, "RGN\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPM marker segment");
         return gFalse;
       }
      }
#else
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&compInfo[comp].defROI.style) ||
         !readUByte(&compInfo[comp].defROI.shift)) {
       error(getPos(), "Error in JPX RGN marker segment");
       return gFalse;
      }
#endif
      break;
    case 0x5f:                     // POC - progression order change
#if 1 //~ progression order changes are unimplemented
      fprintf(stderr, "POC\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPM marker segment");
         return gFalse;
       }
      }
#else
      nProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
      progs = (JPXProgOrder *)gmalloc(nProgs * sizeof(JPXProgOrder));
      for (i = 0; i < nProgs; ++i) {
       if (!readUByte(&progs[i].startRes) ||
           !(img.nComps > 256 && readUWord(&progs[i].startComp)) ||
           !(img.nComps <= 256 && readUByte(&progs[i].startComp)) ||
           !readUWord(&progs[i].endLayer) ||
           !readUByte(&progs[i].endRes) ||
           !(img.nComps > 256 && readUWord(&progs[i].endComp)) ||
           !(img.nComps <= 256 && readUByte(&progs[i].endComp)) ||
           !readUByte(&progs[i].progOrder)) {
         error(getPos(), "Error in JPX POC marker segment");
         return gFalse;
       }
      }
#endif
      break;
    case 0x60:                     // PPM - packed packet headers, main header
#if 1 //~ packed packet headers are unimplemented
      fprintf(stderr, "PPM\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPM marker segment");
         return gFalse;
       }
      }
#endif
      break;
    case 0x55:                     // TLM - tile-part lengths
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX TLM marker segment");
         return gFalse;
       }
      }
      break;
    case 0x57:                     // PLM - packet length, main header
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PLM marker segment");
         return gFalse;
       }
      }
      break;
    case 0x63:                     // CRG - component registration
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX CRG marker segment");
         return gFalse;
       }
      }
      break;
    case 0x64:                     // COM - comment
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX COM marker segment");
         return gFalse;
       }
      }
      break;
    case 0x90:                     // SOT - start of tile
      haveSOT = gTrue;
      break;
    default:
      error(getPos(), "Unknown marker segment %02x in JPX stream", segType);
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         break;
       }
      }
      break;
    }
  } while (!haveSOT);

  if (!haveSIZ) {
    error(getPos(), "Missing SIZ marker segment in JPX stream");
    return gFalse;
  }
  if (!haveCOD) {
    error(getPos(), "Missing COD marker segment in JPX stream");
    return gFalse;
  }
  if (!haveQCD) {
    error(getPos(), "Missing QCD marker segment in JPX stream");
    return gFalse;
  }

  //----- read the tile-parts
  while (1) {
    if (!readTilePart()) {
      return gFalse;
    }
    if (!readMarkerHdr(&segType, &segLen)) {
      error(getPos(), "Error in JPX codestream");
      return gFalse;
    }
    if (segType != 0x90) {  // SOT - start of tile
      break;
    }
  }

  if (segType != 0xd9) {    // EOC - end of codestream
    error(getPos(), "Missing EOC marker in JPX codestream");
    return gFalse;
  }

  //----- finish decoding the image
  for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
    tile = &img.tiles[i];
    for (comp = 0; comp < img.nComps; ++comp) {
      tileComp = &tile->tileComps[comp];
      inverseTransform(tileComp);
    }
    if (!inverseMultiCompAndDC(tile)) {
      return gFalse;
    }
  }

  //~ can free memory below tileComps here, and also tileComp.buf

  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readColorSpecBox ( Guint  dataLen) [private]

Definition at line 541 of file JPXStream.cc.

                                               {
  JPXColorSpec newCS;
  Guint csApprox, csEnum;
  Guint i;
  GBool ok;

  ok = gFalse;
  if (!readUByte(&newCS.meth) ||
      !readByte(&newCS.prec) ||
      !readUByte(&csApprox)) {
    goto err;
  }
  switch (newCS.meth) {
  case 1:                   // enumerated colorspace
    if (!readULong(&csEnum)) {
      goto err;
    }
    newCS.enumerated.type = (JPXColorSpaceType)csEnum;
    switch (newCS.enumerated.type) {
    case jpxCSBiLevel:
      ok = gTrue;
      break;
    case jpxCSYCbCr1:
      ok = gTrue;
      break;
    case jpxCSYCbCr2:
      ok = gTrue;
      break;
    case jpxCSYCBCr3:
      ok = gTrue;
      break;
    case jpxCSPhotoYCC:
      ok = gTrue;
      break;
    case jpxCSCMY:
      ok = gTrue;
      break;
    case jpxCSCMYK:
      ok = gTrue;
      break;
    case jpxCSYCCK:
      ok = gTrue;
      break;
    case jpxCSCIELab:
      if (dataLen == 3 + 7*4) {
       if (!readULong(&newCS.enumerated.cieLab.rl) ||
           !readULong(&newCS.enumerated.cieLab.ol) ||
           !readULong(&newCS.enumerated.cieLab.ra) ||
           !readULong(&newCS.enumerated.cieLab.oa) ||
           !readULong(&newCS.enumerated.cieLab.rb) ||
           !readULong(&newCS.enumerated.cieLab.ob) ||
           !readULong(&newCS.enumerated.cieLab.il)) {
         goto err;
       }
      } else if (dataLen == 3) {
       //~ this assumes the 8-bit case
       newCS.enumerated.cieLab.rl = 100;
       newCS.enumerated.cieLab.ol = 0;
       newCS.enumerated.cieLab.ra = 255;
       newCS.enumerated.cieLab.oa = 128;
       newCS.enumerated.cieLab.rb = 255;
       newCS.enumerated.cieLab.ob = 96;
       newCS.enumerated.cieLab.il = 0x00443530;
      } else {
       goto err;
      }
      ok = gTrue;
      break;
    case jpxCSsRGB:
      ok = gTrue;
      break;
    case jpxCSGrayscale:
      ok = gTrue;
      break;
    case jpxCSBiLevel2:
      ok = gTrue;
      break;
    case jpxCSCIEJab:
      // not allowed in PDF
      goto err;
    case jpxCSCISesRGB:
      ok = gTrue;
      break;
    case jpxCSROMMRGB:
      ok = gTrue;
      break;
    case jpxCSsRGBYCbCr:
      ok = gTrue;
      break;
    case jpxCSYPbPr1125:
      ok = gTrue;
      break;
    case jpxCSYPbPr1250:
      ok = gTrue;
      break;
    default:
      goto err;
    }
    break;
  case 2:                   // restricted ICC profile
  case 3:                   // any ICC profile (JPX)
  case 4:                   // vendor color (JPX)
    for (i = 0; i < dataLen - 3; ++i) {
      if (str->getChar() == EOF) {
       goto err;
      }
    }
    break;
  }

  if (ok && (!haveCS || newCS.prec > cs.prec)) {
    cs = newCS;
    haveCS = gTrue;
  }

  return gTrue;

 err:
  error(getPos(), "Error in JPX color spec");
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int JPXStream::readMarkerHdr ( int segType,
Guint segLen 
) [private]

Definition at line 2706 of file JPXStream.cc.

                                                        {
  int c;

  do {
    do {
      if ((c = str->getChar()) == EOF) {
       return gFalse;
      }
    } while (c != 0xff);
    do {
      if ((c = str->getChar()) == EOF) {
       return gFalse;
      }
    } while (c == 0xff);
  } while (c == 0x00);
  *segType = c;
  if ((c >= 0x30 && c <= 0x3f) ||
      c == 0x4f || c == 0x92 || c == 0x93 || c == 0xd9) {
    *segLen = 0;
    return gTrue;
  }
  return readUWord(segLen);
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readNBytes ( int  nBytes,
GBool  signd,
int x 
) [private]

Definition at line 2777 of file JPXStream.cc.

                                                           {
  int y, c, i;

  y = 0;
  for (i = 0; i < nBytes; ++i) {
    if ((c = str->getChar()) == EOF) {
      return gFalse;
    }
    y = (y << 8) + c;
  }
  if (signd) {
    if (y & (1 << (8 * nBytes - 1))) {
      y |= -1 << (8 * nBytes);
    }
  }
  *x = y;
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1163 of file JPXStream.cc.

                              {
  JPXTile *tile;
  JPXTileComp *tileComp;
  JPXResLevel *resLevel;
  JPXPrecinct *precinct;
  JPXSubband *subband;
  JPXCodeBlock *cb;
  GBool haveSOD;
  Guint tileIdx, tilePartLen, tilePartIdx, nTileParts;
  GBool tilePartToEOC;
  Guint precinctSize, style;
  Guint n, nSBs, nx, ny, sbx0, sby0, comp, segLen;
  Guint i, j, k, cbX, cbY, r, pre, sb, cbi;
  int segType, level;

  // process the SOT marker segment
  if (!readUWord(&tileIdx) ||
      !readULong(&tilePartLen) ||
      !readUByte(&tilePartIdx) ||
      !readUByte(&nTileParts)) {
    error(getPos(), "Error in JPX SOT marker segment");
    return gFalse;
  }

  if (tileIdx >= img.nXTiles * img.nYTiles) {
    error(getPos(), "Weird tile index in JPX stream");
    return gFalse;
  }

  tilePartToEOC = tilePartLen == 0;
  tilePartLen -= 12; // subtract size of SOT segment

  haveSOD = gFalse;
  do {
    if (!readMarkerHdr(&segType, &segLen)) {
      error(getPos(), "Error in JPX tile-part codestream");
      return gFalse;
    }
    tilePartLen -= 2 + segLen;
    switch (segType) {
    case 0x52:                     // COD - coding style default
      if (!readUByte(&img.tiles[tileIdx].tileComps[0].style) ||
         !readUByte(&img.tiles[tileIdx].progOrder) ||
         !readUWord(&img.tiles[tileIdx].nLayers) ||
         !readUByte(&img.tiles[tileIdx].multiComp) ||
         !readUByte(&img.tiles[tileIdx].tileComps[0].nDecompLevels) ||
         !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockW) ||
         !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockH) ||
         !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockStyle) ||
         !readUByte(&img.tiles[tileIdx].tileComps[0].transform)) {
       error(getPos(), "Error in JPX COD marker segment");
       return gFalse;
      }
      img.tiles[tileIdx].tileComps[0].codeBlockW += 2;
      img.tiles[tileIdx].tileComps[0].codeBlockH += 2;
      for (comp = 0; comp < img.nComps; ++comp) {
       if (comp != 0) {
         img.tiles[tileIdx].tileComps[comp].style =
             img.tiles[tileIdx].tileComps[0].style;
         img.tiles[tileIdx].tileComps[comp].nDecompLevels =
             img.tiles[tileIdx].tileComps[0].nDecompLevels;
         img.tiles[tileIdx].tileComps[comp].codeBlockW =
             img.tiles[tileIdx].tileComps[0].codeBlockW;
         img.tiles[tileIdx].tileComps[comp].codeBlockH =
             img.tiles[tileIdx].tileComps[0].codeBlockH;
         img.tiles[tileIdx].tileComps[comp].codeBlockStyle =
             img.tiles[tileIdx].tileComps[0].codeBlockStyle;
         img.tiles[tileIdx].tileComps[comp].transform =
             img.tiles[tileIdx].tileComps[0].transform;
       }
       img.tiles[tileIdx].tileComps[comp].resLevels =
           (JPXResLevel *)grealloc(
                   img.tiles[tileIdx].tileComps[comp].resLevels,
                   (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1) *
                     sizeof(JPXResLevel));
       for (r = 0;
            r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels;
            ++r) {
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
       }
      }
      for (r = 0; r <= img.tiles[tileIdx].tileComps[0].nDecompLevels; ++r) {
       if (img.tiles[tileIdx].tileComps[0].style & 0x01) {
         if (!readUByte(&precinctSize)) {
           error(getPos(), "Error in JPX COD marker segment");
           return gFalse;
         }
         img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth =
             precinctSize & 0x0f;
         img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight =
             (precinctSize >> 4) & 0x0f;
       } else {
         img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth = 15;
         img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight = 15;
       }
      }
      for (comp = 1; comp < img.nComps; ++comp) {
       for (r = 0;
            r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels;
            ++r) {
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
             img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth;
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
             img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight;
       }
      }
      break;
    case 0x53:                     // COC - coding style component
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&style) ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].nDecompLevels) ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockW) ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockH) ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockStyle) ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].transform)) {
       error(getPos(), "Error in JPX COC marker segment");
       return gFalse;
      }
      img.tiles[tileIdx].tileComps[comp].style =
         (img.tiles[tileIdx].tileComps[comp].style & ~1) | (style & 1);
      img.tiles[tileIdx].tileComps[comp].codeBlockW += 2;
      img.tiles[tileIdx].tileComps[comp].codeBlockH += 2;
      img.tiles[tileIdx].tileComps[comp].resLevels =
         (JPXResLevel *)grealloc(
                   img.tiles[tileIdx].tileComps[comp].resLevels,
                   (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1) *
                     sizeof(JPXResLevel));
      for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) {
       img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
      }
      for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) {
       if (img.tiles[tileIdx].tileComps[comp].style & 0x01) {
         if (!readUByte(&precinctSize)) {
           error(getPos(), "Error in JPX COD marker segment");
           return gFalse;
         }
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
             precinctSize & 0x0f;
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
             (precinctSize >> 4) & 0x0f;
       } else {
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = 15;
         img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = 15;
       }
      }
      break;
    case 0x5c:                     // QCD - quantization default
      if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) {
       error(getPos(), "Error in JPX QCD marker segment");
       return gFalse;
      }
      if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x00) {
       img.tiles[tileIdx].tileComps[0].nQuantSteps =
           segLen - 3;
       img.tiles[tileIdx].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[0].quantSteps,
                           img.tiles[tileIdx].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
         if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x01) {
       img.tiles[tileIdx].tileComps[0].nQuantSteps = 1;
       img.tiles[tileIdx].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[0].quantSteps,
                           img.tiles[tileIdx].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[0])) {
         error(getPos(), "Error in JPX QCD marker segment");
         return gFalse;
       }
      } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x02) {
       img.tiles[tileIdx].tileComps[0].nQuantSteps = (segLen - 3) / 2;
       img.tiles[tileIdx].tileComps[0].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[0].quantSteps,
                           img.tiles[tileIdx].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
         if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else {
       error(getPos(), "Error in JPX QCD marker segment");
       return gFalse;
      }
      for (comp = 1; comp < img.nComps; ++comp) {
       img.tiles[tileIdx].tileComps[comp].quantStyle =
           img.tiles[tileIdx].tileComps[0].quantStyle;
       img.tiles[tileIdx].tileComps[comp].nQuantSteps =
           img.tiles[tileIdx].tileComps[0].nQuantSteps;
       img.tiles[tileIdx].tileComps[comp].quantSteps = 
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[comp].quantSteps,
                           img.tiles[tileIdx].tileComps[0].nQuantSteps *
                             sizeof(Guint));
       for (j = 0; j < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++j) {
         img.tiles[tileIdx].tileComps[comp].quantSteps[j] =
             img.tiles[tileIdx].tileComps[0].quantSteps[j];
       }
      }
      break;
    case 0x5d:                     // QCC - quantization component
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&img.tiles[tileIdx].tileComps[comp].quantStyle)) {
       error(getPos(), "Error in JPX QCC marker segment");
       return gFalse;
      }
      if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) == 0x00) {
       img.tiles[tileIdx].tileComps[comp].nQuantSteps =
           segLen - (img.nComps > 256 ? 5 : 4);
       img.tiles[tileIdx].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[comp].quantSteps,
                           img.tiles[tileIdx].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
         if (!readUByte(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
           error(getPos(), "Error in JPX QCC marker segment");
           return gFalse;
         }
       }
      } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
               == 0x01) {
       img.tiles[tileIdx].tileComps[comp].nQuantSteps = 1;
       img.tiles[tileIdx].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[comp].quantSteps,
                           img.tiles[tileIdx].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[0])) {
         error(getPos(), "Error in JPX QCC marker segment");
         return gFalse;
       }
      } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
               == 0x02) {
       img.tiles[tileIdx].tileComps[comp].nQuantSteps =
           (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
       img.tiles[tileIdx].tileComps[comp].quantSteps =
           (Guint *)grealloc(img.tiles[tileIdx].tileComps[comp].quantSteps,
                           img.tiles[tileIdx].tileComps[comp].nQuantSteps *
                             sizeof(Guint));
       for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
         if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
           error(getPos(), "Error in JPX QCD marker segment");
           return gFalse;
         }
       }
      } else {
       error(getPos(), "Error in JPX QCC marker segment");
       return gFalse;
      }
      break;
    case 0x5e:                     // RGN - region of interest
#if 1 //~ ROI is unimplemented
      fprintf(stderr, "RGN\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPM marker segment");
         return gFalse;
       }
      }
#else
      if ((img.nComps > 256 && !readUWord(&comp)) ||
         (img.nComps <= 256 && !readUByte(&comp)) ||
         comp >= img.nComps ||
         !readUByte(&compInfo[comp].roi.style) ||
         !readUByte(&compInfo[comp].roi.shift)) {
       error(getPos(), "Error in JPX RGN marker segment");
       return gFalse;
      }
#endif
      break;
    case 0x5f:                     // POC - progression order change
#if 1 //~ progression order changes are unimplemented
      fprintf(stderr, "POC\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPM marker segment");
         return gFalse;
       }
      }
#else
      nTileProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
      tileProgs = (JPXProgOrder *)gmalloc(nTileProgs * sizeof(JPXProgOrder));
      for (i = 0; i < nTileProgs; ++i) {
       if (!readUByte(&tileProgs[i].startRes) ||
           !(img.nComps > 256 && readUWord(&tileProgs[i].startComp)) ||
           !(img.nComps <= 256 && readUByte(&tileProgs[i].startComp)) ||
           !readUWord(&tileProgs[i].endLayer) ||
           !readUByte(&tileProgs[i].endRes) ||
           !(img.nComps > 256 && readUWord(&tileProgs[i].endComp)) ||
           !(img.nComps <= 256 && readUByte(&tileProgs[i].endComp)) ||
           !readUByte(&tileProgs[i].progOrder)) {
         error(getPos(), "Error in JPX POC marker segment");
         return gFalse;
       }
      }
#endif
      break;
    case 0x61:                     // PPT - packed packet headers, tile-part hdr
#if 1 //~ packed packet headers are unimplemented
      fprintf(stderr, "PPT\n");
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PPT marker segment");
         return gFalse;
       }
      }
#endif
    case 0x58:                     // PLT - packet length, tile-part header
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX PLT marker segment");
         return gFalse;
       }
      }
      break;
    case 0x64:                     // COM - comment
      // skipped
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         error(getPos(), "Error in JPX COM marker segment");
         return gFalse;
       }
      }
      break;
    case 0x93:                     // SOD - start of data
      haveSOD = gTrue;
      break;
    default:
      error(getPos(), "Unknown marker segment %02x in JPX tile-part stream",
           segType);
      for (i = 0; i < segLen - 2; ++i) {
       if (str->getChar() == EOF) {
         break;
       }
      }
      break;
    }
  } while (!haveSOD);

  //----- initialize the tile, precincts, and code-blocks
  if (tilePartIdx == 0) {
    tile = &img.tiles[tileIdx];
    i = tileIdx / img.nXTiles;
    j = tileIdx % img.nXTiles;
    if ((tile->x0 = img.xTileOffset + j * img.xTileSize) < img.xOffset) {
      tile->x0 = img.xOffset;
    }
    if ((tile->y0 = img.yTileOffset + i * img.yTileSize) < img.yOffset) {
      tile->y0 = img.yOffset;
    }
    if ((tile->x1 = img.xTileOffset + (j + 1) * img.xTileSize) > img.xSize) {
      tile->x1 = img.xSize;
    }
    if ((tile->y1 = img.yTileOffset + (i + 1) * img.yTileSize) > img.ySize) {
      tile->y1 = img.ySize;
    }
    tile->comp = 0;
    tile->res = 0;
    tile->precinct = 0;
    tile->layer = 0;
    tile->maxNDecompLevels = 0;
    for (comp = 0; comp < img.nComps; ++comp) {
      tileComp = &tile->tileComps[comp];
      if (tileComp->nDecompLevels > tile->maxNDecompLevels) {
       tile->maxNDecompLevels = tileComp->nDecompLevels;
      }
      tileComp->x0 = jpxCeilDiv(tile->x0, tileComp->hSep);
      tileComp->y0 = jpxCeilDiv(tile->y0, tileComp->hSep);
      tileComp->x1 = jpxCeilDiv(tile->x1, tileComp->hSep);
      tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->hSep);
      tileComp->cbW = 1 << tileComp->codeBlockW;
      tileComp->cbH = 1 << tileComp->codeBlockH;
      tileComp->data = (int *)gmalloc((tileComp->x1 - tileComp->x0) *
                                  (tileComp->y1 - tileComp->y0) *
                                  sizeof(int));
      if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
       n = tileComp->x1 - tileComp->x0;
      } else {
       n = tileComp->y1 - tileComp->y0;
      }
      tileComp->buf = (int *)gmalloc((n + 8) * sizeof(int));
      for (r = 0; r <= tileComp->nDecompLevels; ++r) {
       resLevel = &tileComp->resLevels[r];
       k = r == 0 ? tileComp->nDecompLevels
                  : tileComp->nDecompLevels - r + 1;
       resLevel->x0 = jpxCeilDivPow2(tileComp->x0, k);
       resLevel->y0 = jpxCeilDivPow2(tileComp->y0, k);
       resLevel->x1 = jpxCeilDivPow2(tileComp->x1, k);
       resLevel->y1 = jpxCeilDivPow2(tileComp->y1, k);
       if (r == 0) {
         resLevel->bx0[0] = resLevel->x0;
         resLevel->by0[0] = resLevel->y0;
         resLevel->bx1[0] = resLevel->x1;
         resLevel->by1[0] = resLevel->y1;
       } else {
         resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
         resLevel->by0[0] = resLevel->y0;
         resLevel->bx1[0] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
         resLevel->by1[0] = resLevel->y1;
         resLevel->bx0[1] = resLevel->x0;
         resLevel->by0[1] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
         resLevel->bx1[1] = resLevel->x1;
         resLevel->by1[1] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
         resLevel->bx0[2] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
         resLevel->by0[2] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
         resLevel->bx1[2] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
         resLevel->by1[2] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
       }
       resLevel->precincts = (JPXPrecinct *)gmalloc(1 * sizeof(JPXPrecinct));
       for (pre = 0; pre < 1; ++pre) {
         precinct = &resLevel->precincts[pre];
         precinct->x0 = resLevel->x0;
         precinct->y0 = resLevel->y0;
         precinct->x1 = resLevel->x1;
         precinct->y1 = resLevel->y1;
         nSBs = r == 0 ? 1 : 3;
         precinct->subbands =
             (JPXSubband *)gmalloc(nSBs * sizeof(JPXSubband));
         for (sb = 0; sb < nSBs; ++sb) {
           subband = &precinct->subbands[sb];
           subband->x0 = resLevel->bx0[sb];
           subband->y0 = resLevel->by0[sb];
           subband->x1 = resLevel->bx1[sb];
           subband->y1 = resLevel->by1[sb];
           subband->nXCBs = jpxCeilDivPow2(subband->x1,
                                       tileComp->codeBlockW)
                            - jpxFloorDivPow2(subband->x0,
                                          tileComp->codeBlockW);
           subband->nYCBs = jpxCeilDivPow2(subband->y1,
                                       tileComp->codeBlockH)
                            - jpxFloorDivPow2(subband->y0,
                                          tileComp->codeBlockH);
           n = subband->nXCBs > subband->nYCBs ? subband->nXCBs
                                               : subband->nYCBs;
           for (subband->maxTTLevel = 0, --n;
               n;
               ++subband->maxTTLevel, n >>= 1) ;
           n = 0;
           for (level = subband->maxTTLevel; level >= 0; --level) {
             nx = jpxCeilDivPow2(subband->nXCBs, level);
             ny = jpxCeilDivPow2(subband->nYCBs, level);
             n += nx * ny;
           }
           subband->inclusion =
               (JPXTagTreeNode *)gmalloc(n * sizeof(JPXTagTreeNode));
           subband->zeroBitPlane =
               (JPXTagTreeNode *)gmalloc(n * sizeof(JPXTagTreeNode));
           for (k = 0; k < n; ++k) {
             subband->inclusion[k].finished = gFalse;
             subband->inclusion[k].val = 0;
             subband->zeroBitPlane[k].finished = gFalse;
             subband->zeroBitPlane[k].val = 0;
           }
           subband->cbs = (JPXCodeBlock *)gmalloc(subband->nXCBs *
                                             subband->nYCBs *
                                             sizeof(JPXCodeBlock));
           sbx0 = jpxFloorDivPow2(subband->x0, tileComp->codeBlockW);
           sby0 = jpxFloorDivPow2(subband->y0, tileComp->codeBlockH);
           cb = subband->cbs;
           for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
             for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
              cb->x0 = (sbx0 + cbX) << tileComp->codeBlockW;
              cb->x1 = cb->x0 + tileComp->cbW;
              if (subband->x0 > cb->x0) {
                cb->x0 = subband->x0;
              }
              if (subband->x1 < cb->x1) {
                cb->x1 = subband->x1;
              }
              cb->y0 = (sby0 + cbY) << tileComp->codeBlockH;
              cb->y1 = cb->y0 + tileComp->cbH;
              if (subband->y0 > cb->y0) {
                cb->y0 = subband->y0;
              }
              if (subband->y1 < cb->y1) {
                cb->y1 = subband->y1;
              }
              cb->seen = gFalse;
              cb->lBlock = 3;
              cb->nextPass = jpxPassCleanup;
              cb->nZeroBitPlanes = 0;
              cb->coeffs =
                  (JPXCoeff *)gmalloc((1 << (tileComp->codeBlockW
                                          + tileComp->codeBlockH))
                                   * sizeof(JPXCoeff));
              for (cbi = 0;
                   cbi < (Guint)(1 << (tileComp->codeBlockW
                                    + tileComp->codeBlockH));
                   ++cbi) {
                cb->coeffs[cbi].flags = 0;
                cb->coeffs[cbi].len = 0;
                cb->coeffs[cbi].mag = 0;
              }
              cb->stats = new JArithmeticDecoderStats(jpxNContexts);
              cb->stats->setEntry(jpxContextSigProp, 4, 0);
              cb->stats->setEntry(jpxContextRunLength, 3, 0);
              cb->stats->setEntry(jpxContextUniform, 46, 0);
              ++cb;
             }
           }
         }
       }
      }
    }
  }

  return readTilePartData(tileIdx, tilePartLen, tilePartToEOC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readTilePartData ( Guint  tileIdx,
Guint  tilePartLen,
GBool  tilePartToEOC 
) [private]

Definition at line 1681 of file JPXStream.cc.

                                                                      {
  JPXTile *tile;
  JPXTileComp *tileComp;
  JPXResLevel *resLevel;
  JPXPrecinct *precinct;
  JPXSubband *subband;
  JPXCodeBlock *cb;
  Guint ttVal;
  Guint bits, cbX, cbY, nx, ny, i, j, n, sb;
  int level;

  tile = &img.tiles[tileIdx];

  // read all packets from this tile-part
  while (1) {
    if (tilePartToEOC) {
      //~ peek for an EOC marker
    } else if (tilePartLen == 0) {
      break;
    }

    tileComp = &tile->tileComps[tile->comp];
    resLevel = &tileComp->resLevels[tile->res];
    precinct = &resLevel->precincts[tile->precinct];

    //----- packet header

    // zero-length flag
    if (!readBits(1, &bits)) {
      goto err;
    }
    if (!bits) {
      // packet is empty -- clear all code-block inclusion flags
      for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
       subband = &precinct->subbands[sb];
       for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
         for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
           cb = &subband->cbs[cbY * subband->nXCBs + cbX];
           cb->included = gFalse;
         }
       }
      }
    } else {

      for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
       subband = &precinct->subbands[sb];
       for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
         for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
           cb = &subband->cbs[cbY * subband->nXCBs + cbX];

           // skip code-blocks with no coefficients
           if (cb->x0 >= cb->x1 || cb->y0 >= cb->y1) {
             cb->included = gFalse;
             continue;
           }

           // code-block inclusion
           if (cb->seen) {
             if (!readBits(1, &cb->included)) {
              goto err;
             }
           } else {
             ttVal = 0;
             i = 0;
             for (level = subband->maxTTLevel; level >= 0; --level) {
              nx = jpxCeilDivPow2(subband->nXCBs, level);
              ny = jpxCeilDivPow2(subband->nYCBs, level);
              j = i + (cbY >> level) * nx + (cbX >> level);
              if (!subband->inclusion[j].finished &&
                  !subband->inclusion[j].val) {
                subband->inclusion[j].val = ttVal;
              } else {
                ttVal = subband->inclusion[j].val;
              }
              while (!subband->inclusion[j].finished &&
                     ttVal <= tile->layer) {
                if (!readBits(1, &bits)) {
                  goto err;
                }
                if (bits == 1) {
                  subband->inclusion[j].finished = gTrue;
                } else {
                  ++ttVal;
                }
              }
              subband->inclusion[j].val = ttVal;
              if (ttVal > tile->layer) {
                break;
              }
              i += nx * ny;
             }
             cb->included = level < 0;
           }

           if (cb->included) {

             // zero bit-plane count
             if (!cb->seen) {
              ttVal = 0;
              i = 0;
              for (level = subband->maxTTLevel; level >= 0; --level) {
                nx = jpxCeilDivPow2(subband->nXCBs, level);
                ny = jpxCeilDivPow2(subband->nYCBs, level);
                j = i + (cbY >> level) * nx + (cbX >> level);
                if (!subband->zeroBitPlane[j].finished &&
                    !subband->zeroBitPlane[j].val) {
                  subband->zeroBitPlane[j].val = ttVal;
                } else {
                  ttVal = subband->zeroBitPlane[j].val;
                }
                while (!subband->zeroBitPlane[j].finished) {
                  if (!readBits(1, &bits)) {
                    goto err;
                  }
                  if (bits == 1) {
                    subband->zeroBitPlane[j].finished = gTrue;
                  } else {
                    ++ttVal;
                  }
                }
                subband->zeroBitPlane[j].val = ttVal;
                i += nx * ny;
              }
              cb->nZeroBitPlanes = ttVal;
             }

             // number of coding passes
             if (!readBits(1, &bits)) {
              goto err;
             }
             if (bits == 0) {
              cb->nCodingPasses = 1;
             } else {
              if (!readBits(1, &bits)) {
                goto err;
              }
              if (bits == 0) {
                cb->nCodingPasses = 2;
              } else {
                if (!readBits(2, &bits)) {
                  goto err;
                }
                if (bits < 3) {
                  cb->nCodingPasses = 3 + bits;
                } else {
                  if (!readBits(5, &bits)) {
                    goto err;
                  }
                  if (bits < 31) {
                    cb->nCodingPasses = 6 + bits;
                  } else {
                    if (!readBits(7, &bits)) {
                     goto err;
                    }
                    cb->nCodingPasses = 37 + bits;
                  }
                }
              }
             }

             // update Lblock
             while (1) {
              if (!readBits(1, &bits)) {
                goto err;
              }
              if (!bits) {
                break;
              }
              ++cb->lBlock;
             }

             // length of compressed data
             //~ deal with multiple codeword segments
             for (n = cb->lBlock, i = cb->nCodingPasses >> 1;
                 i;
                 ++n, i >>= 1) ;
             if (!readBits(n, &cb->dataLen)) {
              goto err;
             }
           }
         }
       }
      }
    }
    tilePartLen -= byteCount;
    clearBitBuf();

    //----- packet data

    for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
      subband = &precinct->subbands[sb];
      for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
       for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
         cb = &subband->cbs[cbY * subband->nXCBs + cbX];
         if (cb->included) {
           if (!readCodeBlockData(tileComp, resLevel, precinct, subband,
                               tile->res, sb, cb)) {
             return gFalse;
           }
           tilePartLen -= cb->dataLen;
           cb->seen = gTrue;
         }
       }
      }
    }

    //----- next packet

    switch (tile->progOrder) {
    case 0: // layer, resolution level, component, precinct
      if (++tile->comp == img.nComps) {
       tile->comp = 0;
       if (++tile->res == tile->maxNDecompLevels + 1) {
         tile->res = 0;
         if (++tile->layer == tile->nLayers) {
           tile->layer = 0;
         }
       }
      }
      break;
    case 1: // resolution level, layer, component, precinct
      if (++tile->comp == img.nComps) {
       tile->comp = 0;
       if (++tile->layer == tile->nLayers) {
         tile->layer = 0;
         if (++tile->res == tile->maxNDecompLevels + 1) {
           tile->res = 0;
         }
       }
      }
      break;
    case 2: // resolution level, precinct, component, layer
      //~ this isn't correct -- see B.12.1.3
      if (++tile->layer == tile->nLayers) {
       tile->layer = 0;
       if (++tile->comp == img.nComps) {
         tile->comp = 0;
         if (++tile->res == tile->maxNDecompLevels + 1) {
           tile->res = 0;
         }
       }
      }
      break;
    case 3: // precinct, component, resolution level, layer
      //~ this isn't correct -- see B.12.1.4
      if (++tile->layer == tile->nLayers) {
       tile->layer = 0;
       if (++tile->res == tile->maxNDecompLevels + 1) {
         tile->res = 0;
         if (++tile->comp == img.nComps) {
           tile->comp = 0;
         }
       }
      }
      break;
    case 4: // component, precinct, resolution level, layer
      //~ this isn't correct -- see B.12.1.5
      if (++tile->layer == tile->nLayers) {
       tile->layer = 0;
       if (++tile->res == tile->maxNDecompLevels + 1) {
         tile->res = 0;
         if (++tile->comp == img.nComps) {
           tile->comp = 0;
         }
       }
      }
      break;
    }
  }

  return gTrue;

 err:
  error(getPos(), "Error in JPX stream");
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readUByte ( Guint x) [private]

Definition at line 2730 of file JPXStream.cc.

                                   {
  int c0;

  if ((c0 = str->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)c0;
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readULong ( Guint x) [private]

Definition at line 2764 of file JPXStream.cc.

                                   {
  int c0, c1, c2, c3;

  if ((c0 = str->getChar()) == EOF ||
      (c1 = str->getChar()) == EOF ||
      (c2 = str->getChar()) == EOF ||
      (c3 = str->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JPXStream::readUWord ( Guint x) [private]

Definition at line 2753 of file JPXStream.cc.

                                   {
  int c0, c1;

  if ((c0 = str->getChar()) == EOF ||
      (c1 = str->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)((c0 << 8) | c1);
  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JPXStream::reset ( ) [virtual]

Implements Stream.

Definition at line 270 of file JPXStream.cc.

                      {
  str->reset();
  if (readBoxes()) {
    curY = img.yOffset;
  } else {
    // readBoxes reported an error, so we go immediately to EOF
    curY = img.ySize;
  }
  curX = img.xOffset;
  curComp = 0;
  readBufLen = 0;
}

Here is the call graph for this function:

void FilterStream::setPos ( Guint  pos,
int  dir = 0 
) [virtual, inherited]

Implements Stream.

Definition at line 310 of file Stream.cc.

                                            {
  error(-1, "Internal: called setPos() on FilterStream");
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 328 of file JPXStream.h.

Definition at line 329 of file JPXStream.h.

Definition at line 330 of file JPXStream.h.

Guint* JPXStream::bpc [private]

Definition at line 314 of file JPXStream.h.

Definition at line 332 of file JPXStream.h.

Definition at line 324 of file JPXStream.h.

Definition at line 322 of file JPXStream.h.

Definition at line 318 of file JPXStream.h.

Definition at line 335 of file JPXStream.h.

Definition at line 335 of file JPXStream.h.

Definition at line 335 of file JPXStream.h.

Definition at line 325 of file JPXStream.h.

Definition at line 323 of file JPXStream.h.

Definition at line 319 of file JPXStream.h.

Definition at line 316 of file JPXStream.h.

Definition at line 321 of file JPXStream.h.

Definition at line 315 of file JPXStream.h.

Definition at line 327 of file JPXStream.h.

Definition at line 313 of file JPXStream.h.

Definition at line 320 of file JPXStream.h.

Definition at line 336 of file JPXStream.h.

Definition at line 337 of file JPXStream.h.

Stream* FilterStream::str [protected, inherited]

Definition at line 180 of file Stream.h.

Definition at line 315 of file JPXStream.h.


The documentation for this class was generated from the following files: