📄 jpxstream.cc
字号:
} 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;}GBool JPXStream::readTilePart() { 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 *)greallocn( 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 *)greallocn( 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 *)greallocn(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 *)greallocn(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 *)greallocn(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 *)greallocn(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 *)greallocn(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 *)greallocn(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 *)greallocn(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 *)gmallocn(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 *)gmallocn((tileComp->x1 - tileComp->x0) * (tileComp->y1 - tileComp->y0), sizeof(int)); if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) { n = tileComp->x1 - tileComp->x0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -