LCOV - code coverage report
Current view: directory - frmts/gif - biggifdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 161 133 82.6 %
Date: 2010-01-09 Functions: 15 12 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: biggifdataset.cpp 17666 2009-09-22 10:34:11Z mloskot $
       3                 :  *
       4                 :  * Project:  BIGGIF Driver
       5                 :  * Purpose:  Implement GDAL support for reading large GIF files in a 
       6                 :  *           streaming fashion rather than the slurp-into-memory approach
       7                 :  *           of the normal GIF driver.
       8                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       9                 :  *
      10                 :  ******************************************************************************
      11                 :  * Copyright (c) 2001-2008, Frank Warmerdam <warmerdam@pobox.com>
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "gdal_pam.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : CPL_CVSID("$Id: biggifdataset.cpp 17666 2009-09-22 10:34:11Z mloskot $");
      36                 : 
      37                 : CPL_C_START
      38                 : #include "gif_lib.h"
      39                 : CPL_C_END
      40                 : 
      41                 : CPL_C_START
      42                 : void  GDALRegister_BIGGIF(void);
      43                 : CPL_C_END
      44                 : 
      45                 : static const int InterlacedOffset[] = { 0, 4, 2, 1 }; 
      46                 : static const int InterlacedJumps[] = { 8, 8, 4, 2 };  
      47                 : 
      48                 : static int VSIGIFReadFunc( GifFileType *, GifByteType *, int);
      49                 : 
      50                 : /************************************************************************/
      51                 : /* ==================================================================== */
      52                 : /*        BIGGIFDataset       */
      53                 : /* ==================================================================== */
      54                 : /************************************************************************/
      55                 : 
      56                 : class BIGGifRasterBand;
      57                 : 
      58                 : class BIGGIFDataset : public GDALPamDataset
      59                 : {
      60                 :     friend class BIGGifRasterBand;
      61                 : 
      62                 :     FILE *fp;
      63                 : 
      64                 :     GifFileType *hGifFile;
      65                 :     int         nLastLineRead;
      66                 : 
      67                 :     int    bGeoTransformValid;
      68                 :     double adfGeoTransform[6];
      69                 : 
      70                 :     GDALDataset *poWorkDS;
      71                 : 
      72                 :     CPLErr       ReOpen();
      73                 : 
      74                 :   public:
      75                 :                  BIGGIFDataset();
      76                 :                  ~BIGGIFDataset();
      77                 : 
      78                 :     virtual CPLErr GetGeoTransform( double * );
      79                 :     static GDALDataset *Open( GDALOpenInfo * );
      80                 :     static int          Identify( GDALOpenInfo * );
      81                 : };
      82                 : 
      83                 : /************************************************************************/
      84                 : /* ==================================================================== */
      85                 : /*                            BIGGifRasterBand                          */
      86                 : /* ==================================================================== */
      87                 : /************************************************************************/
      88                 : 
      89                 : class BIGGifRasterBand : public GDALPamRasterBand
      90                 : {
      91                 :     friend class BIGGIFDataset;
      92                 : 
      93                 :     int   *panInterlaceMap;
      94                 :     
      95                 :     GDALColorTable *poColorTable;
      96                 : 
      97                 :   public:
      98                 : 
      99                 :                    BIGGifRasterBand( BIGGIFDataset *, int );
     100                 :     virtual       ~BIGGifRasterBand();
     101                 : 
     102                 :     virtual CPLErr IReadBlock( int, int, void * );
     103                 : 
     104                 :     virtual GDALColorInterp GetColorInterpretation();
     105                 :     virtual GDALColorTable *GetColorTable();
     106                 : };
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                          BIGGifRasterBand()                          */
     110                 : /************************************************************************/
     111                 : 
     112               3 : BIGGifRasterBand::BIGGifRasterBand( BIGGIFDataset *poDS, int nBackground )
     113                 : 
     114                 : {
     115               3 :     SavedImage *psImage = poDS->hGifFile->SavedImages + 0;
     116                 : 
     117               3 :     this->poDS = poDS;
     118               3 :     this->nBand = 1;
     119                 : 
     120               3 :     eDataType = GDT_Byte;
     121                 : 
     122               3 :     nBlockXSize = poDS->nRasterXSize;
     123               3 :     nBlockYSize = 1;
     124                 : 
     125                 : /* -------------------------------------------------------------------- */
     126                 : /*      Setup interlacing map if required.                              */
     127                 : /* -------------------------------------------------------------------- */
     128               3 :     panInterlaceMap = NULL;
     129               3 :     if( psImage->ImageDesc.Interlace )
     130                 :     {
     131               3 :         int i, j, iLine = 0;
     132                 : 
     133               3 :         poDS->SetMetadataItem( "INTERLACED", "YES", "IMAGE_STRUCTURE" );
     134                 : 
     135               3 :         panInterlaceMap = (int *) CPLCalloc(poDS->nRasterYSize,sizeof(int));
     136                 : 
     137              15 :   for (i = 0; i < 4; i++)
     138                 :         {
     139           67146 :       for (j = InterlacedOffset[i]; 
     140                 :                  j < poDS->nRasterYSize;
     141           33567 :                  j += InterlacedJumps[i]) 
     142           33567 :                 panInterlaceMap[j] = iLine++;
     143                 :         }
     144                 :     }
     145                 :     else
     146               0 :         poDS->SetMetadataItem( "INTERLACED", "NO", "IMAGE_STRUCTURE" );
     147                 : 
     148                 : /* -------------------------------------------------------------------- */
     149                 : /*      Setup colormap.                                                 */
     150                 : /* -------------------------------------------------------------------- */
     151               3 :     ColorMapObject  *psGifCT = psImage->ImageDesc.ColorMap;
     152               3 :     if( psGifCT == NULL )
     153               3 :         psGifCT = poDS->hGifFile->SColorMap;
     154                 : 
     155               3 :     poColorTable = new GDALColorTable();
     156              51 :     for( int iColor = 0; iColor < psGifCT->ColorCount; iColor++ )
     157                 :     {
     158                 :         GDALColorEntry  oEntry;
     159                 : 
     160              48 :         oEntry.c1 = psGifCT->Colors[iColor].Red;
     161              48 :         oEntry.c2 = psGifCT->Colors[iColor].Green;
     162              48 :         oEntry.c3 = psGifCT->Colors[iColor].Blue;
     163              48 :         oEntry.c4 = 255;
     164                 : 
     165              48 :         poColorTable->SetColorEntry( iColor, &oEntry );
     166                 :     }
     167                 : 
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      If we have a background value, return it here.  Some            */
     170                 : /*      applications might want to treat this as transparent, but in    */
     171                 : /*      many uses this is inappropriate so we don't return it as        */
     172                 : /*      nodata or transparent.                                          */
     173                 : /* -------------------------------------------------------------------- */
     174               3 :     if( nBackground != 255 )
     175                 :     {
     176                 :         char szBackground[10];
     177                 :         
     178               3 :         sprintf( szBackground, "%d", nBackground );
     179               3 :         SetMetadataItem( "GIF_BACKGROUND", szBackground );
     180                 :     }
     181               3 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                           ~BIGGifRasterBand()                           */
     185                 : /************************************************************************/
     186                 : 
     187               6 : BIGGifRasterBand::~BIGGifRasterBand()
     188                 : 
     189                 : {
     190               3 :     if( poColorTable != NULL )
     191               3 :         delete poColorTable;
     192                 : 
     193               3 :     CPLFree( panInterlaceMap );
     194               6 : }
     195                 : 
     196                 : /************************************************************************/
     197                 : /*                             IReadBlock()                             */
     198                 : /************************************************************************/
     199                 : 
     200             400 : CPLErr BIGGifRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     201                 :                                   void * pImage )
     202                 : 
     203                 : {
     204             400 :     BIGGIFDataset *poGDS = (BIGGIFDataset *) poDS;
     205                 : 
     206                 :     CPLAssert( nBlockXOff == 0 );
     207                 : 
     208             400 :     if( panInterlaceMap != NULL )
     209             400 :         nBlockYOff = panInterlaceMap[nBlockYOff];
     210                 : 
     211                 : /* -------------------------------------------------------------------- */
     212                 : /*      Do we already have this line in the work dataset?               */
     213                 : /* -------------------------------------------------------------------- */
     214             400 :     if( poGDS->poWorkDS != NULL && nBlockYOff <= poGDS->nLastLineRead )
     215                 :     {
     216                 :         return poGDS->poWorkDS->
     217                 :             RasterIO( GF_Read, 0, nBlockYOff, nBlockXSize, 1, 
     218                 :                       pImage, nBlockXSize, 1, GDT_Byte, 
     219             198 :                       1, NULL, 0, 0, 0 );
     220                 :     }
     221                 : 
     222                 : /* -------------------------------------------------------------------- */
     223                 : /*      Do we need to restart from the start of the image?              */
     224                 : /* -------------------------------------------------------------------- */
     225             202 :     if( nBlockYOff <= poGDS->nLastLineRead )
     226                 :     {
     227               1 :         if( poGDS->ReOpen() == CE_Failure )
     228               0 :             return CE_Failure;
     229                 :     }
     230                 : 
     231                 : /* -------------------------------------------------------------------- */
     232                 : /*      Read till we get our target line.                               */
     233                 : /* -------------------------------------------------------------------- */
     234            1005 :     while( poGDS->nLastLineRead < nBlockYOff )
     235                 :     {
     236             601 :         if( DGifGetLine( poGDS->hGifFile, (GifPixelType*)pImage, 
     237                 :                          nBlockXSize ) == GIF_ERROR )
     238                 :         {
     239                 :             CPLError( CE_Failure, CPLE_AppDefined,
     240               0 :                       "Failure decoding scanline of GIF file." );
     241               0 :             return CE_Failure;
     242                 :         }
     243                 : 
     244             601 :         poGDS->nLastLineRead++;
     245                 : 
     246             601 :         if( poGDS->poWorkDS != NULL )
     247                 :         {
     248                 :             poGDS->poWorkDS->RasterIO( GF_Write, 
     249                 :                                        0, poGDS->nLastLineRead, nBlockXSize, 1, 
     250                 :                                        pImage, nBlockXSize, 1, GDT_Byte, 
     251             400 :                                        1, NULL, 0, 0, 0 );
     252                 :         }
     253                 :     }
     254                 : 
     255             202 :     return CE_None;
     256                 : }
     257                 : 
     258                 : /************************************************************************/
     259                 : /*                       GetColorInterpretation()                       */
     260                 : /************************************************************************/
     261                 : 
     262               0 : GDALColorInterp BIGGifRasterBand::GetColorInterpretation()
     263                 : 
     264                 : {
     265               0 :     return GCI_PaletteIndex;
     266                 : }
     267                 : 
     268                 : /************************************************************************/
     269                 : /*                           GetColorTable()                            */
     270                 : /************************************************************************/
     271                 : 
     272               0 : GDALColorTable *BIGGifRasterBand::GetColorTable()
     273                 : 
     274                 : {
     275               0 :     return poColorTable;
     276                 : }
     277                 : 
     278                 : /************************************************************************/
     279                 : /* ==================================================================== */
     280                 : /*                             BIGGIFDataset                            */
     281                 : /* ==================================================================== */
     282                 : /************************************************************************/
     283                 : 
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                            BIGGIFDataset()                            */
     287                 : /************************************************************************/
     288                 : 
     289               3 : BIGGIFDataset::BIGGIFDataset()
     290                 : 
     291                 : {
     292               3 :     hGifFile = NULL;
     293               3 :     fp = NULL;
     294               3 :     bGeoTransformValid = FALSE;
     295               3 :     adfGeoTransform[0] = 0.0;
     296               3 :     adfGeoTransform[1] = 1.0;
     297               3 :     adfGeoTransform[2] = 0.0;
     298               3 :     adfGeoTransform[3] = 0.0;
     299               3 :     adfGeoTransform[4] = 0.0;
     300               3 :     adfGeoTransform[5] = 1.0;
     301               3 :     nLastLineRead = -1;
     302               3 :     poWorkDS = NULL;
     303               3 : }
     304                 : 
     305                 : /************************************************************************/
     306                 : /*                           ~BIGGIFDataset()                            */
     307                 : /************************************************************************/
     308                 : 
     309               6 : BIGGIFDataset::~BIGGIFDataset()
     310                 : 
     311                 : {
     312               3 :     FlushCache();
     313               3 :     if( hGifFile )
     314               3 :         DGifCloseFile( hGifFile );
     315               3 :     if( fp != NULL )
     316               3 :         VSIFCloseL( fp );
     317                 : 
     318               3 :     if( poWorkDS != NULL )
     319                 :     {
     320               1 :         CPLString osTempFilename = poWorkDS->GetDescription();
     321                 : 
     322               1 :         GDALClose( (GDALDatasetH) poWorkDS );
     323               1 :         poWorkDS = NULL;
     324                 : 
     325               1 :         GDALDriver *poGTiff = (GDALDriver *) GDALGetDriverByName( "GTiff" );
     326               1 :         poGTiff->Delete( osTempFilename );
     327                 :     }
     328               6 : }
     329                 : 
     330                 : /************************************************************************/
     331                 : /*                          GetGeoTransform()                           */
     332                 : /************************************************************************/
     333                 : 
     334               0 : CPLErr BIGGIFDataset::GetGeoTransform( double * padfTransform )
     335                 : 
     336                 : {
     337               0 :     if( bGeoTransformValid )
     338                 :     {
     339               0 :         memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     340               0 :         return CE_None;
     341                 :     }
     342                 :     else
     343               0 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     344                 : }
     345                 : 
     346                 : /************************************************************************/
     347                 : /*                                Open()                                */
     348                 : /************************************************************************/
     349                 : 
     350            9360 : int BIGGIFDataset::Identify( GDALOpenInfo * poOpenInfo )
     351                 : 
     352                 : {
     353            9360 :     if( poOpenInfo->nHeaderBytes < 8 )
     354            8589 :         return FALSE;
     355                 : 
     356             771 :     if( strncmp((const char *) poOpenInfo->pabyHeader, "GIF87a",5) != 0
     357                 :         && strncmp((const char *) poOpenInfo->pabyHeader, "GIF89a",5) != 0 )
     358             768 :         return FALSE;
     359                 : 
     360               3 :     return TRUE;
     361                 : }
     362                 : 
     363                 : /************************************************************************/
     364                 : /*                               ReOpen()                               */
     365                 : /*                                                                      */
     366                 : /*      (Re)Open the gif file and process past the first image          */
     367                 : /*      descriptor.                                                     */
     368                 : /************************************************************************/
     369                 : 
     370               4 : CPLErr BIGGIFDataset::ReOpen()
     371                 : 
     372                 : {
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      If the file is already open, close it so we can restart.        */
     375                 : /* -------------------------------------------------------------------- */
     376               4 :     if( hGifFile != NULL )
     377               1 :         DGifCloseFile( hGifFile );
     378                 : 
     379                 : /* -------------------------------------------------------------------- */
     380                 : /*      If we are actually reopening, then we assume that access to     */
     381                 : /*      the image data is not strictly once through sequential, and     */
     382                 : /*      we will try to create a working database in a temporary         */
     383                 : /*      directory to hold the image as we read through it the second    */
     384                 : /*      time.                                                           */
     385                 : /* -------------------------------------------------------------------- */
     386               4 :     if( hGifFile != NULL )
     387                 :     {
     388               1 :         GDALDriver *poGTiffDriver = (GDALDriver*) GDALGetDriverByName("GTiff");
     389                 :         
     390               1 :         if( poGTiffDriver != NULL )
     391                 :         {
     392                 :             /* Create as a sparse file to avoid filling up the whole file */
     393                 :             /* while closing and then destroying this temporary dataset */
     394               1 :             const char* apszOptions[] = { "COMPRESS=LZW", "SPARSE_OK=YES", NULL };
     395               1 :             CPLString osTempFilename = CPLGenerateTempFilename("biggif");
     396                 : 
     397               1 :             osTempFilename += ".tif";
     398                 : 
     399                 :             poWorkDS = poGTiffDriver->Create( osTempFilename, 
     400                 :                                               nRasterXSize, nRasterYSize, 1, 
     401               1 :                                               GDT_Byte, const_cast<char**>(apszOptions));
     402                 :         }
     403                 :     }
     404                 : 
     405                 : /* -------------------------------------------------------------------- */
     406                 : /*      Open                                                            */
     407                 : /* -------------------------------------------------------------------- */
     408               4 :     VSIFSeekL( fp, 0, SEEK_SET );
     409                 : 
     410               4 :     nLastLineRead = -1;
     411               4 :     hGifFile = DGifOpen( fp, VSIGIFReadFunc );
     412               4 :     if( hGifFile == NULL )
     413                 :     {
     414                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     415               0 :                   "DGifOpen() failed.  Perhaps the gif file is corrupt?\n" );
     416                 : 
     417               0 :         return CE_Failure;
     418                 :     }
     419                 : 
     420                 : /* -------------------------------------------------------------------- */
     421                 : /*      Find the first image record.                                    */
     422                 : /* -------------------------------------------------------------------- */
     423               4 :     GifRecordType RecordType = TERMINATE_RECORD_TYPE;
     424                 : 
     425               4 :     while( DGifGetRecordType(hGifFile, &RecordType) != GIF_ERROR
     426                 :            && RecordType != TERMINATE_RECORD_TYPE
     427                 :            && RecordType != IMAGE_DESC_RECORD_TYPE ) {}
     428                 : 
     429               4 :     if( RecordType != IMAGE_DESC_RECORD_TYPE )
     430                 :     {
     431               0 :         DGifCloseFile( hGifFile );
     432               0 :         hGifFile = NULL;
     433                 : 
     434                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     435               0 :                   "Failed to find image description record in GIF file." );
     436               0 :         return CE_Failure;
     437                 :     }
     438                 :     
     439               4 :     if (DGifGetImageDesc(hGifFile) == GIF_ERROR)
     440                 :     {
     441               0 :         DGifCloseFile( hGifFile );
     442               0 :         hGifFile = NULL;
     443                 : 
     444                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     445               0 :                   "Image description reading failed in GIF file." );
     446               0 :         return CE_Failure;
     447                 :     }
     448                 :     
     449               4 :     return CE_None;
     450                 : }
     451                 : 
     452                 : 
     453                 : /************************************************************************/
     454                 : /*                                Open()                                */
     455                 : /************************************************************************/
     456                 : 
     457            1637 : GDALDataset *BIGGIFDataset::Open( GDALOpenInfo * poOpenInfo )
     458                 : 
     459                 : {
     460            1637 :     if( !Identify( poOpenInfo ) )
     461            1634 :         return NULL;
     462                 : 
     463               3 :     if( poOpenInfo->eAccess == GA_Update )
     464                 :     {
     465                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     466                 :                   "The GIF driver does not support update access to existing"
     467               0 :                   " files.\n" );
     468               0 :         return NULL;
     469                 :     }
     470                 : 
     471                 : /* -------------------------------------------------------------------- */
     472                 : /*      Open the file.                                                  */
     473                 : /* -------------------------------------------------------------------- */
     474                 :     FILE                *fp;
     475                 : 
     476               3 :     fp = VSIFOpenL( poOpenInfo->pszFilename, "r" );
     477               3 :     if( fp == NULL )
     478               0 :         return NULL;
     479                 : 
     480                 : /* -------------------------------------------------------------------- */
     481                 : /*      Create a corresponding GDALDataset.                             */
     482                 : /* -------------------------------------------------------------------- */
     483                 :     BIGGIFDataset   *poDS;
     484                 : 
     485               3 :     poDS = new BIGGIFDataset();
     486                 : 
     487               3 :     poDS->fp = fp;
     488               3 :     poDS->eAccess = GA_ReadOnly;
     489               3 :     if( poDS->ReOpen() == CE_Failure )
     490                 :     {
     491               0 :         delete poDS;
     492               0 :         return NULL;
     493                 :     }
     494                 : 
     495                 : /* -------------------------------------------------------------------- */
     496                 : /*      Capture some information from the file that is of interest.     */
     497                 : /* -------------------------------------------------------------------- */
     498                 :     
     499               3 :     poDS->nRasterXSize = poDS->hGifFile->SavedImages[0].ImageDesc.Width;
     500               3 :     poDS->nRasterYSize = poDS->hGifFile->SavedImages[0].ImageDesc.Height;
     501                 : 
     502                 : /* -------------------------------------------------------------------- */
     503                 : /*      Create band information objects.                                */
     504                 : /* -------------------------------------------------------------------- */
     505                 :     poDS->SetBand( 1, 
     506                 :                    new BIGGifRasterBand( poDS, 
     507               3 :                                          poDS->hGifFile->SBackGroundColor ));
     508                 : 
     509                 : /* -------------------------------------------------------------------- */
     510                 : /*      Check for world file.                                           */
     511                 : /* -------------------------------------------------------------------- */
     512                 :     poDS->bGeoTransformValid = 
     513                 :         GDALReadWorldFile( poOpenInfo->pszFilename, NULL, 
     514                 :                            poDS->adfGeoTransform )
     515                 :         || GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
     516               6 :                               poDS->adfGeoTransform );
     517                 : 
     518                 : /* -------------------------------------------------------------------- */
     519                 : /*      Initialize any PAM information.                                 */
     520                 : /* -------------------------------------------------------------------- */
     521               3 :     poDS->SetDescription( poOpenInfo->pszFilename );
     522               3 :     poDS->TryLoadXML();
     523                 : 
     524                 : /* -------------------------------------------------------------------- */
     525                 : /*      Support overviews.                                              */
     526                 : /* -------------------------------------------------------------------- */
     527               3 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     528                 : 
     529               3 :     return poDS;
     530                 : }
     531                 : 
     532                 : /************************************************************************/
     533                 : /*                           VSIGIFReadFunc()                           */
     534                 : /*                                                                      */
     535                 : /*      Proxy function for reading from GIF file.                       */
     536                 : /************************************************************************/
     537                 : 
     538             195 : static int VSIGIFReadFunc( GifFileType *psGFile, GifByteType *pabyBuffer, 
     539                 :                            int nBytesToRead )
     540                 : 
     541                 : {
     542                 :     return VSIFReadL( pabyBuffer, 1, nBytesToRead, 
     543             195 :                       (FILE *) psGFile->UserData );
     544                 : }
     545                 : 
     546                 : /************************************************************************/
     547                 : /*                        GDALRegister_BIGGIF()                         */
     548                 : /************************************************************************/
     549                 : 
     550             338 : void GDALRegister_BIGGIF()
     551                 : 
     552                 : {
     553                 :     GDALDriver  *poDriver;
     554                 : 
     555             338 :     if( GDALGetDriverByName( "BIGGIF" ) == NULL )
     556                 :     {
     557             336 :         poDriver = new GDALDriver();
     558                 :         
     559             336 :         poDriver->SetDescription( "BIGGIF" );
     560                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     561             336 :                                    "Graphics Interchange Format (.gif)" );
     562                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     563             336 :                                    "frmt_gif.html" );
     564             336 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "gif" );
     565             336 :         poDriver->SetMetadataItem( GDAL_DMD_MIMETYPE, "image/gif" );
     566             336 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     567                 : 
     568             336 :         poDriver->pfnOpen = BIGGIFDataset::Open;
     569             336 :         poDriver->pfnIdentify = BIGGIFDataset::Identify;
     570                 : 
     571             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     572                 :     }
     573             338 : }
     574                 : 

Generated by: LCOV version 1.7