// // CreateJFIF() // JpegMarkerSegment* CreateJFIF(const JfifParamaters* jfif) { std::vector<BYTE> rgbyte; for(int i = 0; i < (int)sizeof(jfifID); i++) { rgbyte.push_back(jfifID[i]); } push_back(rgbyte, (USHORT)jfif->Ver); rgbyte.push_back(jfif->units); push_back(rgbyte, (USHORT)jfif->XDensity); push_back(rgbyte, (USHORT)jfif->YDensity); // thumbnail rgbyte.push_back((BYTE)jfif->Xthumb); rgbyte.push_back((BYTE)jfif->Ythumb); if(jfif->Xthumb > 0) { if(jfif->pdataThumbnail) throw JlsException(InvalidJlsParameters); rgbyte.insert(rgbyte.end(), (BYTE*)jfif->pdataThumbnail, (BYTE*)jfif->pdataThumbnail+3*jfif->Xthumb*jfif->Ythumb ); } return new JpegMarkerSegment(JPEG_APP0, rgbyte); }
// // ReadByte() // BYTE JLSInputStream::ReadByte() { if (_cbyteOffset >= _cbyteLength) throw JlsException(InvalidCompressedData); return _pdata[_cbyteOffset++]; }
// // Read() // void JLSInputStream::Read(void* pvoid, size_t cbyteAvailable) { ReadHeader(); JLS_ERROR error = CheckParameterCoherent(&_info); if (error != OK) throw JlsException(error); ReadPixels(pvoid, cbyteAvailable); }
// // ReadHeader() // void JLSInputStream::ReadHeader() { if (ReadByte() != 0xFF) throw JlsException(InvalidCompressedData); if (ReadByte() != JPEG_SOI) throw JlsException(InvalidCompressedData); for (;;) { if (ReadByte() != 0xFF) throw JlsException(InvalidCompressedData); BYTE marker = (BYTE)ReadByte(); size_t cbyteStart = _cbyteOffset; LONG cbyteMarker = ReadWord(); switch (marker) { case JPEG_SOS: ReadStartOfScan(); break; case JPEG_SOF: ReadStartOfFrame(); break; case JPEG_COM: ReadComment(); break; case JPEG_LSE: ReadPresetParameters(); break; case JPEG_APP0: ReadJfif(); break; case JPEG_APP7: ReadColorSpace(); break; case JPEG_APP8: ReadColorXForm(); break; // Other tags not supported (among which DNL DRI) default: throw JlsException(ImageTypeNotSupported); } if (marker == JPEG_SOS) { _cbyteOffset = cbyteStart - 2; return; } _cbyteOffset = cbyteStart + cbyteMarker; } }
// // ReadColorXForm() // void JLSInputStream::ReadColorXForm() { std::vector<char> sourceTag; ReadNBytes(sourceTag, 4); if(strncmp(&sourceTag[0],"mrfx", 4) != 0) return; int xform = ReadByte(); switch(xform) { case COLORXFORM_NONE: case COLORXFORM_HP1: case COLORXFORM_HP2: case COLORXFORM_HP3: _info.colorTransform = xform; return; case COLORXFORM_RGB_AS_YUV_LOSSY: case COLORXFORM_MATRIX: throw JlsException(ImageTypeNotSupported); default: throw JlsException(InvalidCompressedData); } }
// // ReadPixels() // void JLSInputStream::ReadPixels(void* pvoid, LONG cbyteAvailable) { LONG cbytePlane = _info.width * _info.height * ((_info.bitspersample + 7)/8); if (cbyteAvailable < cbytePlane * _info.components) throw JlsException(UncompressedBufferTooSmall); if (_info.ilv == ILV_NONE) { BYTE* pbyte = (BYTE*)pvoid; for (LONG icomp = 0; icomp < _info.components; ++icomp) { ReadScan(pbyte); pbyte += cbytePlane; } } else { ReadScan(pvoid); } }
JLS_ERROR CheckParameterCoherent(const JlsParameters* pparams) { if (pparams->bitspersample < 6 || pparams->bitspersample > 16) return ParameterValueNotSupported; if (pparams->ilv < 0 || pparams->ilv > 2) throw JlsException(InvalidCompressedData); if (pparams->bitspersample < 6 || pparams->bitspersample > 16) return ParameterValueNotSupported; switch (pparams->components) { case 4: return pparams->ilv == ILV_SAMPLE ? ParameterValueNotSupported : OK; case 3: return OK; case 1: return pparams->ilv != ILV_NONE ? ParameterValueNotSupported : OK; case 0: return InvalidJlsParameters; default: return pparams->ilv != ILV_NONE ? ParameterValueNotSupported : OK; } }
// // ReadPixels() // void JLSInputStream::ReadPixels(void* pvoid, size_t cbyteAvailable) { if (_rect.Width <= 0) { _rect.Width = _info.width; _rect.Height = _info.height; } int64_t cbytePlane = (int64_t)(_rect.Width) * _rect.Height * ((_info.bitspersample + 7)/8); if (int64_t(cbyteAvailable) < cbytePlane * _info.components) throw JlsException(UncompressedBufferTooSmall); int scancount = _info.ilv == ILV_NONE ? _info.components : 1; BYTE* pbyte = (BYTE*)pvoid; for (LONG scan = 0; scan < scancount; ++scan) { ReadScan(pbyte); pbyte += cbytePlane; } }