LCOV - code coverage report
Current view: directory - frmts/gif - gifabstractdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 123 101 82.1 %
Date: 2012-12-26 Functions: 15 10 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: gifabstractdataset.cpp 25287 2012-12-05 21:17:14Z 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 25287 2012-12-05 21:17:14Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /* ==================================================================== */
      36                 : /*                         GIFAbstractDataset                           */
      37                 : /* ==================================================================== */
      38                 : /************************************************************************/
      39                 : 
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                         GIFAbstractDataset()                         */
      43                 : /************************************************************************/
      44                 : 
      45              33 : GIFAbstractDataset::GIFAbstractDataset()
      46                 : 
      47                 : {
      48              33 :     hGifFile = NULL;
      49              33 :     fp = NULL;
      50                 : 
      51              33 :     pszProjection = NULL;
      52              33 :     bGeoTransformValid = FALSE;
      53              33 :     adfGeoTransform[0] = 0.0;
      54              33 :     adfGeoTransform[1] = 1.0;
      55              33 :     adfGeoTransform[2] = 0.0;
      56              33 :     adfGeoTransform[3] = 0.0;
      57              33 :     adfGeoTransform[4] = 0.0;
      58              33 :     adfGeoTransform[5] = 1.0;
      59                 : 
      60              33 :     nGCPCount = 0;
      61              33 :     pasGCPList = NULL;
      62                 : 
      63              33 :     bHasReadXMPMetadata = FALSE;
      64              33 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                        ~GIFAbstractDataset()                         */
      68                 : /************************************************************************/
      69                 : 
      70              33 : GIFAbstractDataset::~GIFAbstractDataset()
      71                 : 
      72                 : {
      73              33 :     FlushCache();
      74                 : 
      75              33 :     if ( pszProjection )
      76               0 :         CPLFree( pszProjection );
      77                 : 
      78              33 :     if ( nGCPCount > 0 )
      79                 :     {
      80               0 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
      81               0 :         CPLFree( pasGCPList );
      82                 :     }
      83                 : 
      84              33 :     if( hGifFile )
      85              32 :         DGifCloseFile( hGifFile );
      86                 : 
      87              33 :     if( fp != NULL )
      88              32 :         VSIFCloseL( fp );
      89              33 : }
      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               3 : static CPLString GIFCollectXMPMetadata(VSILFILE* fp)
      99                 : 
     100                 : {
     101               3 :     CPLString osXMP;
     102                 : 
     103                 :     /* Save current position to avoid disturbing GIF stream decoding */
     104               3 :     vsi_l_offset nCurOffset = VSIFTellL(fp);
     105                 : 
     106                 :     char abyBuffer[2048+1];
     107                 : 
     108               3 :     VSIFSeekL( fp, 0, SEEK_SET );
     109                 : 
     110                 :     /* Loop over file */
     111                 : 
     112               3 :     int iStartSearchOffset = 1024;
     113               7 :     while(TRUE)
     114                 :     {
     115              10 :         int nRead = VSIFReadL( abyBuffer + 1024, 1, 1024, fp );
     116              10 :         if (nRead <= 0)
     117               0 :             break;
     118              10 :         abyBuffer[1024 + nRead] = 0;
     119                 : 
     120                 :         int i;
     121              10 :         int iFoundOffset = -1;
     122           15089 :         for(i=iStartSearchOffset;i<1024+nRead - 14;i++)
     123                 :         {
     124           15080 :             if (memcmp(abyBuffer + i, "\x21\xff\x0bXMP DataXMP", 14) == 0)
     125                 :             {
     126               1 :                 iFoundOffset = i + 14;
     127               1 :                 break;
     128                 :             }
     129                 :         }
     130                 : 
     131              10 :         iStartSearchOffset = 0;
     132                 : 
     133              10 :         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               9 :         if (nRead != 1024)
     176               2 :             break;
     177                 : 
     178               7 :         memcpy(abyBuffer, abyBuffer + 1024, 1024);
     179                 :     }
     180                 : 
     181               3 :     VSIFSeekL( fp, nCurOffset, SEEK_SET );
     182                 : 
     183               0 :     return osXMP;
     184                 : }
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                       CollectXMPMetadata()                           */
     188                 : /************************************************************************/
     189                 : 
     190               3 : void GIFAbstractDataset::CollectXMPMetadata()
     191                 : 
     192                 : {
     193               3 :     if (fp == NULL || bHasReadXMPMetadata)
     194               0 :         return;
     195                 : 
     196               3 :     CPLString osXMP = GIFCollectXMPMetadata(fp);
     197               3 :     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               3 :     bHasReadXMPMetadata = TRUE;
     211                 : }
     212                 : 
     213                 : /************************************************************************/
     214                 : /*                           GetMetadata()                              */
     215                 : /************************************************************************/
     216                 : 
     217              38 : char  **GIFAbstractDataset::GetMetadata( const char * pszDomain )
     218                 : {
     219              38 :     if (fp == NULL)
     220               0 :         return NULL;
     221              38 :     if (eAccess == GA_ReadOnly && !bHasReadXMPMetadata &&
     222                 :         (pszDomain != NULL && EQUAL(pszDomain, "xml:XMP")))
     223               3 :         CollectXMPMetadata();
     224              38 :     return GDALPamDataset::GetMetadata(pszDomain);
     225                 : }
     226                 : 
     227                 : /************************************************************************/
     228                 : /*                        GetProjectionRef()                            */
     229                 : /************************************************************************/
     230                 : 
     231              21 : const char *GIFAbstractDataset::GetProjectionRef()
     232                 : 
     233                 : {
     234              21 :     if ( pszProjection && bGeoTransformValid )
     235               0 :         return pszProjection;
     236                 :     else
     237              21 :         return GDALPamDataset::GetProjectionRef();
     238                 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                          GetGeoTransform()                           */
     242                 : /************************************************************************/
     243                 : 
     244              35 : CPLErr GIFAbstractDataset::GetGeoTransform( double * padfTransform )
     245                 : 
     246                 : {
     247              35 :     if( bGeoTransformValid )
     248                 :     {
     249               0 :         memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     250               0 :         return CE_None;
     251                 :     }
     252                 :     else
     253              35 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     254                 : }
     255                 : 
     256                 : /************************************************************************/
     257                 : /*                            GetGCPCount()                             */
     258                 : /************************************************************************/
     259                 : 
     260               8 : int GIFAbstractDataset::GetGCPCount()
     261                 : 
     262                 : {
     263               8 :     if (nGCPCount > 0)
     264               0 :         return nGCPCount;
     265                 :     else
     266               8 :         return GDALPamDataset::GetGCPCount();
     267                 : }
     268                 : 
     269                 : /************************************************************************/
     270                 : /*                          GetGCPProjection()                          */
     271                 : /************************************************************************/
     272                 : 
     273               0 : const char *GIFAbstractDataset::GetGCPProjection()
     274                 : 
     275                 : {
     276               0 :     if ( pszProjection && nGCPCount > 0 )
     277               0 :         return pszProjection;
     278                 :     else
     279               0 :         return GDALPamDataset::GetGCPProjection();
     280                 : }
     281                 : 
     282                 : /************************************************************************/
     283                 : /*                               GetGCPs()                              */
     284                 : /************************************************************************/
     285                 : 
     286               0 : const GDAL_GCP *GIFAbstractDataset::GetGCPs()
     287                 : 
     288                 : {
     289               0 :     if (nGCPCount > 0)
     290               0 :         return pasGCPList;
     291                 :     else
     292               0 :         return GDALPamDataset::GetGCPs();
     293                 : }
     294                 : 
     295                 : /************************************************************************/
     296                 : /*                             Identify()                               */
     297                 : /************************************************************************/
     298                 : 
     299           25368 : int GIFAbstractDataset::Identify( GDALOpenInfo * poOpenInfo )
     300                 : 
     301                 : {
     302           25368 :     if( poOpenInfo->nHeaderBytes < 8 )
     303           23430 :         return FALSE;
     304                 : 
     305            1938 :     if( strncmp((const char *) poOpenInfo->pabyHeader, "GIF87a",5) != 0
     306                 :         && strncmp((const char *) poOpenInfo->pabyHeader, "GIF89a",5) != 0 )
     307            1904 :         return FALSE;
     308                 : 
     309              34 :     return TRUE;
     310                 : }
     311                 : 
     312                 : /************************************************************************/
     313                 : /*                         DetectGeoreferencing()                       */
     314                 : /************************************************************************/
     315                 : 
     316              32 : void GIFAbstractDataset::DetectGeoreferencing( GDALOpenInfo * poOpenInfo )
     317                 : {
     318                 :     bGeoTransformValid =
     319                 :         GDALReadWorldFile( poOpenInfo->pszFilename, NULL,
     320              32 :                            adfGeoTransform );
     321              32 :     if ( !bGeoTransformValid )
     322                 :     {
     323                 :         bGeoTransformValid =
     324                 :             GDALReadWorldFile( poOpenInfo->pszFilename, ".wld",
     325              32 :                                adfGeoTransform );
     326                 :     }
     327              32 : }

Generated by: LCOV version 1.7