LCOV - code coverage report
Current view: directory - gcore - gdaljp2box.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 143 111 77.6 %
Date: 2011-12-18 Functions: 20 17 85.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdaljp2box.cpp 23076 2011-09-07 18:28:51Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL 
       5                 :  * Purpose:  GDALJP2Box Implementation - Low level JP2 box reader.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      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 "gdaljp2metadata.h"
      31                 : #include "cpl_string.h"
      32                 : 
      33                 : CPL_CVSID("$Id: gdaljp2box.cpp 23076 2011-09-07 18:28:51Z rouault $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                             GDALJP2Box()                             */
      37                 : /************************************************************************/
      38                 : 
      39             401 : GDALJP2Box::GDALJP2Box( VSILFILE *fpIn )
      40                 : 
      41                 : {
      42             401 :     fpVSIL = fpIn;
      43             401 :     szBoxType[0] = '\0';
      44             401 :     nBoxOffset = -1;
      45             401 :     nDataOffset = -1;
      46             401 :     nBoxLength = 0;
      47                 :     
      48             401 :     pabyData = NULL;
      49             401 : }
      50                 : 
      51                 : /************************************************************************/
      52                 : /*                            ~GDALJP2Box()                             */
      53                 : /************************************************************************/
      54                 : 
      55             401 : GDALJP2Box::~GDALJP2Box()
      56                 : 
      57                 : {
      58             401 :     CPLFree( pabyData );
      59             401 : }
      60                 : 
      61                 : /************************************************************************/
      62                 : /*                             SetOffset()                              */
      63                 : /************************************************************************/
      64                 : 
      65             916 : int  GDALJP2Box::SetOffset( GIntBig nNewOffset )
      66                 : 
      67                 : {
      68             916 :     szBoxType[0] = '\0';
      69             916 :     return VSIFSeekL( fpVSIL, nNewOffset, SEEK_SET ) == 0;
      70                 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                             ReadFirst()                              */
      74                 : /************************************************************************/
      75                 : 
      76             124 : int GDALJP2Box::ReadFirst()
      77                 : 
      78                 : {
      79             124 :     return SetOffset(0) && ReadBox();
      80                 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                              ReadNext()                              */
      84                 : /************************************************************************/
      85                 : 
      86             651 : int GDALJP2Box::ReadNext()
      87                 : 
      88                 : {
      89             651 :     return SetOffset( nBoxOffset + nBoxLength ) && ReadBox();
      90                 : }
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                           ReadFirstChild()                           */
      94                 : /************************************************************************/
      95                 : 
      96             141 : int GDALJP2Box::ReadFirstChild( GDALJP2Box *poSuperBox )
      97                 : 
      98                 : {
      99             141 :     szBoxType[0] = '\0';
     100             141 :     if( !poSuperBox->IsSuperBox() )
     101               0 :         return FALSE;
     102                 : 
     103             141 :     return SetOffset( poSuperBox->nDataOffset ) && ReadBox();
     104                 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                           ReadNextChild()                            */
     108                 : /************************************************************************/
     109                 : 
     110             270 : int GDALJP2Box::ReadNextChild( GDALJP2Box *poSuperBox )
     111                 : 
     112                 : {
     113             270 :     if( !ReadNext() )
     114               0 :         return FALSE;
     115                 : 
     116             270 :     if( nBoxOffset >= poSuperBox->nBoxOffset + poSuperBox->nBoxLength )
     117                 :     {
     118             118 :         szBoxType[0] = '\0';
     119             118 :         return FALSE;
     120                 :     }
     121                 : 
     122             152 :     return TRUE;
     123                 : }
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                              ReadBox()                               */
     127                 : /************************************************************************/
     128                 : 
     129             916 : int GDALJP2Box::ReadBox()
     130                 : 
     131                 : {
     132                 :     GUInt32   nLBox;
     133                 :     GUInt32   nTBox;
     134                 : 
     135             916 :     nBoxOffset = VSIFTellL( fpVSIL );
     136                 : 
     137             916 :     if( VSIFReadL( &nLBox, 4, 1, fpVSIL ) != 1
     138                 :         || VSIFReadL( &nTBox, 4, 1, fpVSIL ) != 1 )
     139                 :     {
     140              72 :         return FALSE;
     141                 :     }
     142                 : 
     143             844 :     memcpy( szBoxType, &nTBox, 4 );
     144             844 :     szBoxType[4] = '\0';
     145                 : 
     146             844 :     nLBox = CPL_MSBWORD32( nLBox );
     147                 : 
     148             844 :     if( nLBox != 1 )
     149                 :     {
     150             844 :         nBoxLength = nLBox;
     151             844 :         nDataOffset = nBoxOffset + 8;
     152                 :     }
     153                 :     else
     154                 :     {
     155                 :         GByte abyXLBox[8];
     156               0 :         if( VSIFReadL( abyXLBox, 8, 1, fpVSIL ) != 1 )
     157               0 :             return FALSE;
     158                 : 
     159                 :         
     160                 :         if( sizeof(nBoxLength) == 8 )
     161                 :         {
     162               0 :             CPL_MSBPTR64( abyXLBox );
     163               0 :             memcpy( &nBoxLength, abyXLBox, 8 );
     164                 :         }
     165                 :         else
     166                 :         {
     167                 :             CPL_MSBPTR32( abyXLBox+4 );
     168                 :             memcpy( &nBoxLength, abyXLBox+4, 4 );
     169                 :         }
     170                 : 
     171               0 :         nDataOffset = nBoxOffset + 16;
     172                 :     }
     173                 : 
     174             844 :     if( nBoxLength == 0 )
     175                 :     {
     176              74 :         VSIFSeekL( fpVSIL, 0, SEEK_END );
     177              74 :         nBoxLength = VSIFTellL( fpVSIL ) - nBoxOffset;
     178                 :     }
     179                 : 
     180             844 :     if( EQUAL(szBoxType,"uuid") )
     181                 :     {
     182             143 :         VSIFReadL( abyUUID, 16, 1, fpVSIL );
     183             143 :         nDataOffset += 16;
     184                 :     }
     185                 : 
     186             844 :     return TRUE;
     187                 : }
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                             IsSuperBox()                             */
     191                 : /************************************************************************/
     192                 : 
     193             141 : int GDALJP2Box::IsSuperBox()
     194                 : 
     195                 : {
     196             141 :     if( EQUAL(GetType(),"asoc") || EQUAL(GetType(),"jp2h")
     197                 :         || EQUAL(GetType(),"res ") )
     198             141 :         return TRUE;
     199                 :     else
     200               0 :         return FALSE;
     201                 : }
     202                 : 
     203                 : /************************************************************************/
     204                 : /*                            ReadBoxData()                             */
     205                 : /************************************************************************/
     206                 : 
     207             139 : GByte *GDALJP2Box::ReadBoxData()
     208                 : 
     209                 : {
     210             139 :     char *pszData = (char *) CPLMalloc((int)GetDataLength() + 1);
     211                 : 
     212             139 :     if( (GIntBig) VSIFReadL( pszData, 1, (int)GetDataLength(), fpVSIL ) 
     213                 :         != GetDataLength() )
     214                 :     {
     215               0 :         CPLFree( pszData );
     216               0 :         return NULL;
     217                 :     }
     218                 : 
     219             139 :     pszData[GetDataLength()] = '\0';
     220                 : 
     221             139 :     return (GByte *) pszData;
     222                 : }
     223                 : 
     224                 : /************************************************************************/
     225                 : /*                           GetDataLength()                            */
     226                 : /************************************************************************/
     227                 : 
     228             946 : GIntBig GDALJP2Box::GetDataLength()
     229                 : {
     230             946 :     return nBoxLength - (nDataOffset - nBoxOffset);
     231                 : }
     232                 : 
     233                 : /************************************************************************/
     234                 : /*                            DumpReadable()                            */
     235                 : /************************************************************************/
     236                 : 
     237               0 : int GDALJP2Box::DumpReadable( FILE *fpOut )
     238                 : 
     239                 : {
     240               0 :     if( fpOut == NULL )
     241               0 :         fpOut = stdout;
     242                 : 
     243                 :     fprintf( fpOut, "  Type=%s, Offset=%d/%d, Data Size=%d",
     244                 :              szBoxType, (int) nBoxOffset, (int) nDataOffset, 
     245               0 :              (int)(nBoxLength - (nDataOffset - nBoxOffset)) );
     246                 : 
     247               0 :     if( IsSuperBox() )
     248                 :     {
     249               0 :         fprintf( fpOut, " (super)" );
     250                 :     }
     251                 : 
     252               0 :     fprintf( fpOut, "\n" );
     253                 :     
     254               0 :     if( IsSuperBox() ) 
     255                 :     {
     256               0 :         GDALJP2Box oSubBox( GetFILE() );
     257                 : 
     258               0 :         for( oSubBox.ReadFirstChild( this );
     259                 :              strlen(oSubBox.GetType()) > 0;
     260                 :              oSubBox.ReadNextChild( this ) )
     261                 :         {
     262               0 :             oSubBox.DumpReadable( fpOut );
     263                 :         }
     264                 : 
     265               0 :         printf( "  (end of %s subboxes)\n", szBoxType );
     266                 :     }
     267                 : 
     268               0 :     if( EQUAL(GetType(),"uuid") )
     269                 :     {
     270               0 :         char *pszHex = CPLBinaryToHex( 16, GetUUID() );
     271               0 :         fprintf( fpOut, "    UUID=%s", pszHex );
     272                 : 
     273               0 :         if( EQUAL(pszHex,"B14BF8BD083D4B43A5AE8CD7D5A6CE03") )
     274               0 :             fprintf( fpOut, " (GeoTIFF)" );
     275               0 :         if( EQUAL(pszHex,"96A9F1F1DC98402DA7AED68E34451809") )
     276               0 :             fprintf( fpOut, " (MSI Worldfile)" );
     277               0 :         CPLFree( pszHex );
     278                 : 
     279               0 :         fprintf( fpOut, "\n" );
     280                 :     }
     281                 : 
     282               0 :     return 0;
     283                 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                              SetType()                               */
     287                 : /************************************************************************/
     288                 : 
     289             136 : void GDALJP2Box::SetType( const char *pszType )
     290                 : 
     291                 : {
     292             136 :     CPLAssert( strlen(pszType) == 4 );
     293                 : 
     294             136 :     memcpy(szBoxType, pszType, 4);
     295             136 :     szBoxType[4] = '\0';
     296             136 : }
     297                 : 
     298                 : /************************************************************************/
     299                 : /*                          SetWritableData()                           */
     300                 : /************************************************************************/
     301                 : 
     302             136 : void GDALJP2Box::SetWritableData( int nLength, const GByte *pabyDataIn )
     303                 : 
     304                 : {
     305             136 :     CPLFree( pabyData );
     306                 :     
     307             136 :     pabyData = (GByte *) CPLMalloc(nLength);
     308             136 :     memcpy( pabyData, pabyDataIn, nLength );
     309                 : 
     310             136 :     nBoxOffset = -9; // virtual offsets for data length computation.
     311             136 :     nDataOffset = -1;
     312                 :     
     313             136 :     nBoxLength = 8 + nLength;
     314             136 : }
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                           CreateUUIDBox()                            */
     318                 : /************************************************************************/
     319                 : 
     320              29 : GDALJP2Box *GDALJP2Box::CreateUUIDBox( 
     321                 :     const GByte *pabyUUID, int nDataSize, GByte *pabyData )
     322                 : 
     323                 : {
     324                 :     GDALJP2Box *poBox;
     325                 : 
     326              29 :     poBox = new GDALJP2Box();
     327              29 :     poBox->SetType( "uuid" );
     328              29 :     memcpy( poBox->abyUUID, pabyUUID, 16 );
     329                 : 
     330              29 :     GByte *pabyMergedData = (GByte *) CPLMalloc(16+nDataSize);
     331              29 :     memcpy( pabyMergedData, pabyUUID, 16 );
     332              29 :     memcpy( pabyMergedData+16, pabyData, nDataSize );
     333                 :     
     334              29 :     poBox->SetWritableData( 16 + nDataSize, pabyMergedData );
     335                 :     
     336              29 :     CPLFree( pabyMergedData );
     337                 : 
     338              29 :     return poBox;
     339                 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                           CreateAsocBox()                            */
     343                 : /************************************************************************/
     344                 : 
     345              42 : GDALJP2Box *GDALJP2Box::CreateAsocBox( int nCount, GDALJP2Box **papoBoxes )
     346                 : 
     347                 : 
     348                 : {
     349              42 :     int nDataSize=0, iBox;
     350                 :     GByte *pabyCompositeData, *pabyNext;
     351                 : 
     352                 : /* -------------------------------------------------------------------- */
     353                 : /*      Compute size of data area of asoc box.                          */
     354                 : /* -------------------------------------------------------------------- */
     355             130 :     for( iBox = 0; iBox < nCount; iBox++ )
     356              88 :         nDataSize += 8 + (int) papoBoxes[iBox]->GetDataLength();
     357                 : 
     358              42 :     pabyNext = pabyCompositeData = (GByte *) CPLMalloc(nDataSize);
     359                 : 
     360                 : /* -------------------------------------------------------------------- */
     361                 : /*      Copy subboxes headers and data into buffer.                     */
     362                 : /* -------------------------------------------------------------------- */
     363             130 :     for( iBox = 0; iBox < nCount; iBox++ )
     364                 :     {
     365                 :         GUInt32   nLBox;
     366                 : 
     367              88 :         nLBox = CPL_MSBWORD32(papoBoxes[iBox]->nBoxLength);
     368              88 :         memcpy( pabyNext, &nLBox, 4 );
     369              88 :         pabyNext += 4;
     370                 : 
     371              88 :         memcpy( pabyNext, papoBoxes[iBox]->szBoxType, 4 );
     372              88 :         pabyNext += 4;
     373                 : 
     374              88 :         memcpy( pabyNext, papoBoxes[iBox]->pabyData, 
     375             176 :                 (int) papoBoxes[iBox]->GetDataLength() );
     376              88 :         pabyNext += papoBoxes[iBox]->GetDataLength();
     377                 :     }
     378                 :     
     379                 : /* -------------------------------------------------------------------- */
     380                 : /*      Create asoc box.                                                */
     381                 : /* -------------------------------------------------------------------- */
     382              42 :     GDALJP2Box *poAsoc = new GDALJP2Box();
     383                 : 
     384              42 :     poAsoc->SetType( "asoc" );
     385              42 :     poAsoc->SetWritableData( nDataSize, pabyCompositeData );
     386                 :     
     387              42 :     CPLFree( pabyCompositeData );
     388                 : 
     389              42 :     return poAsoc;
     390                 : }
     391                 : 
     392                 : /************************************************************************/
     393                 : /*                            CreateLblBox()                            */
     394                 : /************************************************************************/
     395                 : 
     396              19 : GDALJP2Box *GDALJP2Box::CreateLblBox( const char *pszLabel )
     397                 : 
     398                 : {
     399                 :     GDALJP2Box *poBox;
     400                 : 
     401              19 :     poBox = new GDALJP2Box();
     402              19 :     poBox->SetType( "lbl " );
     403              19 :     poBox->SetWritableData( strlen(pszLabel)+1, (const GByte *) pszLabel );
     404                 : 
     405              19 :     return poBox;
     406                 : }
     407                 : 
     408                 : /************************************************************************/
     409                 : /*                       CreateLabelledXMLAssoc()                       */
     410                 : /************************************************************************/
     411                 : 
     412              23 : GDALJP2Box *GDALJP2Box::CreateLabelledXMLAssoc( const char *pszLabel,
     413                 :                                                 const char *pszXML )
     414                 : 
     415                 : {
     416              23 :     GDALJP2Box oLabel, oXML;
     417                 :     GDALJP2Box *aoList[2];
     418                 : 
     419              23 :     oLabel.SetType( "lbl " );
     420              23 :     oLabel.SetWritableData( strlen(pszLabel)+1, (const GByte *) pszLabel );
     421                 : 
     422              23 :     oXML.SetType( "xml " );
     423              23 :     oXML.SetWritableData( strlen(pszXML)+1, (const GByte *) pszXML );
     424                 : 
     425              23 :     aoList[0] = &oLabel;
     426              23 :     aoList[1] = &oXML;
     427                 :     
     428              23 :     return CreateAsocBox( 2, aoList );
     429                 : }
     430                 : 

Generated by: LCOV version 1.7