EVOLUTION-MANAGER
Edit File: jpgdataset.h
/****************************************************************************** * $Id: jpgdataset.cpp 37340 2017-02-11 18:28:02Z goatbar * * Project: JPEG JFIF Driver * Purpose: Implement GDAL JPEG Support based on IJG libjpeg. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2000, Frank Warmerdam * Copyright (c) 2007-2014, Even Rouault <even dot rouault at mines-paris dot org> * * Portions Copyright (c) Her majesty the Queen in right of Canada as * represented by the Minister of National Defence, 2006. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #undef ENABLE_LIBJPEG_NO_RETURN #include "cpl_port.h" // TODO(schwehr): Run IWYU. #include <cerrno> #include <climits> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #if HAVE_FCNTL_H # include <fcntl.h> #endif #include <setjmp.h> #include <algorithm> #include <string> #include "cpl_conv.h" #include "cpl_error.h" #include "cpl_progress.h" #include "cpl_string.h" #include "cpl_vsi.h" #include "gdal.h" #include "gdal_frmts.h" #include "gdal_pam.h" #include "gdal_priv.h" CPL_C_START #ifdef LIBJPEG_12_PATH # include LIBJPEG_12_PATH #else # include "jpeglib.h" #endif CPL_C_END #include "memdataset.h" #include "vsidataio.h" // TIFF header. typedef struct { GUInt16 tiff_magic; // Magic number (defines byte order). GUInt16 tiff_version; // TIFF version number. GUInt32 tiff_diroff; // byte offset to first directory. } TIFFHeader; // Ok to use setjmp(). #ifdef _MSC_VER # pragma warning(disable:4611) #endif typedef struct { const char *pszFilename; VSILFILE *fpLin; char **papszSiblingFiles; int nScaleFactor; bool bDoPAMInitialize; bool bUseInternalOverviews; } JPGDatasetOpenArgs; #if defined(JPEG_DUAL_MODE_8_12) && !defined(JPGDataset) GDALDataset *JPEGDataset12Open(JPGDatasetOpenArgs *psArgs); GDALDataset *JPEGDataset12CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ); #endif // Do we want to do special processing suitable for when JSAMPLE is a // 16bit value? #if defined(JPEG_LIB_MK1) # define JPEG_LIB_MK1_OR_12BIT 1 #elif BITS_IN_JSAMPLE == 12 # define JPEG_LIB_MK1_OR_12BIT 1 #endif class JPGDatasetCommon; GDALRasterBand *JPGCreateBand(JPGDatasetCommon *poDS, int nBand); typedef void (*my_jpeg_write_m_header)(void *cinfo, int marker, unsigned int datalen); typedef void (*my_jpeg_write_m_byte)(void *cinfo, int val); CPLErr JPGAppendMask( const char *pszJPGFilename, GDALRasterBand *poMask, GDALProgressFunc pfnProgress, void *pProgressData ); void JPGAddEXIFOverview( GDALDataType eWorkDT, GDALDataset *poSrcDS, char** papszOptions, void *cinfo, my_jpeg_write_m_header p_jpeg_write_m_header, my_jpeg_write_m_byte p_jpeg_write_m_byte, GDALDataset *(pCreateCopy)( const char *, GDALDataset *, int, char **, GDALProgressFunc pfnProgress, void *pProgressData ) ); void JPGAddICCProfile( void *pInfo, const char *pszICCProfile, my_jpeg_write_m_header p_jpeg_write_m_header, my_jpeg_write_m_byte p_jpeg_write_m_byte); typedef struct GDALJPEGErrorStruct { jmp_buf setjmp_buffer; bool bNonFatalErrorEncountered; void (*p_previous_emit_message)(j_common_ptr cinfo, int msg_level); GDALJPEGErrorStruct() : bNonFatalErrorEncountered(false), p_previous_emit_message(NULL) { memset(&setjmp_buffer, 0, sizeof(setjmp_buffer)); } } GDALJPEGErrorStruct; /************************************************************************/ /* ==================================================================== */ /* JPGDatasetCommon */ /* ==================================================================== */ /************************************************************************/ class JPGRasterBand; class JPGMaskBand; class JPGDatasetCommon : public GDALPamDataset { protected: friend class JPGRasterBand; friend class JPGMaskBand; int nScaleFactor; bool bHasInitInternalOverviews; int nInternalOverviewsCurrent; int nInternalOverviewsToFree; GDALDataset **papoInternalOverviews; void InitInternalOverviews(); GDALDataset *InitEXIFOverview(); char *pszProjection; bool bGeoTransformValid; double adfGeoTransform[6]; int nGCPCount; GDAL_GCP *pasGCPList; VSILFILE *fpImage; GUIntBig nSubfileOffset; int nLoadedScanline; GByte *pabyScanline; bool bHasReadEXIFMetadata; bool bHasReadXMPMetadata; bool bHasReadICCMetadata; char **papszMetadata; char **papszSubDatasets; bool bigendian; int nExifOffset; int nInterOffset; int nGPSOffset; bool bSwabflag; int nTiffDirStart; int nTIFFHEADER; bool bHasDoneJpegCreateDecompress; bool bHasDoneJpegStartDecompress; virtual CPLErr LoadScanline(int) = 0; virtual CPLErr Restart() = 0; virtual int GetDataPrecision() = 0; virtual int GetOutColorSpace() = 0; bool EXIFInit(VSILFILE *); void ReadICCProfile(); void CheckForMask(); void DecompressMask(); void ReadEXIFMetadata(); void ReadXMPMetadata(); bool bHasCheckedForMask; JPGMaskBand *poMaskBand; GByte *pabyBitMask; bool bMaskLSBOrder; GByte *pabyCMask; int nCMaskSize; // Color space exposed by GDAL. Not necessarily the in_color_space nor // the out_color_space of JPEG library. J_COLOR_SPACE eGDALColorSpace; bool bIsSubfile; bool bHasTriedLoadWorldFileOrTab; void LoadWorldFileOrTab(); CPLString osWldFilename; virtual int CloseDependentDatasets() override; virtual CPLErr IBuildOverviews( const char *, int, int *, int, int *, GDALProgressFunc, void * ) override; public: JPGDatasetCommon(); virtual ~JPGDatasetCommon(); virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, int, int *, GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, GDALRasterIOExtraArg* psExtraArg ) override; virtual CPLErr GetGeoTransform( double * ) override; virtual int GetGCPCount() override; virtual const char *GetGCPProjection() override; virtual const GDAL_GCP *GetGCPs() override; virtual char **GetMetadataDomainList() override; virtual char **GetMetadata( const char *pszDomain = "" ) override; virtual const char *GetMetadataItem( const char *pszName, const char *pszDomain = "" ) override; virtual char **GetFileList(void) override; virtual void FlushCache(void) override; static int Identify( GDALOpenInfo * ); static GDALDataset *Open( GDALOpenInfo * ); }; /************************************************************************/ /* ==================================================================== */ /* JPGDataset */ /* ==================================================================== */ /************************************************************************/ class JPGDataset : public JPGDatasetCommon { GDALJPEGErrorStruct sErrorStruct; bool ErrorOutOnNonFatalError(); static void EmitMessage(j_common_ptr cinfo, int msg_level); struct jpeg_decompress_struct sDInfo; struct jpeg_error_mgr sJErr; virtual CPLErr LoadScanline(int) override; virtual CPLErr Restart() override; virtual int GetDataPrecision() override { return sDInfo.data_precision; } virtual int GetOutColorSpace() override { return sDInfo.out_color_space; } int nQLevel; #if !defined(JPGDataset) void LoadDefaultTables(int); #endif void SetScaleNumAndDenom(); static GDALDataset *OpenStage2( JPGDatasetOpenArgs *psArgs, JPGDataset *&poDS ); public: JPGDataset(); virtual ~JPGDataset(); static GDALDataset *Open( JPGDatasetOpenArgs *psArgs ); static GDALDataset *CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ); static GDALDataset *CreateCopyStage2( const char *pszFilename, GDALDataset *poSrcDS, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData, VSILFILE *fpImage, GDALDataType eDT, int nQuality, bool bAppendMask, GDALJPEGErrorStruct &sErrorStruct, struct jpeg_compress_struct &sCInfo, struct jpeg_error_mgr &sJErr, GByte *&pabyScanline); static void ErrorExit(j_common_ptr cinfo); }; /************************************************************************/ /* ==================================================================== */ /* JPGRasterBand */ /* ==================================================================== */ /************************************************************************/ class JPGRasterBand : public GDALPamRasterBand { friend class JPGDatasetCommon; // We have to keep a pointer to the JPGDataset that this JPGRasterBand // belongs to. In some case, we may have this->poGDS != this->poDS // For example for a JPGRasterBand that is set to a NITFDataset. // In other words, this->poDS doesn't necessary point to a JPGDataset // See ticket #1807. JPGDatasetCommon *poGDS; public: JPGRasterBand(JPGDatasetCommon *, int); virtual ~JPGRasterBand() {} virtual CPLErr IReadBlock( int, int, void * ) override; virtual GDALColorInterp GetColorInterpretation() override; virtual GDALRasterBand *GetMaskBand() override; virtual int GetMaskFlags() override; virtual GDALRasterBand *GetOverview(int i) override; virtual int GetOverviewCount() override; }; #if !defined(JPGDataset) /************************************************************************/ /* ==================================================================== */ /* JPGMaskBand */ /* ==================================================================== */ /************************************************************************/ class JPGMaskBand : public GDALRasterBand { protected: virtual CPLErr IReadBlock( int, int, void * ) override; public: explicit JPGMaskBand( JPGDataset *poDS ); virtual ~JPGMaskBand() {} }; /************************************************************************/ /* GDALRegister_JPEG() */ /************************************************************************/ class GDALJPGDriver: public GDALDriver { public: GDALJPGDriver() {} char **GetMetadata( const char *pszDomain = "" ) override; const char *GetMetadataItem( const char *pszName, const char *pszDomain = "" ) override; }; #endif // !defined(JPGDataset)