LCOV - code coverage report
Current view: directory - frmts/nitf - nitfwritejpeg.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 66 58 87.9 %
Date: 2010-01-09 Functions: 2 2 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: nitfwritejpeg.cpp 18142 2009-11-30 20:16:00Z warmerdam $
       3                 :  *
       4                 :  * Project:  NITF Read/Write Translator
       5                 :  * Purpose:  GDALDataset/GDALRasterBand implementation on top of "nitflib".
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam
      10                 :  *
      11                 :  * Portions Copyright (c) Her majesty the Queen in right of Canada as
      12                 :  * represented by the Minister of National Defence, 2006.
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #ifdef JPEG_SUPPORTED
      34                 : 
      35                 : #include "cpl_port.h"
      36                 : #include "gdal_pam.h"
      37                 : 
      38                 : CPL_C_START
      39                 : #ifdef LIBJPEG_12_PATH 
      40                 : #  include LIBJPEG_12_PATH
      41                 : #else
      42                 : #  include "jpeglib.h"
      43                 : #endif
      44                 : CPL_C_END
      45                 : 
      46                 : /*  
      47                 : * Do we want to do special processing suitable for when JSAMPLE is a 
      48                 : * 16bit value?   
      49                 : */ 
      50                 : #if defined(JPEG_LIB_MK1)
      51                 : #  define JPEG_LIB_MK1_OR_12BIT 1
      52                 : #elif BITS_IN_JSAMPLE == 12
      53                 : #  define JPEG_LIB_MK1_OR_12BIT 1
      54                 : #endif
      55                 : 
      56                 : #if defined(JPEG_DUAL_MODE_8_12) && !defined(NITFWriteJPEGBlock)
      57                 : int 
      58                 : NITFWriteJPEGBlock_12( GDALDataset *poSrcDS, FILE *fp,
      59                 :                      int nBlockXOff, int nBlockYOff,
      60                 :                      int nBlockXSize, int nBlockYSize,
      61                 :                      int bProgressive, int nQuality,
      62                 :                      GDALProgressFunc pfnProgress, void * pProgressData );
      63                 : #endif
      64                 : 
      65                 : void jpeg_vsiio_src (j_decompress_ptr cinfo, FILE * infile);
      66                 : void jpeg_vsiio_dest (j_compress_ptr cinfo, FILE * outfile);
      67                 : 
      68                 : /************************************************************************/
      69                 : /*                         NITFWriteJPEGBlock()                         */
      70                 : /************************************************************************/
      71                 : 
      72                 : int 
      73              11 : NITFWriteJPEGBlock( GDALDataset *poSrcDS, FILE *fp,
      74                 :                     int nBlockXOff, int nBlockYOff,
      75                 :                     int nBlockXSize, int nBlockYSize,
      76                 :                     int bProgressive, int nQuality,
      77                 :                     GDALProgressFunc pfnProgress, void * pProgressData )
      78                 : {
      79              11 :     GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
      80                 : #if defined(JPEG_DUAL_MODE_8_12) && !defined(NITFWriteJPEGBlock)
      81              10 :     if( eDT == GDT_UInt16 )
      82                 :     {
      83                 :         return NITFWriteJPEGBlock_12(poSrcDS, fp,
      84                 :                                      nBlockXOff, nBlockYOff,
      85                 :                                      nBlockXSize, nBlockYSize,
      86                 :                                      bProgressive, nQuality,
      87               1 :                                      pfnProgress, pProgressData );
      88                 :     }
      89                 : #endif
      90                 : 
      91              10 :     int  nBands = poSrcDS->GetRasterCount();
      92              10 :     int  nXSize = poSrcDS->GetRasterXSize();
      93              10 :     int  nYSize = poSrcDS->GetRasterYSize();
      94              10 :     int  anBandList[3] = {1,2,3};
      95                 : 
      96                 : /* -------------------------------------------------------------------- */
      97                 : /*      Initialize JPG access to the file.                              */
      98                 : /* -------------------------------------------------------------------- */
      99                 :     struct jpeg_compress_struct sCInfo;
     100                 :     struct jpeg_error_mgr sJErr;
     101                 :     
     102              10 :     sCInfo.err = jpeg_std_error( &sJErr );
     103              10 :     jpeg_create_compress( &sCInfo );
     104                 : 
     105              10 :     jpeg_vsiio_dest( &sCInfo, fp );
     106                 :     
     107              10 :     sCInfo.image_width = nBlockXSize;
     108              10 :     sCInfo.image_height = nBlockYSize;
     109              10 :     sCInfo.input_components = nBands;
     110                 : 
     111              10 :     if( nBands == 1 )
     112                 :     {
     113               1 :         sCInfo.in_color_space = JCS_GRAYSCALE;
     114                 :     }
     115                 :     else
     116                 :     {
     117               9 :         sCInfo.in_color_space = JCS_RGB;
     118                 :     }
     119                 : 
     120              10 :     jpeg_set_defaults( &sCInfo );
     121                 :     
     122                 : #if defined(JPEG_LIB_MK1_OR_12BIT)
     123               1 :     if( eDT == GDT_UInt16 )
     124                 :     {
     125               1 :         sCInfo.data_precision = 12;
     126                 :     }
     127                 :     else
     128                 :     {
     129               0 :         sCInfo.data_precision = 8;
     130                 :     }
     131                 : #endif
     132                 : 
     133                 :     GDALDataType eWorkDT;
     134                 : #ifdef JPEG_LIB_MK1
     135                 :     sCInfo.bits_in_jsample = sCInfo.data_precision;
     136                 :     eWorkDT = GDT_UInt16; /* Always force to 16 bit for JPEG_LIB_MK1 */
     137                 : #else
     138              10 :     eWorkDT = eDT;
     139                 : #endif
     140                 : 
     141              10 :     sCInfo.write_JFIF_header = FALSE;
     142              10 :     jpeg_set_quality( &sCInfo, nQuality, TRUE );
     143                 : 
     144              10 :     if( bProgressive )
     145               0 :         jpeg_simple_progression( &sCInfo );
     146                 : 
     147              10 :     jpeg_start_compress( &sCInfo, TRUE );
     148                 : 
     149                 : /* -------------------------------------------------------------------- */
     150                 : /*      Loop over image, copying image data.                            */
     151                 : /* -------------------------------------------------------------------- */
     152                 :     GByte   *pabyScanline;
     153              10 :     CPLErr      eErr = CE_None;
     154              10 :     int         nWorkDTSize = GDALGetDataTypeSize(eWorkDT) / 8;
     155                 : 
     156              10 :     pabyScanline = (GByte *) CPLMalloc( nBands * nBlockXSize * nWorkDTSize );
     157                 : 
     158              10 :     double nTotalPixels = (double)nXSize * nYSize;
     159                 : 
     160              10 :     int nBlockXSizeToRead = nBlockXSize;
     161              10 :     if (nBlockXSize * nBlockXOff + nBlockXSize > nXSize)
     162                 :     {
     163               4 :         nBlockXSizeToRead = nXSize - nBlockXSize * nBlockXOff;
     164                 :     }
     165              10 :     int nBlockYSizeToRead = nBlockYSize;
     166              10 :     if (nBlockYSize * nBlockYOff + nBlockYSize > nYSize)
     167                 :     {
     168               4 :         nBlockYSizeToRead = nYSize - nBlockYSize * nBlockYOff;
     169                 :     }
     170                 :     
     171              10 :     bool bClipWarn = false;
     172             380 :     for( int iLine = 0; iLine < nBlockYSize && eErr == CE_None; iLine++ )
     173                 :     {
     174                 :         JSAMPLE      *ppSamples;
     175                 : 
     176             370 :         if (iLine < nBlockYSizeToRead)
     177                 :         {
     178                 :             eErr = poSrcDS->RasterIO( GF_Read, nBlockXSize * nBlockXOff, iLine + nBlockYSize * nBlockYOff, nBlockXSizeToRead, 1, 
     179                 :                                     pabyScanline, nBlockXSizeToRead, 1, eWorkDT,
     180                 :                                     nBands, anBandList, 
     181             314 :                                     nBands*nWorkDTSize, nBands * nBlockXSize * nWorkDTSize, nWorkDTSize );
     182                 : 
     183                 : #if !defined(JPEG_LIB_MK1_OR_12BIT)
     184                 :             /* Repeat the last pixel till the end of the line */
     185                 :             /* to minimize discontinuity */
     186             250 :             if (nBlockXSizeToRead < nBlockXSize)
     187                 :             {
     188             400 :                 for (int iBand = 0; iBand < nBands; iBand++)
     189                 :                 {
     190             300 :                     GByte bVal = pabyScanline[nBands * (nBlockXSizeToRead - 1) + iBand];
     191            4500 :                     for(int iX = nBlockXSizeToRead; iX < nBlockXSize; iX ++)
     192                 :                     {
     193            4200 :                         pabyScanline[nBands * iX + iBand ] = bVal;
     194                 :                     }
     195                 :                 }
     196                 :             }
     197                 : #endif
     198                 :         }
     199                 : 
     200                 :         // clamp 16bit values to 12bit.
     201             370 :         if( eDT == GDT_UInt16 )
     202                 :         {
     203              64 :             GUInt16 *panScanline = (GUInt16 *) pabyScanline;
     204                 :             int iPixel;
     205                 : 
     206            4160 :             for( iPixel = 0; iPixel < nXSize*nBands; iPixel++ )
     207                 :             {
     208            4096 :                 if( panScanline[iPixel] > 4095 )
     209                 :                 {
     210               0 :                     panScanline[iPixel] = 4095;
     211               0 :                     if( !bClipWarn )
     212                 :                     {
     213               0 :                         bClipWarn = true;
     214                 :                         CPLError( CE_Warning, CPLE_AppDefined,
     215               0 :                                   "One or more pixels clipped to fit 12bit domain for jpeg output." );
     216                 :                     }
     217                 :                 }
     218                 :             }
     219                 :         }
     220                 : 
     221             370 :         ppSamples = (JSAMPLE *) pabyScanline;
     222                 : 
     223             370 :         if( eErr == CE_None )
     224             370 :             jpeg_write_scanlines( &sCInfo, &ppSamples, 1 );
     225                 : 
     226                 :         double nCurPixels = (double)nBlockYOff * nBlockYSize * nXSize +
     227             370 :                             (double)nBlockXOff * nBlockYSize * nBlockXSize + (iLine + 1) * nBlockXSizeToRead;
     228             370 :         if( eErr == CE_None 
     229                 :             && !pfnProgress( nCurPixels / nTotalPixels, NULL, pProgressData ) )
     230                 :         {
     231               0 :             eErr = CE_Failure;
     232                 :             CPLError( CE_Failure, CPLE_UserInterrupt, 
     233               0 :                       "User terminated CreateCopy()" );
     234                 :         }
     235                 :     }
     236                 : 
     237                 : /* -------------------------------------------------------------------- */
     238                 : /*      Cleanup and close.                                              */
     239                 : /* -------------------------------------------------------------------- */
     240              10 :     CPLFree( pabyScanline );
     241                 : 
     242              10 :     if( eErr == CE_None )
     243              10 :         jpeg_finish_compress( &sCInfo );
     244              10 :     jpeg_destroy_compress( &sCInfo );
     245                 : 
     246              10 :     return eErr == CE_None;
     247                 : }
     248                 : #endif /* def JPEG_SUPPORTED */

Generated by: LCOV version 1.7