📄 jpxstream.cc
字号:
if (pixBits == 8) { readBuf = (readBuf << 8) | (pix & 0xff); } else { readBuf = (readBuf << pixBits) | (pix & ((1 << pixBits) - 1)); } readBufLen += pixBits; } while (readBufLen < 8);}GString *JPXStream::getPSFilter(int psLevel, char *indent) { return NULL;}GBool JPXStream::isBinary(GBool last) { return str->isBinary(gTrue);}void JPXStream::getImageParams(int *bitsPerComponent, StreamColorSpaceMode *csMode) { Guint boxType, boxLen, dataLen, csEnum; Guint bpc1, dummy, i; int csMeth, csPrec, csPrec1, dummy2; StreamColorSpaceMode csMode1; GBool haveBPC, haveCSMode; csPrec = 0; // make gcc happy haveBPC = haveCSMode = gFalse; str->reset(); if (str->lookChar() == 0xff) { getImageParams2(bitsPerComponent, csMode); } else { while (readBoxHdr(&boxType, &boxLen, &dataLen)) { if (boxType == 0x6a703268) { // JP2 header cover(0); // skip the superbox } else if (boxType == 0x69686472) { // image header cover(1); if (readULong(&dummy) && readULong(&dummy) && readUWord(&dummy) && readUByte(&bpc1) && readUByte(&dummy) && readUByte(&dummy) && readUByte(&dummy)) { *bitsPerComponent = bpc1 + 1; haveBPC = gTrue; } } else if (boxType == 0x636F6C72) { // color specification cover(2); if (readByte(&csMeth) && readByte(&csPrec1) && readByte(&dummy2)) { if (csMeth == 1) { if (readULong(&csEnum)) { csMode1 = streamCSNone; if (csEnum == jpxCSBiLevel || csEnum == jpxCSGrayscale) { csMode1 = streamCSDeviceGray; } else if (csEnum == jpxCSCMYK) { csMode1 = streamCSDeviceCMYK; } else if (csEnum == jpxCSsRGB || csEnum == jpxCSCISesRGB || csEnum == jpxCSROMMRGB) { csMode1 = streamCSDeviceRGB; } if (csMode1 != streamCSNone && (!haveCSMode || csPrec1 > csPrec)) { *csMode = csMode1; csPrec = csPrec1; haveCSMode = gTrue; } for (i = 0; i < dataLen - 7; ++i) { str->getChar(); } } } else { for (i = 0; i < dataLen - 3; ++i) { str->getChar(); } } } } else if (boxType == 0x6A703263) { // codestream cover(3); if (!(haveBPC && haveCSMode)) { getImageParams2(bitsPerComponent, csMode); } break; } else { cover(4); for (i = 0; i < dataLen; ++i) { str->getChar(); } } } } str->close();}// Get image parameters from the codestream.void JPXStream::getImageParams2(int *bitsPerComponent, StreamColorSpaceMode *csMode) { int segType; Guint segLen, nComps1, bpc1, dummy, i; while (readMarkerHdr(&segType, &segLen)) { if (segType == 0x51) { // SIZ - image and tile size cover(5); if (readUWord(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readULong(&dummy) && readUWord(&nComps1) && readUByte(&bpc1)) { *bitsPerComponent = (bpc1 & 0x7f) + 1; // if there's no color space info, take a guess if (nComps1 == 1) { *csMode = streamCSDeviceGray; } else if (nComps1 == 3) { *csMode = streamCSDeviceRGB; } else if (nComps1 == 4) { *csMode = streamCSDeviceCMYK; } } break; } else { cover(6); if (segLen > 2) { for (i = 0; i < segLen - 2; ++i) { str->getChar(); } } } }}GBool JPXStream::readBoxes() { 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) { cover(7); error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper"); readCodestream(0); nComps = img.nComps; bpc = (Guint *)gmallocn(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 cover(8); break; case 0x69686472: // image header cover(9); 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 *)gmallocn(nComps, sizeof(Guint)); for (i = 0; i < nComps; ++i) { bpc[i] = bpc1; } haveImgHdr = gTrue; break; case 0x62706363: // bits per component cover(10); 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 cover(11); if (!readColorSpecBox(dataLen)) { return gFalse; } break; case 0x70636c72: // palette cover(12); if (!readUWord(&palette.nEntries) || !readUByte(&palette.nComps)) { error(getPos(), "Unexpected EOF in JPX stream"); return gFalse; } palette.bpc = (Guint *)gmallocn(palette.nComps, sizeof(Guint)); palette.c = (int *)gmallocn(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 cover(13); compMap.nChannels = dataLen / 4; compMap.comp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint)); compMap.type = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint)); compMap.pComp = (Guint *)gmallocn(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 cover(14); if (!readUWord(&channelDefn.nChannels)) { error(getPos(), "Unexpected EOF in JPX stream"); return gFalse; } channelDefn.idx = (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint)); channelDefn.type = (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint)); channelDefn.assoc = (Guint *)gmallocn(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 cover(15); if (!bpc) { error(getPos(), "JPX stream is missing the image header box"); } if (!haveCS) { error(getPos(), "JPX stream has no supported color spec"); } if (!readCodestream(dataLen)) { return gFalse; } break; default: cover(16); for (i = 0; i < dataLen; ++i) { if (str->getChar() == EOF) { error(getPos(), "Unexpected EOF in JPX stream"); return gFalse; } } break; } } return gTrue;}GBool JPXStream::readColorSpecBox(Guint dataLen) { 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 cover(17); 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 == 7 + 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 == 7) { //~ this assumes the 8-bit case cover(92); 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) cover(18); for (i = 0; i < dataLen - 3; ++i) { if (str->getChar() == EOF) { goto err; } } break; } if (ok && (!haveCS || newCS.prec > cs.prec)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -