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); }
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"); }