LCOV - code coverage report
Current view: directory - frmts/nitf - nitfwritejpeg.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 72 64 88.9 %
Date: 2012-12-26 Functions: 2 2 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: nitfwritejpeg.cpp 21951 2011-03-12 22:02:07Z 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, VSILFILE *fp,
      59                 :                      int nBlockXOff, int nBlockYOff,
      60                 :                      int nBlockXSize, int nBlockYSize,
      61                 :                      int bProgressive, int nQuality,
      62                 :                      const GByte* pabyAPP6, int nRestartInterval,
      63                 :                      GDALProgressFunc pfnProgress, void * pProgressData );
      64                 : #endif
      65                 : 
      66                 : void jpeg_vsiio_src (j_decompress_ptr cinfo, VSILFILE * infile);
      67                 : void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                         NITFWriteJPEGBlock()                         */
      71                 : /************************************************************************/
      72                 : 
      73                 : int 
      74              11 : NITFWriteJPEGBlock( GDALDataset *poSrcDS, VSILFILE *fp,
      75                 :                     int nBlockXOff, int nBlockYOff,
      76                 :                     int nBlockXSize, int nBlockYSize,
      77                 :                     int bProgressive, int nQuality,
      78                 :                     const GByte* pabyAPP6, int nRestartInterval,
      79                 :                     GDALProgressFunc pfnProgress, void * pProgressData )
      80                 : {
      81              11 :     GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
      82                 : #if defined(JPEG_DUAL_MODE_8_12) && !defined(NITFWriteJPEGBlock)
      83              10 :     if( eDT == GDT_UInt16 )
      84                 :     {
      85                 :         return NITFWriteJPEGBlock_12(poSrcDS, fp,
      86                 :                                      nBlockXOff, nBlockYOff,
      87                 :                                      nBlockXSize, nBlockYSize,
      88                 :                                      bProgressive, nQuality,
      89                 :                                      pabyAPP6, nRestartInterval,
      90               1 :                                      pfnProgress, pProgressData );
      91                 :     }
      92                 : #endif
      93                 : 
      94              10 :     int  nBands = poSrcDS->GetRasterCount();
      95              10 :     int  nXSize = poSrcDS->GetRasterXSize();
      96              10 :     int  nYSize = poSrcDS->GetRasterYSize();
      97              10 :     int  anBandList[3] = {1,2,3};
      98                 : 
      99                 : /* -------------------------------------------------------------------- */
     100                 : /*      Initialize JPG access to the file.                              */
     101                 : /* -------------------------------------------------------------------- */
     102                 :     struct jpeg_compress_struct sCInfo;
     103                 :     struct jpeg_error_mgr sJErr;
     104                 :     
     105              10 :     sCInfo.err = jpeg_std_error( &sJErr );
     106              10 :     jpeg_create_compress( &sCInfo );
     107                 : 
     108              10 :     jpeg_vsiio_dest( &sCInfo, fp );
     109                 :     
     110              10 :     sCInfo.image_width = nBlockXSize;
     111              10 :     sCInfo.image_height = nBlockYSize;
     112              10 :     sCInfo.input_components = nBands;
     113                 : 
     114              10 :     if( nBands == 1 )
     115                 :     {
     116               1 :         sCInfo.in_color_space = JCS_GRAYSCALE;
     117                 :     }
     118                 :     else
     119                 :     {
     120               9 :         sCInfo.in_color_space = JCS_RGB;
     121                 :     }
     122                 : 
     123              10 :     jpeg_set_defaults( &sCInfo );
     124                 :     
     125                 : #if defined(JPEG_LIB_MK1_OR_12BIT)
     126               1 :     if( eDT == GDT_UInt16 )
     127                 :     {
     128               1 :         sCInfo.data_precision = 12;
     129                 :     }
     130                 :     else
     131                 :     {
     132               0 :         sCInfo.data_precision = 8;
     133                 :     }
     134                 : #endif
     135                 : 
     136                 :     GDALDataType eWorkDT;
     137                 : #ifdef JPEG_LIB_MK1
     138                 :     sCInfo.bits_in_jsample = sCInfo.data_precision;
     139                 :     eWorkDT = GDT_UInt16; /* Always force to 16 bit for JPEG_LIB_MK1 */
     140                 : #else
     141              10 :     eWorkDT = eDT;
     142                 : #endif
     143                 : 
     144              10 :     sCInfo.write_JFIF_header = FALSE;
     145                 : 
     146                 :     /* Set the restart interval */
     147              10 :     if (nRestartInterval < 0)
     148                 :     {
     149                 :         /* nRestartInterval < 0 means that we will guess the value */
     150                 :         /* so we set it at the maximum allowed by MIL-STD-188-198 */
     151                 :         /* that is to say the number of MCU per row-block */
     152              10 :         nRestartInterval = nBlockXSize / 8;
     153                 :     }
     154                 : 
     155              10 :     if (nRestartInterval > 0)
     156              10 :         sCInfo.restart_interval = nRestartInterval;
     157                 : 
     158              10 :     jpeg_set_quality( &sCInfo, nQuality, TRUE );
     159                 : 
     160              10 :     if( bProgressive )
     161               0 :         jpeg_simple_progression( &sCInfo );
     162                 : 
     163              10 :     jpeg_start_compress( &sCInfo, TRUE );
     164                 : 
     165                 : /* -------------------------------------------------------------------- */
     166                 : /*    Emits APP6 NITF application segment (required by MIL-STD-188-198) */
     167                 : /* -------------------------------------------------------------------- */
     168              10 :     if (pabyAPP6)
     169                 :     {
     170                 :         /* 0xe6 = APP6 marker */
     171               4 :         jpeg_write_marker( &sCInfo, 0xe6, (const JOCTET*) pabyAPP6, 23);
     172                 :     }
     173                 : 
     174                 : /* -------------------------------------------------------------------- */
     175                 : /*      Loop over image, copying image data.                            */
     176                 : /* -------------------------------------------------------------------- */
     177                 :     GByte   *pabyScanline;
     178              10 :     CPLErr      eErr = CE_None;
     179              10 :     int         nWorkDTSize = GDALGetDataTypeSize(eWorkDT) / 8;
     180                 : 
     181              10 :     pabyScanline = (GByte *) CPLMalloc( nBands * nBlockXSize * nWorkDTSize );
     182                 : 
     183              10 :     double nTotalPixels = (double)nXSize * nYSize;
     184                 : 
     185              10 :     int nBlockXSizeToRead = nBlockXSize;
     186              10 :     if (nBlockXSize * nBlockXOff + nBlockXSize > nXSize)
     187                 :     {
     188               4 :         nBlockXSizeToRead = nXSize - nBlockXSize * nBlockXOff;
     189                 :     }
     190              10 :     int nBlockYSizeToRead = nBlockYSize;
     191              10 :     if (nBlockYSize * nBlockYOff + nBlockYSize > nYSize)
     192                 :     {
     193               4 :         nBlockYSizeToRead = nYSize - nBlockYSize * nBlockYOff;
     194                 :     }
     195                 :     
     196              10 :     bool bClipWarn = false;
     197             380 :     for( int iLine = 0; iLine < nBlockYSize && eErr == CE_None; iLine++ )
     198                 :     {
     199                 :         JSAMPLE      *ppSamples;
     200                 : 
     201             370 :         if (iLine < nBlockYSizeToRead)
     202                 :         {
     203                 :             eErr = poSrcDS->RasterIO( GF_Read, nBlockXSize * nBlockXOff, iLine + nBlockYSize * nBlockYOff, nBlockXSizeToRead, 1, 
     204                 :                                     pabyScanline, nBlockXSizeToRead, 1, eWorkDT,
     205                 :                                     nBands, anBandList, 
     206             314 :                                     nBands*nWorkDTSize, nBands * nBlockXSize * nWorkDTSize, nWorkDTSize );
     207                 : 
     208                 : #if !defined(JPEG_LIB_MK1_OR_12BIT)
     209                 :             /* Repeat the last pixel till the end of the line */
     210                 :             /* to minimize discontinuity */
     211             250 :             if (nBlockXSizeToRead < nBlockXSize)
     212                 :             {
     213             400 :                 for (int iBand = 0; iBand < nBands; iBand++)
     214                 :                 {
     215             300 :                     GByte bVal = pabyScanline[nBands * (nBlockXSizeToRead - 1) + iBand];
     216            4500 :                     for(int iX = nBlockXSizeToRead; iX < nBlockXSize; iX ++)
     217                 :                     {
     218            4200 :                         pabyScanline[nBands * iX + iBand ] = bVal;
     219                 :                     }
     220                 :                 }
     221                 :             }
     222                 : #endif
     223                 :         }
     224                 : 
     225                 :         // clamp 16bit values to 12bit.
     226             370 :         if( eDT == GDT_UInt16 )
     227                 :         {
     228              64 :             GUInt16 *panScanline = (GUInt16 *) pabyScanline;
     229                 :             int iPixel;
     230                 : 
     231            4160 :             for( iPixel = 0; iPixel < nXSize*nBands; iPixel++ )
     232                 :             {
     233            4096 :                 if( panScanline[iPixel] > 4095 )
     234                 :                 {
     235               0 :                     panScanline[iPixel] = 4095;
     236               0 :                     if( !bClipWarn )
     237                 :                     {
     238               0 :                         bClipWarn = true;
     239                 :                         CPLError( CE_Warning, CPLE_AppDefined,
     240               0 :                                   "One or more pixels clipped to fit 12bit domain for jpeg output." );
     241                 :                     }
     242                 :                 }
     243                 :             }
     244                 :         }
     245                 : 
     246             370 :         ppSamples = (JSAMPLE *) pabyScanline;
     247                 : 
     248             370 :         if( eErr == CE_None )
     249             370 :             jpeg_write_scanlines( &sCInfo, &ppSamples, 1 );
     250                 : 
     251                 :         double nCurPixels = (double)nBlockYOff * nBlockYSize * nXSize +
     252             370 :                             (double)nBlockXOff * nBlockYSize * nBlockXSize + (iLine + 1) * nBlockXSizeToRead;
     253             370 :         if( eErr == CE_None 
     254                 :             && !pfnProgress( nCurPixels / nTotalPixels, NULL, pProgressData ) )
     255                 :         {
     256               0 :             eErr = CE_Failure;
     257                 :             CPLError( CE_Failure, CPLE_UserInterrupt, 
     258               0 :                       "User terminated CreateCopy()" );
     259                 :         }
     260                 :     }
     261                 : 
     262                 : /* -------------------------------------------------------------------- */
     263                 : /*      Cleanup and close.                                              */
     264                 : /* -------------------------------------------------------------------- */
     265              10 :     CPLFree( pabyScanline );
     266                 : 
     267              10 :     if( eErr == CE_None )
     268              10 :         jpeg_finish_compress( &sCInfo );
     269              10 :     jpeg_destroy_compress( &sCInfo );
     270                 : 
     271              10 :     return eErr == CE_None;
     272                 : }
     273                 : #endif /* def JPEG_SUPPORTED */

Generated by: LCOV version 1.7