📄 jpxstream.cc
字号:
#endif break; case 0x55: // TLM - tile-part lengths // skipped cover(28); 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 cover(29); 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 cover(30); 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 cover(31); 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 cover(32); haveSOT = gTrue; break; default: cover(33); 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;}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 cover(34); 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 cover(35); 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 cover(36); 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 cover(37); 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 cover(38);#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 cover(39);#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 cover(40);#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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -