Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use CharLS 2.0 #18

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
17 changes: 9 additions & 8 deletions dcmjpls/libsrc/djcodecd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
#include "djerror.h" /* for private class DJLSError */

// JPEG-LS library (CharLS) includes
#include "intrface.h"
#include "CharLS/charls.h"
#include "CharLS/publictypes.h"

E_TransferSyntax DJLSLosslessDecoder::supportedTransferSyntax() const
{
Expand Down Expand Up @@ -382,18 +383,18 @@ OFCondition DJLSDecoderBase::decodeFrame(
if (result.good())
{
JlsParameters params;
JLS_ERROR err;
CharlsApiResultType err;

err = JpegLsReadHeader(jlsData, compressedSize, &params);
err = JpegLsReadHeader(jlsData, compressedSize, &params, NULL);
result = DJLSError::convert(err);

if (result.good())
{
if (params.width != imageColumns) result = EC_JLSImageDataMismatch;
else if (params.height != imageRows) result = EC_JLSImageDataMismatch;
else if (params.components != imageSamplesPerPixel) result = EC_JLSImageDataMismatch;
else if ((bytesPerSample == 1) && (params.bitspersample > 8)) result = EC_JLSImageDataMismatch;
else if ((bytesPerSample == 2) && (params.bitspersample <= 8)) result = EC_JLSImageDataMismatch;
else if ((bytesPerSample == 1) && (params.bitsPerSample > 8)) result = EC_JLSImageDataMismatch;
else if ((bytesPerSample == 2) && (params.bitsPerSample <= 8)) result = EC_JLSImageDataMismatch;
}

if (!result.good())
Expand All @@ -402,13 +403,13 @@ OFCondition DJLSDecoderBase::decodeFrame(
}
else
{
err = JpegLsDecode(buffer, bufSize, jlsData, compressedSize, &params);
err = JpegLsDecode(buffer, bufSize, jlsData, compressedSize, &params, NULL);
result = DJLSError::convert(err);
delete[] jlsData;

if (result.good() && imageSamplesPerPixel == 3)
{
if (imagePlanarConfiguration == 1 && params.ilv != ILV_NONE)
if (imagePlanarConfiguration == 1 && params.interleaveMode != charls::InterleaveMode::None)
{
// The dataset says this should be planarConfiguration == 1, but
// it isn't -> convert it.
Expand All @@ -418,7 +419,7 @@ OFCondition DJLSDecoderBase::decodeFrame(
else
result = createPlanarConfiguration1Word(OFreinterpret_cast(Uint16*, buffer), imageColumns, imageRows);
}
else if (imagePlanarConfiguration == 0 && params.ilv != ILV_SAMPLE && params.ilv != ILV_LINE)
else if (imagePlanarConfiguration == 0 && params.interleaveMode != charls::InterleaveMode::Sample && params.interleaveMode != charls::InterleaveMode::Line)
{
// The dataset says this should be planarConfiguration == 0, but
// it isn't -> convert it.
Expand Down
76 changes: 40 additions & 36 deletions dcmjpls/libsrc/djcodece.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
#include "dcmtk/dcmimgle/dcmimage.h" /* for class DicomImage */

// JPEG-LS library (CharLS) includes
#include "intrface.h"
#include "CharLS/charls.h"
#include "CharLS/publictypes.h"

BEGIN_EXTERN_C
#ifdef HAVE_FCNTL_H
Expand All @@ -69,6 +70,9 @@ BEGIN_EXTERN_C
#endif
END_EXTERN_C

// No longer defined in charls
typedef unsigned char BYTE;


E_TransferSyntax DJLSLosslessEncoder::supportedTransferSyntax() const
{
Expand Down Expand Up @@ -568,13 +572,13 @@ OFCondition DJLSEncoderBase::compressRawFrame(

// Set up the information structure for CharLS
OFBitmanipTemplate<char>::zeroMem((char *) &jls_params, sizeof(jls_params));
jls_params.bitspersample = bitsAllocated;
jls_params.bitsPerSample = bitsAllocated;
jls_params.height = height;
jls_params.width = width;
jls_params.allowedlossyerror = 0; // must be zero for raw mode
jls_params.allowedLossyError = 0; // must be zero for raw mode
jls_params.outputBgr = false;
// No idea what this one does, but I don't think DICOM says anything about it
jls_params.colorTransform = 0;
jls_params.colorTransformation = charls::ColorTransformation::None;

// Unset: jls_params.jfif (thumbnail, dpi)

Expand All @@ -596,15 +600,15 @@ OFCondition DJLSEncoderBase::compressRawFrame(
else
return EC_IllegalCall;

enum interleavemode ilv;
CharlsInterleaveModeType ilv;
switch (planarConfiguration)
{
// ILV_LINE is not supported by DICOM
// charls::InterleaveMode::Line is not supported by DICOM
case 0:
ilv = ILV_SAMPLE;
ilv = charls::InterleaveMode::Sample;
break;
case 1:
ilv = ILV_NONE;
ilv = charls::InterleaveMode::None;
break;
default:
return EC_IllegalCall;
Expand All @@ -613,39 +617,39 @@ OFCondition DJLSEncoderBase::compressRawFrame(
switch (djcp->getJplsInterleaveMode())
{
case DJLSCodecParameter::interleaveSample:
jls_params.ilv = ILV_SAMPLE;
jls_params.interleaveMode = charls::InterleaveMode::Sample;
break;
case DJLSCodecParameter::interleaveLine:
jls_params.ilv = ILV_LINE;
jls_params.interleaveMode = charls::InterleaveMode::Line;
break;
case DJLSCodecParameter::interleaveNone:
jls_params.ilv = ILV_NONE;
jls_params.interleaveMode = charls::InterleaveMode::None;
break;
case DJLSCodecParameter::interleaveDefault:
default:
// In default mode we just never convert the image to another
// interleave-mode. Instead, we use what is already there.
jls_params.ilv = ilv;
jls_params.interleaveMode = ilv;
break;
}

// Special case: one component images are always ILV_NONE (Standard requires this)
// Special case: one component images are always charls::InterleaveMode::None (Standard requires this)
if (jls_params.components == 1)
{
jls_params.ilv = ILV_NONE;
jls_params.interleaveMode = charls::InterleaveMode::None;
// Don't try to convert to another interleave mode, not necessary
ilv = ILV_NONE;
ilv = charls::InterleaveMode::None;
}

// Do we have to convert the image to some other interleave mode?
if ((jls_params.ilv == ILV_NONE && (ilv == ILV_SAMPLE || ilv == ILV_LINE)) ||
(ilv == ILV_NONE && (jls_params.ilv == ILV_SAMPLE || jls_params.ilv == ILV_LINE)))
if ((jls_params.interleaveMode == charls::InterleaveMode::None && (ilv == charls::InterleaveMode::Sample || ilv == charls::InterleaveMode::Line)) ||
(ilv == charls::InterleaveMode::None && (jls_params.interleaveMode == charls::InterleaveMode::Sample || jls_params.interleaveMode == charls::InterleaveMode::Line)))
{
DCMJPLS_DEBUG("Converting image from " << (ilv == ILV_NONE ? "color-by-plane" : "color-by-pixel")
<< " to " << (jls_params.ilv == ILV_NONE ? "color-by-plane" : "color-by-pixel"));
DCMJPLS_DEBUG("Converting image from " << (ilv == charls::InterleaveMode::None ? "color-by-plane" : "color-by-pixel")
<< " to " << (jls_params.interleaveMode == charls::InterleaveMode::None ? "color-by-plane" : "color-by-pixel"));

frameBuffer = new Uint8[frameSize];
if (jls_params.ilv == ILV_NONE)
if (jls_params.interleaveMode == charls::InterleaveMode::None)
result = convertToUninterleaved(frameBuffer, framePointer, samplesPerPixel, width, height, bitsAllocated);
else
/* For CharLS, sample-interleaved and line-interleaved is both expected to
Expand All @@ -664,7 +668,7 @@ OFCondition DJLSEncoderBase::compressRawFrame(

size_t bytesWritten = 0;

JLS_ERROR err = JpegLsEncode(&buffer, &size, &bytesWritten, framePointer, frameSize, &jls_params);
CharlsApiResultType err = JpegLsEncode(buffer, size, &bytesWritten, framePointer, frameSize, &jls_params, NULL);
result = DJLSError::convert(err);

if (result.good())
Expand Down Expand Up @@ -997,23 +1001,23 @@ OFCondition DJLSEncoderBase::compressCookedFrame(
OFBitmanipTemplate<char>::zeroMem((char *) &jls_params, sizeof(jls_params));
jls_params.height = height;
jls_params.width = width;
jls_params.allowedlossyerror = nearLosslessDeviation;
jls_params.allowedLossyError = nearLosslessDeviation;
jls_params.outputBgr = false;
jls_params.bitspersample = depth;
jls_params.bitsPerSample = depth;
// No idea what this one does, but I don't think DICOM says anything about it
jls_params.colorTransform = 0;
jls_params.colorTransformation = charls::ColorTransformation::None;

// This was already checked for a sane value above
jls_params.components = samplesPerPixel;
switch(dinter->getRepresentation())
{
case EPR_Uint8:
case EPR_Sint8:
jls_params.bitspersample = 8;
jls_params.bitsPerSample = 8;
break;
case EPR_Uint16:
case EPR_Sint16:
jls_params.bitspersample = 16;
jls_params.bitsPerSample = 16;
break;
default:
// Everything else was already handled above and can't happen here
Expand All @@ -1033,45 +1037,45 @@ OFCondition DJLSEncoderBase::compressCookedFrame(
switch (djcp->getJplsInterleaveMode())
{
case DJLSCodecParameter::interleaveSample:
jls_params.ilv = ILV_SAMPLE;
jls_params.interleaveMode = charls::InterleaveMode::Sample;
break;
case DJLSCodecParameter::interleaveLine:
jls_params.ilv = ILV_LINE;
jls_params.interleaveMode = charls::InterleaveMode::Line;
break;
case DJLSCodecParameter::interleaveNone:
jls_params.ilv = ILV_NONE;
jls_params.interleaveMode = charls::InterleaveMode::None;
break;
case DJLSCodecParameter::interleaveDefault:
default:
// Default for the cooked encoder is always ILV_LINE
jls_params.ilv = ILV_LINE;
// Default for the cooked encoder is always charls::InterleaveMode::Line
jls_params.interleaveMode = charls::InterleaveMode::Line;
break;
}

// Special case: one component images are always ILV_NONE (Standard requires this)
// Special case: one component images are always CharlsInterleaveMode.None (Standard requires this)
if (jls_params.components == 1)
{
jls_params.ilv = ILV_NONE;
jls_params.interleaveMode = charls::InterleaveMode::None;
}

Uint8 *frameBuffer = NULL;
Uint8 *framePointer = buffer;
// Do we have to convert the image to color-by-plane now?
if (jls_params.ilv == ILV_NONE && jls_params.components != 1)
if (jls_params.interleaveMode == charls::InterleaveMode::None && jls_params.components != 1)
{
DCMJPLS_DEBUG("Converting image from color-by-pixel to color-by-plane");

frameBuffer = new Uint8[buffer_size];
framePointer = frameBuffer;
result = convertToUninterleaved(frameBuffer, buffer, samplesPerPixel, width, height, jls_params.bitspersample);
result = convertToUninterleaved(frameBuffer, buffer, samplesPerPixel, width, height, jls_params.bitsPerSample);
}

size_t compressed_buffer_size = buffer_size + 1024;
BYTE *compressed_buffer = new BYTE[compressed_buffer_size];

size_t bytesWritten = 0;

JLS_ERROR err = JpegLsEncode(&compressed_buffer, &compressed_buffer_size, &bytesWritten, framePointer, buffer_size, &jls_params);
CharlsApiResultType err = JpegLsEncode(compressed_buffer, compressed_buffer_size, &bytesWritten, framePointer, buffer_size, &jls_params, NULL);
result = DJLSError::convert(err);

if (result.good())
Expand Down
25 changes: 13 additions & 12 deletions dcmjpls/libsrc/djerror.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@

#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmjpls/djlsutil.h" /* For the OFCondition codes */
#include "intrface.h" /* CharLS include */
#include "CharLS/charls.h" /* CharLS include */
#include "CharLS/publictypes.h" /* CharLS include */

/** Helper class for converting between dcmjpls and CharLS error codes
*/
Expand All @@ -40,29 +41,29 @@ class DJLSError
* @param error The CharLS error code
* @return The OFCondition
*/
static const OFConditionConst& convert(JLS_ERROR error)
static const OFConditionConst& convert(CharlsApiResultType error)
{
switch (error)
{
case OK:
case charls::ApiResult::OK:
return EC_Normal;
case UncompressedBufferTooSmall:
case charls::ApiResult::UncompressedBufferTooSmall:
return EC_JLSUncompressedBufferTooSmall;
case CompressedBufferTooSmall:
case charls::ApiResult::CompressedBufferTooSmall:
return EC_JLSCompressedBufferTooSmall;
case ImageTypeNotSupported:
case charls::ApiResult::ImageTypeNotSupported:
return EC_JLSCodecUnsupportedImageType;
case InvalidJlsParameters:
case charls::ApiResult::InvalidJlsParameters:
return EC_JLSCodecInvalidParameters;
case ParameterValueNotSupported:
case charls::ApiResult::ParameterValueNotSupported:
return EC_JLSCodecUnsupportedValue;
case InvalidCompressedData:
case charls::ApiResult::InvalidCompressedData:
return EC_JLSInvalidCompressedData;
case UnsupportedBitDepthForTransform:
case charls::ApiResult::UnsupportedBitDepthForTransform:
return EC_JLSUnsupportedBitDepthForTransform;
case UnsupportedColorTransform:
case charls::ApiResult::UnsupportedColorTransform:
return EC_JLSUnsupportedColorTransform;
case TooMuchCompressedData:
case charls::ApiResult::TooMuchCompressedData:
return EC_JLSTooMuchCompressedData;
default:
return EC_IllegalParameter;
Expand Down