LCOV - code coverage report
Current view: top level - sdext/source/pdfimport/xpdfwrapper - pnghelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 178 0.0 %
Date: 2012-08-25 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 244 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  *  OpenOffice.org - a multi-platform office productivity suite
       5                 :            :  *
       6                 :            :  *  The Contents of this file are made available subject to
       7                 :            :  *  the terms of GNU General Public License Version 2.
       8                 :            :  *
       9                 :            :  *
      10                 :            :  *    GNU General Public License, version 2
      11                 :            :  *    =============================================
      12                 :            :  *    Copyright 2005 by Sun Microsystems, Inc.
      13                 :            :  *    901 San Antonio Road, Palo Alto, CA 94303, USA
      14                 :            :  *
      15                 :            :  *    This program is free software; you can redistribute it and/or
      16                 :            :  *    modify it under the terms of the GNU General Public License as
      17                 :            :  *    published by the Free Software Foundation; either version 2 of
      18                 :            :  *    the License, or (at your option) any later version.
      19                 :            :  *
      20                 :            :  *    This program is distributed in the hope that it will be useful,
      21                 :            :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      22                 :            :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      23                 :            :  *    GNU General Public License for more details.
      24                 :            :  *
      25                 :            :  *    You should have received a copy of the GNU General Public
      26                 :            :  *    License along with this program; if not, write to the Free
      27                 :            :  *    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      28                 :            :  *    Boston, MA 02110-1301, USA.
      29                 :            :  *
      30                 :            :  ************************************************************************/
      31                 :            : 
      32                 :            : #include "pnghelper.hxx"
      33                 :            : #include <sal/macros.h>
      34                 :            : 
      35                 :            : #ifdef SYSTEM_ZLIB
      36                 :            : #include "zlib.h"
      37                 :            : #else
      38                 :            : #define ZLIB_INTERNAL 1
      39                 :            : #include <zlib/zlib.h>
      40                 :            : #endif
      41                 :            : 
      42                 :            : using namespace pdfi;
      43                 :            : 
      44                 :            : // checksum helpers, courtesy of libpng.org
      45                 :            : 
      46                 :            : /* Table of CRCs of all 8-bit messages. */
      47                 :            : sal_uInt32 PngHelper::crc_table[256];
      48                 :            : 
      49                 :            : /* Flag: has the table been computed? Initially false. */
      50                 :            : bool PngHelper::bCRCTableInit = true;
      51                 :            : 
      52                 :            : /* Make the table for a fast CRC. */
      53                 :          0 : void PngHelper::initCRCTable()
      54                 :            : {
      55         [ #  # ]:          0 :     for (sal_uInt32 n = 0; n < 256; n++)
      56                 :            :     {
      57                 :          0 :         sal_uInt32 c = n;
      58         [ #  # ]:          0 :         for (int k = 0; k < 8; k++)
      59                 :            :         {
      60         [ #  # ]:          0 :             if (c & 1)
      61                 :          0 :                 c = 0xedb88320L ^ (c >> 1);
      62                 :            :             else
      63                 :          0 :                 c = c >> 1;
      64                 :            :         }
      65                 :          0 :         crc_table[n] = c;
      66                 :            :     }
      67                 :          0 :     bCRCTableInit = false;
      68                 :          0 : }
      69                 :            : 
      70                 :            : /* Update a running CRC with the bytes buf[0..len-1]--the CRC
      71                 :            :   should be initialized to all 1's, and the transmitted value
      72                 :            :   is the 1's complement of the final running CRC (see the
      73                 :            :   crc() routine below)). */
      74                 :            : 
      75                 :          0 : void PngHelper::updateCRC( sal_uInt32& io_rCRC, const sal_uInt8* i_pBuf, size_t i_nLen )
      76                 :            : {
      77         [ #  # ]:          0 :     if( bCRCTableInit )
      78                 :          0 :         initCRCTable();
      79                 :            : 
      80                 :          0 :     sal_uInt32 nCRC = io_rCRC;
      81         [ #  # ]:          0 :     for( size_t n = 0; n < i_nLen; n++ )
      82                 :          0 :         nCRC = crc_table[(nCRC ^ i_pBuf[n]) & 0xff] ^ (nCRC >> 8);
      83                 :          0 :     io_rCRC = nCRC;
      84                 :          0 : }
      85                 :            : 
      86                 :          0 : sal_uInt32 PngHelper::getCRC( const sal_uInt8* i_pBuf, size_t i_nLen )
      87                 :            : {
      88                 :          0 :     sal_uInt32 nCRC = 0xffffffff;
      89                 :          0 :     updateCRC( nCRC, i_pBuf, i_nLen );
      90                 :          0 :     return nCRC ^ 0xffffffff;
      91                 :            : }
      92                 :            : 
      93                 :          0 : sal_uInt32 PngHelper::deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, OutputBuffer& o_rOut )
      94                 :            : {
      95                 :          0 :     size_t nOrigSize = o_rOut.size();
      96                 :            : 
      97                 :            :     // prepare z stream
      98                 :            :     z_stream aStream;
      99                 :          0 :     aStream.zalloc  = Z_NULL;
     100                 :          0 :     aStream.zfree   = Z_NULL;
     101                 :          0 :     aStream.opaque  = Z_NULL;
     102         [ #  # ]:          0 :     deflateInit( &aStream, Z_BEST_COMPRESSION );
     103                 :          0 :     aStream.avail_in = uInt(i_nLen);
     104                 :          0 :     aStream.next_in = (Bytef*)i_pBuf;
     105                 :            : 
     106                 :            :     sal_uInt8 aOutBuf[ 32768 ];
     107         [ #  # ]:          0 :     do
     108                 :            :     {
     109                 :          0 :         aStream.avail_out = sizeof( aOutBuf );
     110                 :          0 :         aStream.next_out = aOutBuf;
     111                 :            : 
     112 [ #  # ][ #  # ]:          0 :         if( deflate( &aStream, Z_FINISH ) == Z_STREAM_ERROR )
     113                 :            :         {
     114         [ #  # ]:          0 :             deflateEnd( &aStream );
     115                 :            :             // scrao the data of this broken stream
     116         [ #  # ]:          0 :             o_rOut.resize( nOrigSize );
     117                 :          0 :             return 0;
     118                 :            :         }
     119                 :            : 
     120                 :            :         // append compressed bytes
     121                 :          0 :         sal_uInt32 nCompressedBytes = sizeof( aOutBuf ) - aStream.avail_out;
     122         [ #  # ]:          0 :         if( nCompressedBytes )
     123         [ #  # ]:          0 :             o_rOut.insert( o_rOut.end(), aOutBuf, aOutBuf+nCompressedBytes );
     124                 :            : 
     125                 :            :     } while( aStream.avail_out == 0 );
     126                 :            : 
     127                 :            :     // cleanup
     128         [ #  # ]:          0 :     deflateEnd( &aStream );
     129                 :            : 
     130                 :          0 :     return sal_uInt32( o_rOut.size() - nOrigSize );
     131                 :            : }
     132                 :            : 
     133                 :          0 : void PngHelper::appendFileHeader( OutputBuffer& o_rOutputBuf )
     134                 :            : {
     135                 :            :     static const unsigned char aHeader[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
     136                 :            : 
     137                 :          0 :     o_rOutputBuf.insert( o_rOutputBuf.end(), aHeader, aHeader + SAL_N_ELEMENTS(aHeader) );
     138                 :          0 : }
     139                 :            : 
     140                 :          0 : size_t PngHelper::startChunk( const char* pChunkName, OutputBuffer& o_rOutputBuf )
     141                 :            : {
     142                 :          0 :     size_t nIndex = sal_uInt32( o_rOutputBuf.size() );
     143         [ #  # ]:          0 :     o_rOutputBuf.insert( o_rOutputBuf.end(), 4, (Output_t)0 );
     144         [ #  # ]:          0 :     o_rOutputBuf.push_back( pChunkName[0] );
     145         [ #  # ]:          0 :     o_rOutputBuf.push_back( pChunkName[1] );
     146         [ #  # ]:          0 :     o_rOutputBuf.push_back( pChunkName[2] );
     147         [ #  # ]:          0 :     o_rOutputBuf.push_back( pChunkName[3] );
     148                 :          0 :     return nIndex;
     149                 :            : }
     150                 :            : 
     151                 :          0 : void PngHelper::set( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf, size_t i_nIndex )
     152                 :            : {
     153                 :          0 :     o_rOutputBuf[ i_nIndex   ] = (i_nValue & 0xff000000) >> 24;
     154                 :          0 :     o_rOutputBuf[ i_nIndex+1 ] = (i_nValue & 0x00ff0000) >> 16;
     155                 :          0 :     o_rOutputBuf[ i_nIndex+2 ] = (i_nValue & 0x0000ff00) >> 8;
     156                 :          0 :     o_rOutputBuf[ i_nIndex+3 ] = (i_nValue & 0x000000ff);
     157                 :          0 : }
     158                 :            : 
     159                 :          0 : void PngHelper::endChunk( size_t nStart, OutputBuffer& o_rOutputBuf )
     160                 :            : {
     161         [ #  # ]:          0 :     if( nStart+8 > o_rOutputBuf.size() )
     162                 :          0 :         return; // something broken is going on
     163                 :            : 
     164                 :            :     // update chunk length
     165                 :          0 :     size_t nLen = o_rOutputBuf.size() - nStart;
     166                 :          0 :     sal_uInt32 nDataLen = sal_uInt32(nLen)-8;
     167                 :          0 :     set( nDataLen, o_rOutputBuf, nStart );
     168                 :            : 
     169                 :            :     // append chunk crc
     170                 :          0 :     sal_uInt32 nChunkCRC = getCRC( (sal_uInt8*)&o_rOutputBuf[nStart+4], nLen-4 );
     171                 :          0 :     append( nChunkCRC, o_rOutputBuf );
     172                 :            : }
     173                 :            : 
     174                 :          0 : void PngHelper::appendIHDR( OutputBuffer& o_rOutputBuf, int width, int height, int depth, int colortype )
     175                 :            : {
     176                 :          0 :     size_t nStart = startChunk( "IHDR", o_rOutputBuf );
     177                 :          0 :     append( width, o_rOutputBuf );
     178                 :          0 :     append( height, o_rOutputBuf );
     179         [ #  # ]:          0 :     o_rOutputBuf.push_back( Output_t(depth) );
     180         [ #  # ]:          0 :     o_rOutputBuf.push_back( Output_t(colortype) );
     181         [ #  # ]:          0 :     o_rOutputBuf.push_back( 0 ); // compression method deflate
     182         [ #  # ]:          0 :     o_rOutputBuf.push_back( 0 ); // filtering method 0 (default)
     183         [ #  # ]:          0 :     o_rOutputBuf.push_back( 0 ); // no interlacing
     184                 :          0 :     endChunk( nStart, o_rOutputBuf );
     185                 :          0 : }
     186                 :            : 
     187                 :          0 : void PngHelper::appendIEND( OutputBuffer& o_rOutputBuf )
     188                 :            : {
     189                 :          0 :     size_t nStart = startChunk( "IEND", o_rOutputBuf );
     190                 :          0 :     endChunk( nStart, o_rOutputBuf );
     191                 :          0 : }
     192                 :            : 
     193                 :          0 : void PngHelper::createPng( OutputBuffer&     o_rOutputBuf,
     194                 :            :                            Stream*           str,
     195                 :            :                            int               width,
     196                 :            :                            int               height,
     197                 :            :                            GfxRGB&           zeroColor,
     198                 :            :                            GfxRGB&           oneColor,
     199                 :            :                            bool              bIsMask
     200                 :            :                            )
     201                 :            : {
     202         [ #  # ]:          0 :     appendFileHeader( o_rOutputBuf );
     203         [ #  # ]:          0 :     appendIHDR( o_rOutputBuf, width, height, 1, 3 );
     204                 :            : 
     205                 :            :     // write palette
     206         [ #  # ]:          0 :     size_t nIdx = startChunk( "PLTE", o_rOutputBuf );
     207                 :            :     // write colors 0 and 1
     208         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(zeroColor.r));
     209         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(zeroColor.g));
     210         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(zeroColor.b));
     211         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(oneColor.r));
     212         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(oneColor.g));
     213         [ #  # ]:          0 :     o_rOutputBuf.push_back(colToByte(oneColor.b));
     214                 :            :     // end PLTE chunk
     215         [ #  # ]:          0 :     endChunk( nIdx, o_rOutputBuf );
     216                 :            : 
     217         [ #  # ]:          0 :     if( bIsMask )
     218                 :            :     {
     219                 :            :         // write tRNS chunk
     220         [ #  # ]:          0 :         nIdx = startChunk( "tRNS", o_rOutputBuf );
     221         [ #  # ]:          0 :         o_rOutputBuf.push_back( 0xff );
     222         [ #  # ]:          0 :         o_rOutputBuf.push_back( 0 );
     223                 :            :         // end tRNS chunk
     224         [ #  # ]:          0 :         endChunk( nIdx, o_rOutputBuf );
     225                 :            :     }
     226                 :            : 
     227                 :            :     // create scan line data buffer
     228         [ #  # ]:          0 :     OutputBuffer aScanlines;
     229                 :          0 :     int nLineSize = (width + 7)/8;
     230         [ #  # ]:          0 :     aScanlines.reserve( nLineSize * height + height );
     231                 :            : 
     232         [ #  # ]:          0 :     str->reset();
     233         [ #  # ]:          0 :     for( int y = 0; y < height; y++ )
     234                 :            :     {
     235                 :            :         // determine filter type (none) for this scanline
     236         [ #  # ]:          0 :         aScanlines.push_back( 0 );
     237         [ #  # ]:          0 :         for( int x = 0; x < nLineSize; x++ )
     238 [ #  # ][ #  # ]:          0 :             aScanlines.push_back( str->getChar() );
     239                 :            :     }
     240                 :            : 
     241                 :            :     // begin IDAT chunk for scanline data
     242         [ #  # ]:          0 :     nIdx = startChunk( "IDAT", o_rOutputBuf );
     243                 :            :     // compress scanlines
     244 [ #  # ][ #  # ]:          0 :     deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
     245                 :            :     // end IDAT chunk
     246         [ #  # ]:          0 :     endChunk( nIdx, o_rOutputBuf );
     247                 :            : 
     248                 :            :     // output IEND
     249         [ #  # ]:          0 :     appendIEND( o_rOutputBuf );
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
     253                 :            :                            Stream* str,
     254                 :            :                            int width, int height, GfxImageColorMap* colorMap,
     255                 :            :                            Stream* maskStr,
     256                 :            :                            int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap )
     257                 :            : {
     258         [ #  # ]:          0 :     appendFileHeader( o_rOutputBuf );
     259         [ #  # ]:          0 :     appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
     260                 :            : 
     261                 :            :     // initialize stream
     262                 :            :     Guchar *p, *pm;
     263                 :            :     GfxRGB rgb;
     264                 :            :     GfxGray alpha;
     265                 :            :     ImageStream* imgStr =
     266                 :            :         new ImageStream(str,
     267                 :            :                         width,
     268                 :            :                         colorMap->getNumPixelComps(),
     269 [ #  # ][ #  # ]:          0 :                         colorMap->getBits());
     270         [ #  # ]:          0 :     imgStr->reset();
     271                 :            : 
     272                 :            :     // create scan line data buffer
     273         [ #  # ]:          0 :     OutputBuffer aScanlines;
     274         [ #  # ]:          0 :     aScanlines.reserve( width*height*4 + height );
     275                 :            : 
     276         [ #  # ]:          0 :     for( int y=0; y<height; ++y)
     277                 :            :     {
     278         [ #  # ]:          0 :         aScanlines.push_back( 0 );
     279         [ #  # ]:          0 :         p = imgStr->getLine();
     280         [ #  # ]:          0 :         for( int x=0; x<width; ++x)
     281                 :            :         {
     282         [ #  # ]:          0 :             colorMap->getRGB(p, &rgb);
     283         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.r));
     284         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.g));
     285         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.b));
     286         [ #  # ]:          0 :             aScanlines.push_back( 0xff );
     287                 :            : 
     288                 :          0 :             p +=colorMap->getNumPixelComps();
     289                 :            :         }
     290                 :            :     }
     291                 :            : 
     292                 :            : 
     293                 :            :     // now fill in the mask data
     294                 :            : 
     295                 :            :     // CAUTION: originally this was done in one single loop
     296                 :            :     // it caused merry chaos; the reason is that maskStr and str are
     297                 :            :     // not independent streams, it happens that reading one advances
     298                 :            :     // the other, too. Hence the two passes are imperative !
     299                 :            : 
     300                 :            :     // initialize mask stream
     301                 :            :     ImageStream* imgStrMask =
     302                 :            :         new ImageStream(maskStr,
     303                 :            :                         maskWidth,
     304                 :            :                         maskColorMap->getNumPixelComps(),
     305 [ #  # ][ #  # ]:          0 :                         maskColorMap->getBits());
     306                 :            : 
     307         [ #  # ]:          0 :     imgStrMask->reset();
     308         [ #  # ]:          0 :     for( int y = 0; y < maskHeight; ++y )
     309                 :            :     {
     310         [ #  # ]:          0 :         pm = imgStrMask->getLine();
     311         [ #  # ]:          0 :         for( int x = 0; x < maskWidth; ++x )
     312                 :            :         {
     313         [ #  # ]:          0 :             maskColorMap->getGray(pm,&alpha);
     314                 :          0 :             pm += maskColorMap->getNumPixelComps();
     315                 :            :             int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
     316                 :          0 :                          (x*width/maskWidth)*4 + 1  + 3        // mapped column
     317                 :            :                          ;
     318         [ #  # ]:          0 :             aScanlines[ nIndex ] = colToByte(alpha);
     319                 :            :         }
     320                 :            :     }
     321                 :            : 
     322 [ #  # ][ #  # ]:          0 :     delete imgStr;
     323 [ #  # ][ #  # ]:          0 :     delete imgStrMask;
     324                 :            : 
     325                 :            :     // begind IDAT chunk for scanline data
     326         [ #  # ]:          0 :     size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
     327                 :            :     // compress scanlines
     328 [ #  # ][ #  # ]:          0 :     deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
     329                 :            :     // end IDAT chunk
     330         [ #  # ]:          0 :     endChunk( nIdx, o_rOutputBuf );
     331                 :            :     // output IEND
     332         [ #  # ]:          0 :     appendIEND( o_rOutputBuf );
     333                 :          0 : }
     334                 :            : 
     335                 :            : // one bit mask; 0 bits opaque
     336                 :          0 : void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
     337                 :            :                            Stream* str,
     338                 :            :                            int width, int height, GfxImageColorMap* colorMap,
     339                 :            :                            Stream* maskStr,
     340                 :            :                            int maskWidth, int maskHeight,
     341                 :            :                            bool maskInvert
     342                 :            :                           )
     343                 :            : {
     344         [ #  # ]:          0 :     appendFileHeader( o_rOutputBuf );
     345         [ #  # ]:          0 :     appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
     346                 :            : 
     347                 :            :     // initialize stream
     348                 :            :     Guchar *p;
     349                 :            :     GfxRGB rgb;
     350                 :            :     ImageStream* imgStr =
     351                 :            :         new ImageStream(str,
     352                 :            :                         width,
     353                 :            :                         colorMap->getNumPixelComps(),
     354 [ #  # ][ #  # ]:          0 :                         colorMap->getBits());
     355         [ #  # ]:          0 :     imgStr->reset();
     356                 :            : 
     357                 :            :     // create scan line data buffer
     358         [ #  # ]:          0 :     OutputBuffer aScanlines;
     359         [ #  # ]:          0 :     aScanlines.reserve( width*height*4 + height );
     360                 :            : 
     361         [ #  # ]:          0 :     for( int y=0; y<height; ++y)
     362                 :            :     {
     363         [ #  # ]:          0 :         aScanlines.push_back( 0 );
     364         [ #  # ]:          0 :         p = imgStr->getLine();
     365         [ #  # ]:          0 :         for( int x=0; x<width; ++x)
     366                 :            :         {
     367         [ #  # ]:          0 :             colorMap->getRGB(p, &rgb);
     368         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.r));
     369         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.g));
     370         [ #  # ]:          0 :             aScanlines.push_back(colToByte(rgb.b));
     371         [ #  # ]:          0 :             aScanlines.push_back( 0xff );
     372                 :            : 
     373                 :          0 :             p +=colorMap->getNumPixelComps();
     374                 :            :         }
     375                 :            :     }
     376                 :            : 
     377                 :            : 
     378                 :            :     // now fill in the mask data
     379                 :            : 
     380                 :            :     // CAUTION: originally this was done in one single loop
     381                 :            :     // it caused merry chaos; the reason is that maskStr and str are
     382                 :            :     // not independent streams, it happens that reading one advances
     383                 :            :     // the other, too. Hence the two passes are imperative !
     384                 :            : 
     385                 :            :     // initialize mask stream
     386                 :            :     ImageStream* imgStrMask =
     387 [ #  # ][ #  # ]:          0 :         new ImageStream(maskStr, maskWidth, 1, 1);
     388                 :            : 
     389         [ #  # ]:          0 :     imgStrMask->reset();
     390         [ #  # ]:          0 :     for( int y = 0; y < maskHeight; ++y )
     391                 :            :     {
     392         [ #  # ]:          0 :         for( int x = 0; x < maskWidth; ++x )
     393                 :            :         {
     394                 :          0 :             Guchar aPixel = 0;
     395         [ #  # ]:          0 :             imgStrMask->getPixel( &aPixel );
     396                 :            :             int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
     397                 :          0 :                          (x*width/maskWidth)*4 + 1  + 3        // mapped column
     398                 :            :                          ;
     399         [ #  # ]:          0 :             if( maskInvert )
     400 [ #  # ][ #  # ]:          0 :                 aScanlines[ nIndex ] = aPixel ? 0xff : 0x00;
     401                 :            :             else
     402 [ #  # ][ #  # ]:          0 :                 aScanlines[ nIndex ] = aPixel ? 0x00 : 0xff;
     403                 :            :         }
     404                 :            :     }
     405                 :            : 
     406 [ #  # ][ #  # ]:          0 :     delete imgStr;
     407 [ #  # ][ #  # ]:          0 :     delete imgStrMask;
     408                 :            : 
     409                 :            :     // begind IDAT chunk for scanline data
     410         [ #  # ]:          0 :     size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
     411                 :            :     // compress scanlines
     412 [ #  # ][ #  # ]:          0 :     deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
     413                 :            :     // end IDAT chunk
     414         [ #  # ]:          0 :     endChunk( nIdx, o_rOutputBuf );
     415                 :            :     // output IEND
     416         [ #  # ]:          0 :     appendIEND( o_rOutputBuf );
     417                 :          0 : }
     418                 :            : 
     419                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10