+void GetJpegPixelFormat(int jpegColorspace, TJPF& pixelLibJpegType, Pixel::Format& pixelFormat)
+{
+ pixelLibJpegType = TJPF_RGB;
+ pixelFormat = Pixel::RGB888;
+
+ switch(jpegColorspace)
+ {
+ case TJCS_RGB:
+ // YCbCr is not an absolute colorspace but rather a mathematical transformation of RGB designed solely for storage and transmission.
+ // YCbCr images must be converted to RGB before they can actually be displayed.
+ case TJCS_YCbCr:
+ {
+ pixelLibJpegType = TJPF_RGB;
+ pixelFormat = Pixel::RGB888;
+ break;
+ }
+ case TJCS_GRAY:
+ {
+ pixelLibJpegType = TJPF_GRAY;
+ pixelFormat = Pixel::L8;
+ break;
+ }
+ case TJCS_CMYK:
+ case TJCS_YCCK:
+ {
+ pixelLibJpegType = TJPF_CMYK;
+ pixelFormat = Pixel::RGBA8888;
+ break;
+ }
+ default:
+ {
+ pixelLibJpegType = TJPF_RGB;
+ pixelFormat = Pixel::RGB888;
+ break;
+ }
+ }
+}
+
+bool TransformBitmap(int scaledPreXformWidth, int scaledPreXformHeight, JpegTransform transform, uint8_t* bitmapPixelBuffer, Pixel::Format pixelFormat)
+{
+ const unsigned int bufferWidth = Dali::TizenPlatform::GetTextureDimension(scaledPreXformWidth);
+ const unsigned int bufferHeight = Dali::TizenPlatform::GetTextureDimension(scaledPreXformHeight);
+
+ bool result = false;
+
+ switch(transform)
+ {
+ case JpegTransform::NONE:
+ {
+ result = true;
+ break;
+ }
+ // 3 orientation changes for a camera held perpendicular to the ground or upside-down:
+ case JpegTransform::ROTATE_180:
+ {
+ static auto rotate180Functions = TransformFunctionArray{
+ &Rotate180<1>,
+ &Rotate180<3>,
+ &Rotate180<4>,
+ };
+ result = Transform(rotate180Functions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ case JpegTransform::ROTATE_270:
+ {
+ static auto rotate270Functions = TransformFunctionArray{
+ &Rotate270<1>,
+ &Rotate270<3>,
+ &Rotate270<4>,
+ };
+ result = Transform(rotate270Functions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ case JpegTransform::ROTATE_90:
+ {
+ static auto rotate90Functions = TransformFunctionArray{
+ &Rotate90<1>,
+ &Rotate90<3>,
+ &Rotate90<4>,
+ };
+ result = Transform(rotate90Functions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ case JpegTransform::FLIP_VERTICAL:
+ {
+ static auto flipVerticalFunctions = TransformFunctionArray{
+ &FlipVertical<1>,
+ &FlipVertical<3>,
+ &FlipVertical<4>,
+ };
+ result = Transform(flipVerticalFunctions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ // Less-common orientation changes, since they don't correspond to a camera's physical orientation:
+ case JpegTransform::FLIP_HORIZONTAL:
+ {
+ static auto flipHorizontalFunctions = TransformFunctionArray{
+ &FlipHorizontal<1>,
+ &FlipHorizontal<3>,
+ &FlipHorizontal<4>,
+ };
+ result = Transform(flipHorizontalFunctions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ case JpegTransform::TRANSPOSE:
+ {
+ static auto transposeFunctions = TransformFunctionArray{
+ &Transpose<1>,
+ &Transpose<3>,
+ &Transpose<4>,
+ };
+ result = Transform(transposeFunctions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ case JpegTransform::TRANSVERSE:
+ {
+ static auto transverseFunctions = TransformFunctionArray{
+ &Transverse<1>,
+ &Transverse<3>,
+ &Transverse<4>,
+ };
+ result = Transform(transverseFunctions, bitmapPixelBuffer, bufferWidth, bufferHeight, pixelFormat);
+ break;
+ }
+ default:
+ {
+ DALI_LOG_ERROR("Unsupported JPEG Orientation transformation: %x.\n", transform);
+ break;
+ }
+ }
+ return result;
+}
+
+bool LoadJpegFile(const Dali::ImageLoader::Input& input, Vector<uint8_t>& jpegBuffer, unsigned int& jpegBufferSize)
+{
+ FILE* const fp = input.file;
+
+ if(DALI_UNLIKELY(fseek(fp, 0, SEEK_END)))
+ {
+ DALI_LOG_ERROR("Error seeking to end of file\n");
+ return false;
+ }
+
+ long positionIndicator = ftell(fp);
+ jpegBufferSize = 0u;
+ if(positionIndicator > -1L)
+ {
+ jpegBufferSize = static_cast<unsigned int>(positionIndicator);
+ }
+
+ if(DALI_UNLIKELY(0u == jpegBufferSize))
+ {
+ DALI_LOG_ERROR("Jpeg buffer size error\n");
+ return false;
+ }
+
+ if(DALI_UNLIKELY(fseek(fp, 0, SEEK_SET)))
+ {
+ DALI_LOG_ERROR("Error seeking to start of file\n");
+ return false;
+ }
+
+ try
+ {
+ jpegBuffer.ResizeUninitialized(jpegBufferSize);
+ }
+ catch(...)
+ {
+ DALI_LOG_ERROR("Could not allocate temporary memory to hold JPEG file of size %uMB.\n", jpegBufferSize / 1048576U);
+ return false;
+ }
+ unsigned char* const jpegBufferPtr = jpegBuffer.Begin();
+
+ // Pull the compressed JPEG image bytes out of a file and into memory:
+ if(DALI_UNLIKELY(fread(jpegBufferPtr, 1, jpegBufferSize, fp) != jpegBufferSize))
+ {
+ DALI_LOG_ERROR("Error on image file read.\n");
+ return false;
+ }
+
+ if(DALI_UNLIKELY(fseek(fp, 0, SEEK_SET)))
+ {
+ DALI_LOG_ERROR("Error seeking to start of file\n");
+ return false;
+ }
+
+ return true;
+}
+