/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
}
+/**
+ * @brief Helper function to convert from Turbo Jpeg Pixel Format as TJPF_CMYK to RGB888 by naive method.
+ *
+ * @param[in] cmykBuffer buffer of cmyk.
+ * @param[in] rgbBuffer buffer of Pixel::RGB888
+ * @param[in] width width of image.
+ * @param[in] height height of image.
+ */
+void ConvertTjpfCMYKToRGB888(PixelArray __restrict__ cmykBuffer, PixelArray __restrict__ rgbBuffer, int32_t width, int32_t height)
+{
+ const int32_t pixelCount = width * height;
+ const uint8_t cmykBpp = 4u;
+ const uint8_t bpp = 3u;
+
+ const PixelArray cmykBufferEnd = cmykBuffer + pixelCount * cmykBpp;
+ // Convert every pixel
+ while(cmykBuffer != cmykBufferEnd)
+ {
+ const uint16_t channelK = static_cast<uint16_t>(*(cmykBuffer + 3u));
+ *(rgbBuffer + 0u) = static_cast<uint8_t>(static_cast<uint16_t>(*(cmykBuffer + 0u)) * channelK / 255);
+ *(rgbBuffer + 1u) = static_cast<uint8_t>(static_cast<uint16_t>(*(cmykBuffer + 1u)) * channelK / 255);
+ *(rgbBuffer + 2u) = static_cast<uint8_t>(static_cast<uint16_t>(*(cmykBuffer + 2u)) * channelK / 255);
+ cmykBuffer += cmykBpp;
+ rgbBuffer += bpp;
+ }
+}
} // namespace
namespace Dali
int chrominanceSubsampling = -1;
int preXformImageWidth = 0, preXformImageHeight = 0;
- // In Ubuntu, the turbojpeg version is not correct. so build error occurs.
- // Temporarily separate Ubuntu and other profiles.
-#ifndef DALI_PROFILE_UBUNTU
int jpegColorspace = -1;
if( tjDecompressHeader3( jpeg.get(), jpegBufferPtr, jpegBufferSize, &preXformImageWidth, &preXformImageHeight, &chrominanceSubsampling, &jpegColorspace ) == -1 )
{
DALI_LOG_ERROR("%s\n", tjGetErrorStr());
// Do not set width and height to 0 or return early as this sometimes fails only on determining subsampling type.
}
-#else
- if( tjDecompressHeader2( jpeg.get(), jpegBufferPtr, jpegBufferSize, &preXformImageWidth, &preXformImageHeight, &chrominanceSubsampling ) == -1 )
- {
- DALI_LOG_ERROR("%s\n", tjGetErrorStr());
- // Do not set width and height to 0 or return early as this sometimes fails only on determining subsampling type.
- }
-#endif
if(preXformImageWidth == 0 || preXformImageHeight == 0)
{
// Colorspace conversion options
TJPF pixelLibJpegType = TJPF_RGB;
Pixel::Format pixelFormat = Pixel::RGB888;
-#ifndef DALI_PROFILE_UBUNTU
switch (jpegColorspace)
{
case TJCS_RGB:
case TJCS_YCCK:
{
pixelLibJpegType = TJPF_CMYK;
- pixelFormat = Pixel::RGBA8888;
+ pixelFormat = Pixel::RGB888;
break;
}
default:
break;
}
}
-#endif
// Allocate a bitmap and decompress the jpeg buffer into its pixel buffer:
bitmap = Dali::Devel::PixelBuffer::New(scaledPostXformWidth, scaledPostXformHeight, pixelFormat);
auto bitmapPixelBuffer = bitmap.GetBuffer();
- if( tjDecompress2( jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<unsigned char*>( bitmapPixelBuffer ), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags ) == -1 )
+ if(pixelLibJpegType == TJPF_CMYK)
{
- std::string errorString = tjGetErrorStr();
+ // Currently we support only for 4 bytes per each CMYK pixel.
+ const uint8_t cmykBytesPerPixel = 4u;
+
+ uint8_t* cmykBuffer = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * scaledPostXformWidth * scaledPostXformHeight * cmykBytesPerPixel));
- if( IsJpegErrorFatal( errorString ) )
+ int decodeResult = tjDecompress2(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<uint8_t*>(cmykBuffer), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags);
+ if(DALI_UNLIKELY(decodeResult == -1))
{
- DALI_LOG_ERROR("%s\n", errorString.c_str() );
+ std::string errorString = tjGetErrorStr();
+
+ if(IsJpegErrorFatal(errorString))
+ {
+ DALI_LOG_ERROR("%s\n", errorString.c_str());
+ free(cmykBuffer);
return false;
+ }
+ else
+ {
+ DALI_LOG_WARNING("%s\n", errorString.c_str());
+ }
}
- else
+ ConvertTjpfCMYKToRGB888(cmykBuffer, bitmapPixelBuffer, scaledPostXformWidth, scaledPostXformHeight);
+
+ free(cmykBuffer);
+ }
+ else
+ {
+ int decodeResult = tjDecompress2(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<uint8_t*>(bitmapPixelBuffer), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags);
+ if(DALI_UNLIKELY(decodeResult == -1))
{
- DALI_LOG_WARNING("%s\n", errorString.c_str() );
+ std::string errorString = tjGetErrorStr();
+
+ if(IsJpegErrorFatal(errorString))
+ {
+ DALI_LOG_ERROR("%s\n", errorString.c_str());
+ return false;
+ }
+ else
+ {
+ DALI_LOG_WARNING("%s\n", errorString.c_str());
+ }
}
}