CHARLS_IMEXPORT(JLS_ERROR) JpegLsDecode(void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength, JlsParameters* info) { ByteStreamInfo compressedStream = FromByteArray(compressedData, compressedLength); ByteStreamInfo rawStreamInfo = FromByteArray(uncompressedData, uncompressedLength); return JpegLsDecodeStream(rawStreamInfo, compressedStream, info); }
CHARLS_IMEXPORT(JLS_ERROR) JpegLsEncode(void* compressedData, size_t compressedLength, size_t* pcbyteWritten, const void* uncompressedData, size_t uncompressedLength, struct JlsParameters* pparams) { ByteStreamInfo rawStreamInfo = FromByteArray(uncompressedData, uncompressedLength); ByteStreamInfo compressedStreamInfo = FromByteArray(compressedData, compressedLength); return JpegLsEncodeStream(compressedStreamInfo, pcbyteWritten, rawStreamInfo, pparams); }
CHARLS_IMEXPORT(JLS_ERROR) JpegLsVerifyEncode(const void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength) { JlsParameters info = JlsParameters(); JLS_ERROR error = JpegLsReadHeader(compressedData, compressedLength, &info); if (error != OK) return error; ByteStreamInfo rawStreamInfo = FromByteArray(uncompressedData, uncompressedLength); error = CheckInput(rawStreamInfo, &info); if (error != OK) return error; Size size = Size(info.width, info.height); JpegMarkerWriter writer(info.jfif, size, info.bitspersample, info.components); if (info.ilv == ILV_NONE) { LONG fieldLength = size.cx*size.cy*((info.bitspersample +7)/8); for (LONG component = 0; component < info.components; ++component) { writer.AddScan(rawStreamInfo, &info); SkipBytes(&rawStreamInfo, fieldLength); } } else { writer.AddScan(rawStreamInfo, &info); } std::vector<BYTE> rgbyteCompressed(compressedLength + 16); memcpy(&rgbyteCompressed[0], compressedData, compressedLength); writer.EnableCompare(true); writer.Write(FromByteArray(&rgbyteCompressed[0], rgbyteCompressed.size())); return OK; }
CHARLS_IMEXPORT(JLS_ERROR) JpegLsDecodeRect(void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength, JlsRect roi, JlsParameters* info) { ByteStreamInfo compressedStream = FromByteArray(compressedData, compressedLength); JLSInputStream reader(compressedStream); ByteStreamInfo rawStreamInfo = FromByteArray(uncompressedData, uncompressedLength); if(info != NULL) { reader.SetInfo(info); } reader.SetRect(roi); try { reader.Read(rawStreamInfo); return OK; } catch (JlsException& e) { return e._error; } }
CHARLS_IMEXPORT(JLS_ERROR) JpegLsReadHeader(const void* compressedData, size_t compressedLength, JlsParameters* pparams) { return JpegLsReadHeaderStream(FromByteArray(compressedData, compressedLength), pparams); }
void JPEGLSCodec::decompress(const DataChunk &data) { ByteStreamInfo inStream = FromByteArray(data.Data, data.Size); struct JlsParameters info; JLS_ERROR err = JpegLsReadHeaderStream(inStream, &info); if(err == OK) { const int width = info.width; const int height = info.height; assert(info.components == (_channels == JPEGLS_RGBA ? 4 : 3)); assert(info.colorTransform == COLORXFORM_NONE); const PixelType pixType = (_depth == JPEGLS_8 ? UINT8 : _depth == JPEGLS_10 ? UINT10 : _depth == JPEGLS_12 ? UINT12 : _depth == JPEGLS_16 ? UINT16 : UINT8); const size_t pixSize = PixelSize(pixType); const unsigned int bitDepth = PixelBits(pixType); assert(info.bitspersample == bitDepth); const size_t pixelSize = (info.components * PixelSize(pixType)); const size_t rowBytes = (width * pixelSize); const size_t bufSize = (height * rowBytes); DataChunkPtr frameData = new DataChunk(bufSize); char *buf = (char *)frameData->Data; const Box2i dataW = dataWindow(); assert(width == (dataW.max.x - dataW.min.x + 1)); assert(height == (dataW.max.y - dataW.min.y + 1)); assert(dataW.min.x == 0); assert(dataW.min.y == 0); FrameBufferPtr frameBuffer = new FrameBuffer(dataW); frameBuffer->insert("R", Slice(pixType, &buf[0 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("G", Slice(pixType, &buf[1 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("B", Slice(pixType, &buf[2 * pixSize], pixelSize, rowBytes)); if(info.components >= 4) frameBuffer->insert("A", Slice(pixType, &buf[3 * pixSize], pixelSize, rowBytes)); frameBuffer->attachData(frameData); ByteStreamInfo outStream = FromByteArray(frameData->Data, frameData->Size); err = JpegLsDecodeStream(outStream, inStream, &info); if(err == OK) { storeFrame(frameBuffer); } } if(err != OK) throw MoxMxf::ArgExc("JPEG-LS decompression error"); }
void JPEGLSCodec::compress(const FrameBuffer &frame) { const Box2i dataW = dataWindow(); const int width = (dataW.max.x - dataW.min.x + 1); const int height = (dataW.max.y - dataW.min.y + 1); const PixelType pixType = (_depth == JPEGLS_8 ? UINT8 : _depth == JPEGLS_10 ? UINT10 : _depth == JPEGLS_12 ? UINT12 : _depth == JPEGLS_16 ? UINT16 : UINT8); const size_t pixSize = PixelSize(pixType); const unsigned int bitDepth = PixelBits(pixType); const int numChannels = (_channels == JPEGLS_RGBA ? 4 : 3); const size_t tempPixelSize = (numChannels * pixSize); const size_t tempRowbytes = (tempPixelSize * width); const size_t tempBufSize = (tempRowbytes * height); DataChunk dataChunk(tempBufSize); char *tempBuffer = (char *)dataChunk.Data; assert(dataW.min.x == 0 && dataW.min.y == 0); FrameBuffer tempFrameBuffer(dataW); tempFrameBuffer.insert("R", Slice(pixType, &tempBuffer[0 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("G", Slice(pixType, &tempBuffer[1 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("B", Slice(pixType, &tempBuffer[2 * pixSize], tempPixelSize, tempRowbytes)); if(_channels == JPEGLS_RGBA) tempFrameBuffer.insert("A", Slice(pixType, &tempBuffer[3 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.copyFromFrame(frame); JlsParameters params = JlsParameters(); params.width = width; params.height = height; params.bitspersample = bitDepth; //params.bytesperline = (tempRowbytes / 3); params.components = numChannels; params.allowedlossyerror = 0; // always lossless params.ilv = ILV_SAMPLE; params.colorTransform = COLORXFORM_NONE; //params.outputBgr = 0; /* params.custom.MAXVAL = 255; params.custom.T1 = 0; params.custom.T2 = 0; params.custom.T3 = 0; params.custom.RESET = 1; params.jfif.Ver = 123; params.jfif.units = 0; params.jfif.XDensity = 72; params.jfif.YDensity = 72; params.jfif.Xthumb = 0; params.jfif.Ythumb = 0; params.jfif.pdataThumbnail = NULL; */ ByteStreamInfo inStream = FromByteArray(dataChunk.Data, dataChunk.Size); DataChunkPtr outDataChunk = new DataChunk(tempBufSize); size_t bytesWritten = 0; JLS_ERROR err = OK; do { ByteStreamInfo outStream = FromByteArray(outDataChunk->Data, outDataChunk->Size); err = JpegLsEncodeStream(outStream, &bytesWritten, inStream, ¶ms); if(err == CompressedBufferTooSmall) { outDataChunk->Resize(2 * outDataChunk->Size, false); } }while(err == CompressedBufferTooSmall); assert(err != TooMuchCompressedData); if(err == OK) { assert(bytesWritten > 0); outDataChunk->Resize(bytesWritten); storeData(outDataChunk); } else throw MoxMxf::ArgExc("JPEG-LS compression error"); }