LCOV - code coverage report
Current view: directory - frmts/gif - gifabstractdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 133 104 78.2 %
Date: 2011-12-18 Functions: 16 11 68.8 %

       1                 : /******************************************************************************
       2                 :  * $Id: gifabstractdataset.cpp 22685 2011-07-10 19:31:35Z rouault $
       3                 :  *
       4                 :  * Project:  GIF Driver
       5                 :  * Purpose:  GIF Abstract Dataset
       6                 :  * Author:   Even Rouault <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ****************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gifabstractdataset.h"
      31                 : 
      32                 : CPL_CVSID("$Id: gifabstractdataset.cpp 22685 2011-07-10 19:31:35Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /* ==================================================================== */
      36                 : /*                         GIFAbstractDataset                           */
      37                 : /* ==================================================================== */
      38                 : /************************************************************************/
      39                 : 
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                         GIFAbstractDataset()                         */
      43                 : /************************************************************************/
      44                 : 
      45              31 : GIFAbstractDataset::GIFAbstractDataset()
      46                 : 
      47                 : {
      48              31 :     hGifFile = NULL;
      49              31 :     fp = NULL;
      50                 : 
      51              31 :     pszProjection = NULL;
      52              31 :     bGeoTransformValid = FALSE;
      53              31 :     adfGeoTransform[0] = 0.0;
      54              31 :     adfGeoTransform[1] = 1.0;
      55              31 :     adfGeoTransform[2] = 0.0;
      56              31 :     adfGeoTransform[3] = 0.0;
      57              31 :     adfGeoTransform[4] = 0.0;
      58              31 :     adfGeoTransform[5] = 1.0;
      59                 : 
      60              31 :     nGCPCount = 0;
      61              31 :     pasGCPList = NULL;
      62                 : 
      63              31 :     bHasReadXMPMetadata = FALSE;
      64              31 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                        ~GIFAbstractDataset()                         */
      68                 : /************************************************************************/
      69                 : 
      70              31 : GIFAbstractDataset::~GIFAbstractDataset()
      71                 : 
      72                 : {
      73              31 :     FlushCache();
      74                 : 
      75              31 :     if ( pszProjection )
      76               0 :         CPLFree( pszProjection );
      77                 : 
      78              31 :     if ( nGCPCount > 0 )
      79                 :     {
      80               0 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
      81               0 :         CPLFree( pasGCPList );
      82                 :     }
      83                 : 
      84              31 :     if( hGifFile )
      85              30 :         DGifCloseFile( hGifFile );
      86                 : 
      87              31 :     if( fp != NULL )
      88              30 :         VSIFCloseL( fp );
      89              31 : }
      90                 : 
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                       GIFCollectXMPMetadata()                        */
      94                 : /************************************************************************/
      95                 : 
      96                 : /* See ยง2.1.2 of http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf */
      97                 : 
      98               1 : static CPLString GIFCollectXMPMetadata(VSILFILE* fp)
      99                 : 
     100                 : {
     101               1 :     CPLString osXMP;
     102                 : 
     103                 :     /* Save current position to avoid disturbing GIF stream decoding */
     104               1 :     vsi_l_offset nCurOffset = VSIFTellL(fp);
     105                 : 
     106                 :     char abyBuffer[2048+1];
     107                 : 
     108               1 :     VSIFSeekL( fp, 0, SEEK_SET );
     109                 : 
     110                 :     /* Loop over file */
     111                 : 
     112               1 :     int iStartSearchOffset = 1024;
     113               0 :     while(TRUE)
     114                 :     {
     115               1 :         int nRead = VSIFReadL( abyBuffer + 1024, 1, 1024, fp );
     116               1 :         if (nRead <= 0)
     117               0 :             break;
     118               1 :         abyBuffer[1024 + nRead] = 0;
     119                 : 
     120                 :         int i;
     121               1 :         int iFoundOffset = -1;
     122             782 :         for(i=iStartSearchOffset;i<1024+nRead - 14;i++)
     123                 :         {
     124             782 :             if (memcmp(abyBuffer + i, "\x21\xff\x0bXMP DataXMP", 14) == 0)
     125                 :             {
     126               1 :                 iFoundOffset = i + 14;
     127               1 :                 break;
     128                 :             }
     129                 :         }
     130                 : 
     131               1 :         iStartSearchOffset = 0;
     132                 : 
     133               1 :         if (iFoundOffset >= 0)
     134                 :         {
     135               1 :             int nSize = 1024 + nRead - iFoundOffset;
     136               1 :             char* pszXMP = (char*)VSIMalloc(nSize + 1);
     137               1 :             if (pszXMP == NULL)
     138               0 :                 break;
     139                 : 
     140               1 :             pszXMP[nSize] = 0;
     141               1 :             memcpy(pszXMP, abyBuffer + iFoundOffset, nSize);
     142                 : 
     143                 :             /* Read from file until we find a NUL character */
     144               1 :             int nLen = (int)strlen(pszXMP);
     145               6 :             while(nLen == nSize)
     146                 :             {
     147               4 :                 char* pszNewXMP = (char*)VSIRealloc(pszXMP, nSize + 1024 + 1);
     148               4 :                 if (pszNewXMP == NULL)
     149               0 :                     break;
     150               4 :                 pszXMP = pszNewXMP;
     151                 : 
     152               4 :                 nRead = VSIFReadL( pszXMP + nSize, 1, 1024, fp );
     153               4 :                 if (nRead <= 0)
     154               0 :                     break;
     155                 : 
     156               4 :                 pszXMP[nSize + nRead] = 0;
     157               4 :                 nLen += (int)strlen(pszXMP + nSize);
     158               4 :                 nSize += nRead;
     159                 :             }
     160                 : 
     161               4 :             if (nLen > 256 && pszXMP[nLen - 1] == '\x01' &&
     162               2 :                 pszXMP[nLen - 2] == '\x02' && pszXMP[nLen - 255] == '\xff' &&
     163               1 :                 pszXMP[nLen - 256] == '\x01')
     164                 :             {
     165               1 :                 pszXMP[nLen - 256] = 0;
     166                 : 
     167               1 :                 osXMP = pszXMP;
     168                 :             }
     169                 : 
     170               1 :             VSIFree(pszXMP);
     171                 : 
     172               1 :             break;
     173                 :         }
     174                 : 
     175               0 :         if (nRead != 1024)
     176               0 :             break;
     177                 : 
     178               0 :         memcpy(abyBuffer, abyBuffer + 1024, 1024);
     179                 :     }
     180                 : 
     181               1 :     VSIFSeekL( fp, nCurOffset, SEEK_SET );
     182                 : 
     183               0 :     return osXMP;
     184                 : }
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                       CollectXMPMetadata()                           */
     188                 : /************************************************************************/
     189                 : 
     190               1 : void GIFAbstractDataset::CollectXMPMetadata()
     191                 : 
     192                 : {
     193               1 :     if (fp == NULL || bHasReadXMPMetadata)
     194               0 :         return;
     195                 : 
     196               1 :     CPLString osXMP = GIFCollectXMPMetadata(fp);
     197               1 :     if (osXMP.size())
     198                 :     {
     199                 :         /* Avoid setting the PAM dirty bit just for that */
     200               1 :         int nOldPamFlags = nPamFlags;
     201                 : 
     202                 :         char *apszMDList[2];
     203               1 :         apszMDList[0] = (char*) osXMP.c_str();
     204               1 :         apszMDList[1] = NULL;
     205               1 :         SetMetadata(apszMDList, "xml:XMP");
     206                 : 
     207               1 :         nPamFlags = nOldPamFlags;
     208                 :     }
     209                 : 
     210               1 :     bHasReadXMPMetadata = TRUE;
     211                 : }
     212                 : 
     213                 : /************************************************************************/
     214                 : /*                           GetMetadata()                              */
     215                 : /************************************************************************/
     216                 : 
     217              36 : char  **GIFAbstractDataset::GetMetadata( const char * pszDomain )
     218                 : {
     219              36 :     if (fp == NULL)
     220               0 :         return NULL;
     221              36 :     if (eAccess == GA_ReadOnly && !bHasReadXMPMetadata &&
     222                 :         (pszDomain != NULL && EQUAL(pszDomain, "xml:XMP")))
     223               1 :         CollectXMPMetadata();
     224              36 :     return GDALPamDataset::GetMetadata(pszDomain);
     225                 : }
     226                 : 
     227                 : /************************************************************************/
     228                 : /*                       GetMetadataItem()                              */
     229                 : /************************************************************************/
     230                 : 
     231              21 : const char *GIFAbstractDataset::GetMetadataItem( const char * pszName,
     232                 :                                          const char * pszDomain )
     233                 : {
     234              21 :     if (fp == NULL)
     235               0 :         return NULL;
     236              21 :     if (eAccess == GA_ReadOnly && !bHasReadXMPMetadata &&
     237                 :         (pszDomain != NULL && EQUAL(pszDomain, "xml:XMP")))
     238               0 :         CollectXMPMetadata();
     239              21 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
     240                 : }
     241                 : 
     242                 : /************************************************************************/
     243                 : /*                        GetProjectionRef()                            */
     244                 : /************************************************************************/
     245                 : 
     246              18 : const char *GIFAbstractDataset::GetProjectionRef()
     247                 : 
     248                 : {
     249              18 :     if ( pszProjection && bGeoTransformValid )
     250               0 :         return pszProjection;
     251                 :     else
     252              18 :         return GDALPamDataset::GetProjectionRef();
     253                 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                          GetGeoTransform()                           */
     257                 : /************************************************************************/
     258                 : 
     259              33 : CPLErr GIFAbstractDataset::GetGeoTransform( double * padfTransform )
     260                 : 
     261                 : {
     262              33 :     if( bGeoTransformValid )
     263                 :     {
     264               0 :         memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     265               0 :         return CE_None;
     266                 :     }
     267                 :     else
     268              33 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     269                 : }
     270                 : 
     271                 : /************************************************************************/
     272                 : /*                            GetGCPCount()                             */
     273                 : /************************************************************************/
     274                 : 
     275               7 : int GIFAbstractDataset::GetGCPCount()
     276                 : 
     277                 : {
     278               7 :     if (nGCPCount > 0)
     279               0 :         return nGCPCount;
     280                 :     else
     281               7 :         return GDALPamDataset::GetGCPCount();
     282                 : }
     283                 : 
     284                 : /************************************************************************/
     285                 : /*                          GetGCPProjection()                          */
     286                 : /************************************************************************/
     287                 : 
     288               0 : const char *GIFAbstractDataset::GetGCPProjection()
     289                 : 
     290                 : {
     291               0 :     if ( pszProjection && nGCPCount > 0 )
     292               0 :         return pszProjection;
     293                 :     else
     294               0 :         return GDALPamDataset::GetGCPProjection();
     295                 : }
     296                 : 
     297                 : /************************************************************************/
     298                 : /*                               GetGCPs()                              */
     299                 : /************************************************************************/
     300                 : 
     301               0 : const GDAL_GCP *GIFAbstractDataset::GetGCPs()
     302                 : 
     303                 : {
     304               0 :     if (nGCPCount > 0)
     305               0 :         return pasGCPList;
     306                 :     else
     307               0 :         return GDALPamDataset::GetGCPs();
     308                 : }
     309                 : 
     310                 : /************************************************************************/
     311                 : /*                             Identify()                               */
     312                 : /************************************************************************/
     313                 : 
     314           23429 : int GIFAbstractDataset::Identify( GDALOpenInfo * poOpenInfo )
     315                 : 
     316                 : {
     317           23429 :     if( poOpenInfo->nHeaderBytes < 8 )
     318           21610 :         return FALSE;
     319                 : 
     320            1819 :     if( strncmp((const char *) poOpenInfo->pabyHeader, "GIF87a",5) != 0
     321                 :         && strncmp((const char *) poOpenInfo->pabyHeader, "GIF89a",5) != 0 )
     322            1788 :         return FALSE;
     323                 : 
     324              31 :     return TRUE;
     325                 : }
     326                 : 
     327                 : /************************************************************************/
     328                 : /*                         DetectGeoreferencing()                       */
     329                 : /************************************************************************/
     330                 : 
     331              30 : void GIFAbstractDataset::DetectGeoreferencing( GDALOpenInfo * poOpenInfo )
     332                 : {
     333                 :     bGeoTransformValid =
     334                 :         GDALReadWorldFile( poOpenInfo->pszFilename, NULL,
     335              30 :                            adfGeoTransform );
     336              30 :     if ( !bGeoTransformValid )
     337                 :     {
     338                 :         bGeoTransformValid =
     339                 :             GDALReadWorldFile( poOpenInfo->pszFilename, ".wld",
     340              30 :                                adfGeoTransform );
     341                 : 
     342              30 :         if ( !bGeoTransformValid )
     343                 :         {
     344                 :             int bOziFileOK =
     345                 :                 GDALReadOziMapFile( poOpenInfo->pszFilename,
     346                 :                                     adfGeoTransform,
     347                 :                                     &pszProjection,
     348              30 :                                     &nGCPCount, &pasGCPList );
     349                 : 
     350              30 :             if ( bOziFileOK && nGCPCount == 0 )
     351               0 :                  bGeoTransformValid = TRUE;
     352                 :         }
     353                 :     }
     354              30 : }

Generated by: LCOV version 1.7