LCOV - code coverage report
Current view: top level - svtools/source/filter/jpeg - jpegc.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 58 127 45.7 %
Date: 2012-08-25 Functions: 4 5 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14 60 23.3 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <stdio.h>
      21                 :            : #include <stdlib.h>
      22                 :            : #include "setjmp.h"
      23                 :            : #include "jpeglib.h"
      24                 :            : #include "jerror.h"
      25                 :            : #include "jpeg.h"
      26                 :            : #include "rtl/alloc.h"
      27                 :            : #include "osl/diagnose.h"
      28                 :            : 
      29                 :            : struct my_error_mgr
      30                 :            : {
      31                 :            :     struct jpeg_error_mgr pub;
      32                 :            :     jmp_buf setjmp_buffer;
      33                 :            : };
      34                 :            : 
      35                 :            : void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile);
      36                 :            : void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile);
      37                 :            : 
      38                 :            : METHODDEF( void )
      39                 :         20 : my_error_exit (j_common_ptr cinfo)
      40                 :            : {
      41                 :         20 :     my_error_ptr myerr = (my_error_ptr) cinfo->err;
      42                 :         20 :     (*cinfo->err->output_message) (cinfo);
      43                 :         20 :     longjmp(myerr->setjmp_buffer, 1);
      44                 :            : }
      45                 :            : 
      46                 :            : 
      47                 :            : METHODDEF( void )
      48                 :         45 : my_output_message (j_common_ptr cinfo)
      49                 :            : {
      50                 :            :     char buffer[JMSG_LENGTH_MAX];
      51                 :         45 :     (*cinfo->err->format_message) (cinfo, buffer);
      52                 :         45 : }
      53                 :            : 
      54                 :            : /* TODO: when incompatible changes are possible again
      55                 :            :    the preview size hint should be redone */
      56                 :            : static int nPreviewWidth = 0;
      57                 :            : static int nPreviewHeight = 0;
      58                 :         42 : void SetJpegPreviewSizeHint( int nWidth, int nHeight )
      59                 :            : {
      60                 :         42 :     nPreviewWidth = nWidth;
      61                 :         42 :     nPreviewHeight = nHeight;
      62                 :         42 : }
      63                 :            : 
      64                 :         42 : void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
      65                 :            : {
      66                 :            :     struct jpeg_decompress_struct   cinfo;
      67                 :            :     struct my_error_mgr             jerr;
      68                 :            :     struct JPEGCreateBitmapParam    aCreateBitmapParam;
      69                 :            :     HPBYTE                          pDIB;
      70                 :            :     HPBYTE                          pTmp;
      71                 :            :     long                            nWidth;
      72                 :            :     long                            nHeight;
      73                 :            :     long                            nAlignedWidth;
      74                 :            :     JSAMPLE * range_limit;
      75                 :         42 :     HPBYTE pScanLineBuffer = NULL;
      76                 :         42 :     long nScanLineBufferComponents = 0;
      77                 :            :     // declare bDecompCreated volatile because of gcc
      78                 :            :     // warning: variable 'bDecompCreated' might be clobbered by `longjmp' or `vfork'
      79                 :         42 :     volatile long                   bDecompCreated = 0;
      80                 :            : 
      81                 :            :     /* Falls der Stream nicht ausreicht (IO_PENDING)
      82                 :            :      wird ueber ein longjmp in der Schleife nach Exit
      83                 :            :      gesprungen, wir geben dann die Anzahl
      84                 :            :      der bisher bearbeiteten Scanlines zurueck*/
      85         [ +  + ]:         42 :     if ( setjmp( jerr.setjmp_buffer ) )
      86                 :         20 :         goto Exit;
      87                 :            : 
      88                 :         42 :     cinfo.err = jpeg_std_error( &jerr.pub );
      89                 :         42 :     jerr.pub.error_exit = my_error_exit;
      90                 :         42 :     jerr.pub.output_message = my_output_message;
      91                 :            : 
      92                 :         42 :     jpeg_create_decompress( &cinfo );
      93                 :         42 :     bDecompCreated = 1;
      94                 :         42 :         jpeg_svstream_src( &cinfo, pIStm );
      95                 :         42 :     jpeg_read_header( &cinfo, sal_True );
      96                 :            : 
      97                 :         37 :     cinfo.scale_num = 1;
      98                 :         37 :     cinfo.scale_denom = 1;
      99                 :         37 :     cinfo.output_gamma = 1.0;
     100                 :         37 :     cinfo.raw_data_out = sal_False;
     101                 :         37 :     cinfo.quantize_colors = sal_False;
     102         [ +  - ]:         37 :     if ( cinfo.jpeg_color_space == JCS_YCbCr )
     103                 :         37 :         cinfo.out_color_space = JCS_RGB;
     104         [ #  # ]:          0 :     else if ( cinfo.jpeg_color_space == JCS_YCCK )
     105                 :          0 :         cinfo.out_color_space = JCS_CMYK;
     106                 :            : 
     107                 :            :     OSL_ASSERT(cinfo.out_color_space == JCS_CMYK || cinfo.out_color_space == JCS_GRAYSCALE || cinfo.out_color_space == JCS_RGB);
     108                 :            : 
     109                 :            :     /* change scale for preview import */
     110 [ +  - ][ -  + ]:         37 :     if( nPreviewWidth || nPreviewHeight )
     111                 :            :     {
     112         [ #  # ]:          0 :         if( nPreviewWidth == 0 ) {
     113                 :          0 :             nPreviewWidth = ( cinfo.image_width*nPreviewHeight )/cinfo.image_height;
     114         [ #  # ]:          0 :             if( nPreviewWidth <= 0 )
     115                 :          0 :                 nPreviewWidth = 1;
     116         [ #  # ]:          0 :         } else if( nPreviewHeight == 0 ) {
     117                 :          0 :             nPreviewHeight = ( cinfo.image_height*nPreviewWidth )/cinfo.image_width;
     118         [ #  # ]:          0 :             if( nPreviewHeight <= 0 )
     119                 :          0 :                 nPreviewHeight = 1;
     120                 :            :         }
     121                 :            : 
     122         [ #  # ]:          0 :         for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
     123                 :            :         {
     124         [ #  # ]:          0 :             if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
     125                 :          0 :                 break;
     126         [ #  # ]:          0 :             if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
     127                 :          0 :                 break;
     128                 :            :         }
     129                 :            : 
     130         [ #  # ]:          0 :         if( cinfo.scale_denom > 1 )
     131                 :            :         {
     132                 :          0 :             cinfo.dct_method            = JDCT_FASTEST;
     133                 :          0 :             cinfo.do_fancy_upsampling   = sal_False;
     134                 :          0 :             cinfo.do_block_smoothing    = sal_False;
     135                 :            :         }
     136                 :            :     }
     137                 :            : 
     138                 :         37 :     jpeg_start_decompress( &cinfo );
     139                 :            : 
     140                 :         27 :     nWidth = cinfo.output_width;
     141                 :         27 :     nHeight = cinfo.output_height;
     142                 :         27 :     aCreateBitmapParam.nWidth = nWidth;
     143                 :         27 :     aCreateBitmapParam.nHeight = nHeight;
     144                 :            : 
     145                 :         27 :     aCreateBitmapParam.density_unit = cinfo.density_unit;
     146                 :         27 :     aCreateBitmapParam.X_density = cinfo.X_density;
     147                 :         27 :     aCreateBitmapParam.Y_density = cinfo.Y_density;
     148                 :         27 :     aCreateBitmapParam.bGray = cinfo.output_components == 1;
     149                 :         27 :     pDIB = CreateBitmap( pJPEGReader, &aCreateBitmapParam );
     150                 :         27 :     nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
     151                 :         27 :     range_limit=cinfo.sample_range_limit;
     152                 :            : 
     153         [ -  + ]:         27 :     if ( cinfo.out_color_space == JCS_CMYK )
     154                 :            :     {
     155                 :          0 :             nScanLineBufferComponents = cinfo.output_width * 4;
     156                 :          0 :         pScanLineBuffer = rtl_allocateMemory( nScanLineBufferComponents );
     157                 :            :     }
     158                 :            : 
     159         [ +  - ]:         27 :     if( pDIB )
     160                 :            :     {
     161         [ +  - ]:         27 :         if( aCreateBitmapParam.bTopDown )
     162                 :         27 :             pTmp = pDIB;
     163                 :            :         else
     164                 :            :         {
     165                 :          0 :             pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
     166                 :          0 :             nAlignedWidth = -nAlignedWidth;
     167                 :            :         }
     168                 :            : 
     169         [ +  + ]:       1355 :         for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
     170                 :            :         {
     171         [ -  + ]:       1328 :             if (pScanLineBuffer!=NULL) { // in other words cinfo.out_color_space == JCS_CMYK
     172                 :            :             int i;
     173                 :            :             int j;
     174                 :          0 :             jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
     175                 :            :             // convert CMYK to RGB
     176         [ #  # ]:          0 :             for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
     177                 :            :             {
     178                 :          0 :                 int c_=255-pScanLineBuffer[i+0];
     179                 :          0 :                 int m_=255-pScanLineBuffer[i+1];
     180                 :          0 :                 int y_=255-pScanLineBuffer[i+2];
     181                 :          0 :                 int k_=255-pScanLineBuffer[i+3];
     182                 :          0 :                 pTmp[j+0]=range_limit[ 255L - ( c_ + k_ ) ];
     183                 :          0 :                 pTmp[j+1]=range_limit[ 255L - ( m_ + k_ ) ];
     184                 :          0 :                 pTmp[j+2]=range_limit[ 255L - ( y_ + k_ ) ];
     185                 :            :             }
     186                 :            :             } else {
     187                 :       1328 :             jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
     188                 :            :             }
     189                 :            :             /* PENDING ??? */
     190         [ -  + ]:       1328 :             if ( cinfo.err->msg_code == 113 )
     191                 :          0 :             break;
     192                 :            : 
     193                 :       1328 :             pTmp += nAlignedWidth;
     194                 :            :         }
     195                 :            :     }
     196                 :            : 
     197                 :         27 :     jpeg_finish_decompress( &cinfo );
     198         [ -  + ]:         22 :     if (pScanLineBuffer!=NULL) {
     199                 :          0 :         rtl_freeMemory( pScanLineBuffer );
     200                 :          0 :         pScanLineBuffer=NULL;
     201                 :            :     }
     202                 :            : 
     203                 :            : Exit:
     204                 :            : 
     205         [ +  - ]:         42 :     if( bDecompCreated )
     206                 :         42 :         jpeg_destroy_decompress( &cinfo );
     207                 :         42 : }
     208                 :            : 
     209                 :          0 : long WriteJPEG( void* pJPEGWriter, void* pOStm,
     210                 :            :                 long nWidth, long nHeight, long bGreys,
     211                 :            :                 long nQualityPercent, void* pCallbackData )
     212                 :            : {
     213                 :            :     struct jpeg_compress_struct cinfo;
     214                 :            :     struct my_error_mgr         jerr;
     215                 :            :     void*                       pScanline;
     216                 :            :     long                        nY;
     217                 :            :     // declare bCompCreated, bRet volatile because of gcc
     218                 :            :     // warning: variable 'bCompCreated' might be clobbered by `longjmp' or `vfork'
     219                 :          0 :     volatile long               bCompCreated = 0;
     220                 :          0 :     volatile long               bRet = 0;
     221                 :            : 
     222         [ #  # ]:          0 :     if ( setjmp( jerr.setjmp_buffer ) )
     223                 :          0 :         goto Exit;
     224                 :            : 
     225                 :          0 :     cinfo.err = jpeg_std_error( &jerr.pub );
     226                 :          0 :     jerr.pub.error_exit = my_error_exit;
     227                 :          0 :     jerr.pub.output_message = my_output_message;
     228                 :            : 
     229                 :          0 :     jpeg_create_compress( &cinfo );
     230                 :          0 :     bCompCreated = 1;
     231                 :            : 
     232                 :          0 :     jpeg_svstream_dest( &cinfo, pOStm );
     233                 :            : 
     234                 :          0 :     cinfo.image_width = (JDIMENSION) nWidth;
     235                 :          0 :     cinfo.image_height = (JDIMENSION) nHeight;
     236         [ #  # ]:          0 :     if ( bGreys )
     237                 :            :     {
     238                 :          0 :         cinfo.input_components = 1;
     239                 :          0 :         cinfo.in_color_space = JCS_GRAYSCALE;
     240                 :            :     }
     241                 :            :     else
     242                 :            :     {
     243                 :          0 :         cinfo.input_components = 3;
     244                 :          0 :         cinfo.in_color_space = JCS_RGB;
     245                 :            :     }
     246                 :            : 
     247                 :          0 :     jpeg_set_defaults( &cinfo );
     248                 :          0 :     jpeg_set_quality( &cinfo, (int) nQualityPercent, sal_False );
     249                 :            : 
     250 [ #  # ][ #  # ]:          0 :     if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
     251                 :          0 :         jpeg_simple_progression( &cinfo );
     252                 :            : 
     253                 :          0 :     jpeg_start_compress( &cinfo, sal_True );
     254                 :            : 
     255         [ #  # ]:          0 :     for( nY = 0; nY < nHeight; nY++ )
     256                 :            :     {
     257                 :          0 :         pScanline = GetScanline( pJPEGWriter, nY );
     258                 :            : 
     259         [ #  # ]:          0 :         if( pScanline )
     260                 :          0 :             jpeg_write_scanlines( &cinfo, (JSAMPARRAY) &pScanline, 1 );
     261                 :            : 
     262         [ #  # ]:          0 :         if( JPEGCallback( pCallbackData, nY * 100L / nHeight ) )
     263                 :          0 :             goto Exit;
     264                 :            :     }
     265                 :            : 
     266                 :          0 :     bRet = 1;
     267                 :            : 
     268                 :          0 :     jpeg_finish_compress(&cinfo);
     269                 :            : 
     270                 :            : Exit:
     271                 :            : 
     272         [ #  # ]:          0 :     if ( bCompCreated )
     273                 :          0 :         jpeg_destroy_compress( &cinfo );
     274                 :            : 
     275                 :          0 :     return bRet;
     276                 :            : }
     277                 :            : 
     278                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10