From f239ef0faa9e2b8c9ab0dec4c5ec6772a8c36845 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Wed, 15 Mar 2017 14:27:31 +0000 Subject: avoid slow conversion between scanline format and dest format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when we can, e.g. for the svp/gtk3 case Change-Id: I74f7b01004423f27ed2f142b325c2c74b4de290b Reviewed-on: https://gerrit.libreoffice.org/35229 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- vcl/source/filter/jpeg/jpegc.cxx | 70 +++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 26 deletions(-) (limited to 'vcl') diff --git a/vcl/source/filter/jpeg/jpegc.cxx b/vcl/source/filter/jpeg/jpegc.cxx index 8b5b483cf946..8d9b1626022d 100644 --- a/vcl/source/filter/jpeg/jpegc.cxx +++ b/vcl/source/filter/jpeg/jpegc.cxx @@ -157,19 +157,41 @@ void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines, if (pAccess) { - ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb; int nPixelSize = 3; + J_COLOR_SPACE best_out_color_space = JCS_RGB; + ScanlineFormat eScanlineFormat = ScanlineFormat::N24BitTcRgb; + ScanlineFormat eFinalFormat = pAccess->GetScanlineFormat(); + + if (eFinalFormat == ScanlineFormat::N32BitTcBgra) + { + best_out_color_space = JCS_EXT_BGRA; + eScanlineFormat = eFinalFormat; + nPixelSize = 4; + } + else if (eFinalFormat == ScanlineFormat::N32BitTcRgba) + { + best_out_color_space = JCS_EXT_RGBA; + eScanlineFormat = eFinalFormat; + nPixelSize = 4; + } + else if (eFinalFormat == ScanlineFormat::N32BitTcArgb) + { + best_out_color_space = JCS_EXT_ARGB; + eScanlineFormat = eFinalFormat; + nPixelSize = 4; + } + if ( cinfo.jpeg_color_space == JCS_YCbCr ) - cinfo.out_color_space = JCS_RGB; + cinfo.out_color_space = best_out_color_space; else if ( cinfo.jpeg_color_space == JCS_YCCK ) cinfo.out_color_space = JCS_CMYK; if (cinfo.out_color_space != JCS_CMYK && cinfo.out_color_space != JCS_GRAYSCALE && - cinfo.out_color_space != JCS_RGB) + cinfo.out_color_space != best_out_color_space) { - SAL_WARN("vcl.filter", "jpg with unknown out color space, forcing to rgb"); - cinfo.out_color_space = JCS_RGB; + SAL_WARN("vcl.filter", "jpg with unknown out color space, forcing to :" << best_out_color_space); + cinfo.out_color_space = best_out_color_space; } JSAMPLE* aRangeLimit = cinfo.sample_range_limit; @@ -199,36 +221,32 @@ void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines, { size_t yIndex = *pLines; - if (cinfo.out_color_space == JCS_CMYK) - { - sal_uInt8* p = pCYMKBuffer.data(); - jpeg_read_scanlines(&cinfo, reinterpret_cast(&p), 1); + sal_uInt8* p = (cinfo.out_color_space == JCS_CMYK) ? pCYMKBuffer.data() : pScanLineBuffer.data(); + jpeg_read_scanlines(&cinfo, reinterpret_cast(&p), 1); + if (bGray) + { + for (long x = 0; x < nWidth; ++x) + { + sal_uInt8 nColorGray = pScanLineBuffer[x]; + pAccess->SetPixel(yIndex, x, pCols[nColorGray]); + } + } + else if (cinfo.out_color_space == JCS_CMYK) + { // convert CMYK to RGB - for (int cmyk = 0, rgb = 0; cmyk < nWidth * 4; cmyk += 4, rgb += 3) + for (long cmyk = 0, x = 0; cmyk < nWidth * 4; cmyk += 4, ++x) { int color_C = 255 - pCYMKBuffer[cmyk + 0]; int color_M = 255 - pCYMKBuffer[cmyk + 1]; int color_Y = 255 - pCYMKBuffer[cmyk + 2]; int color_K = 255 - pCYMKBuffer[cmyk + 3]; - pScanLineBuffer[rgb + 0] = aRangeLimit[255L - (color_C + color_K)]; - pScanLineBuffer[rgb + 1] = aRangeLimit[255L - (color_M + color_K)]; - pScanLineBuffer[rgb + 2] = aRangeLimit[255L - (color_Y + color_K)]; - } - } - else - { - sal_uInt8* p = pScanLineBuffer.data(); - jpeg_read_scanlines(&cinfo, reinterpret_cast(&p), 1); - } + sal_uInt8 cRed = aRangeLimit[255L - (color_C + color_K)]; + sal_uInt8 cGreen = aRangeLimit[255L - (color_M + color_K)]; + sal_uInt8 cBlue = aRangeLimit[255L - (color_Y + color_K)]; - if (bGray) - { - for (long x = 0; x < nWidth; ++x) - { - sal_uInt8 nColorGray = pScanLineBuffer[x]; - pAccess->SetPixel(yIndex, x, pCols[nColorGray]); + pAccess->SetPixel(yIndex, x, BitmapColor(cRed, cGreen, cBlue)); } } else -- cgit