📄 jpxstream.cc
字号:
} else { n = tileComp->y1 - tileComp->y0; } tileComp->buf = (int *)gmallocn(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 *)gmallocn(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 *)gmallocn(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 *)gmallocn(n, sizeof(JPXTagTreeNode)); subband->zeroBitPlane = (JPXTagTreeNode *)gmallocn(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 *)gmallocn(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 *)gmallocn((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->arithDecoder = NULL; cb->stats = NULL; ++cb; } } } } } } } return readTilePartData(tileIdx, tilePartLen, tilePartToEOC);}GBool JPXStream::readTilePartData(Guint tileIdx, Guint tilePartLen, GBool tilePartToEOC) { 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;}GBool JPXStream::readCodeBlockData(JPXTileComp *tileComp, JPXResLevel *resLevel, JPXPrecinct *precinct, JPXSubband *subband, Guint res, Guint sb, JPXCodeBlock *cb) { JPXCoeff *coeff0, *coeff1, *coeff; Guint horiz, vert, diag, all, cx, xorBit; int horizSign,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -