LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/filter/jpeg - jpegc.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 58 127 45.7 %
Date: 2012-12-27 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          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           4 : my_error_exit (j_common_ptr cinfo)
      40             : {
      41           4 :     my_error_ptr myerr = (my_error_ptr) cinfo->err;
      42           4 :     (*cinfo->err->output_message) (cinfo);
      43           4 :     longjmp(myerr->setjmp_buffer, 1);
      44             : }
      45             : 
      46             : 
      47             : METHODDEF( void )
      48           9 : my_output_message (j_common_ptr cinfo)
      49             : {
      50             :     char buffer[JMSG_LENGTH_MAX];
      51           9 :     (*cinfo->err->format_message) (cinfo, buffer);
      52           9 : }
      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           8 : void SetJpegPreviewSizeHint( int nWidth, int nHeight )
      59             : {
      60           8 :     nPreviewWidth = nWidth;
      61           8 :     nPreviewHeight = nHeight;
      62           8 : }
      63             : 
      64           8 : 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           8 :     HPBYTE pScanLineBuffer = NULL;
      76           8 :     long nScanLineBufferComponents = 0;
      77             :     // declare bDecompCreated volatile because of gcc
      78             :     // warning: variable 'bDecompCreated' might be clobbered by `longjmp' or `vfork'
      79           8 :     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           8 :     if ( setjmp( jerr.setjmp_buffer ) )
      86           4 :         goto Exit;
      87             : 
      88           8 :     cinfo.err = jpeg_std_error( &jerr.pub );
      89           8 :     jerr.pub.error_exit = my_error_exit;
      90           8 :     jerr.pub.output_message = my_output_message;
      91             : 
      92           8 :     jpeg_create_decompress( &cinfo );
      93           8 :     bDecompCreated = 1;
      94           8 :         jpeg_svstream_src( &cinfo, pIStm );
      95           8 :     jpeg_read_header( &cinfo, sal_True );
      96             : 
      97           7 :     cinfo.scale_num = 1;
      98           7 :     cinfo.scale_denom = 1;
      99           7 :     cinfo.output_gamma = 1.0;
     100           7 :     cinfo.raw_data_out = sal_False;
     101           7 :     cinfo.quantize_colors = sal_False;
     102           7 :     if ( cinfo.jpeg_color_space == JCS_YCbCr )
     103           7 :         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           7 :     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           7 :     jpeg_start_decompress( &cinfo );
     139             : 
     140           5 :     nWidth = cinfo.output_width;
     141           5 :     nHeight = cinfo.output_height;
     142           5 :     aCreateBitmapParam.nWidth = nWidth;
     143           5 :     aCreateBitmapParam.nHeight = nHeight;
     144             : 
     145           5 :     aCreateBitmapParam.density_unit = cinfo.density_unit;
     146           5 :     aCreateBitmapParam.X_density = cinfo.X_density;
     147           5 :     aCreateBitmapParam.Y_density = cinfo.Y_density;
     148           5 :     aCreateBitmapParam.bGray = cinfo.output_components == 1;
     149           5 :     pDIB = CreateBitmap( pJPEGReader, &aCreateBitmapParam );
     150           5 :     nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
     151           5 :     range_limit=cinfo.sample_range_limit;
     152             : 
     153           5 :     if ( cinfo.out_color_space == JCS_CMYK )
     154             :     {
     155           0 :             nScanLineBufferComponents = cinfo.output_width * 4;
     156           0 :         pScanLineBuffer = rtl_allocateMemory( nScanLineBufferComponents );
     157             :     }
     158             : 
     159           5 :     if( pDIB )
     160             :     {
     161           5 :         if( aCreateBitmapParam.bTopDown )
     162           5 :             pTmp = pDIB;
     163             :         else
     164             :         {
     165           0 :             pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
     166           0 :             nAlignedWidth = -nAlignedWidth;
     167             :         }
     168             : 
     169         233 :         for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
     170             :         {
     171         228 :             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         228 :             jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
     188             :             }
     189             :             /* PENDING ??? */
     190         228 :             if ( cinfo.err->msg_code == 113 )
     191           0 :             break;
     192             : 
     193         228 :             pTmp += nAlignedWidth;
     194             :         }
     195             :     }
     196             : 
     197           5 :     jpeg_finish_decompress( &cinfo );
     198           4 :     if (pScanLineBuffer!=NULL) {
     199           0 :         rtl_freeMemory( pScanLineBuffer );
     200           0 :         pScanLineBuffer=NULL;
     201             :     }
     202             : 
     203             : Exit:
     204             : 
     205           8 :     if( bDecompCreated )
     206           8 :         jpeg_destroy_decompress( &cinfo );
     207           8 : }
     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