LCOV - code coverage report
Current view: directory - frmts/ecw - ecwcreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 483 375 77.6 %
Date: 2010-01-09 Functions: 34 28 82.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: ecwcreatecopy.cpp 17906 2009-10-26 19:47:21Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL ECW Driver
       5                 :  * Purpose:  ECW CreateCopy method implementation.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2001, 2004, 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 "gdal_pam.h"
      31                 : #include "ogr_spatialref.h"
      32                 : #include "cpl_string.h"
      33                 : #include "cpl_conv.h"
      34                 : #include "vsiiostream.h"
      35                 : #include "jp2userbox.h"
      36                 : #include "gdaljp2metadata.h"
      37                 : 
      38                 : CPL_CVSID("$Id: ecwcreatecopy.cpp 17906 2009-10-26 19:47:21Z rouault $");
      39                 : 
      40                 : CPL_C_START
      41                 : CPLErr CPL_DLL GTIFMemBufFromWkt( const char *pszWKT, 
      42                 :                                   const double *padfGeoTransform,
      43                 :                                   int nGCPCount, const GDAL_GCP *pasGCPList,
      44                 :                                   int *pnSize, unsigned char **ppabyBuffer );
      45                 : CPL_C_END
      46                 : 
      47                 : void ECWInitialize( void );
      48                 : 
      49                 : GDALDataset* ECWDatasetOpenJPEG2000(GDALOpenInfo* poOpenInfo);
      50                 : 
      51                 : #if defined(FRMT_ecw) && defined(HAVE_COMPRESS)
      52                 : 
      53                 : class GDALECWCompressor : public CNCSFile {
      54                 : 
      55                 : public:
      56                 :     GDALECWCompressor();
      57                 :     virtual ~GDALECWCompressor();
      58                 : 
      59                 :     virtual CNCSError WriteReadLine(UINT32 nNextLine, void **ppInputArray);
      60                 :     virtual void WriteStatus(UINT32 nCurrentLine);
      61                 :     virtual bool WriteCancel();
      62                 : 
      63                 :     CPLErr  Initialize( const char *pszFilename, char **papszOptions, 
      64                 :                         int nXSize, int nYSize, int nBands, 
      65                 :                         GDALDataType eType, 
      66                 :                         const char *pszWKT, double *padfGeoTransform,
      67                 :                         int nGCPCount, const GDAL_GCP *pasGCPList,
      68                 :                         int bIsJPEG2000 );
      69                 :     CPLErr  CloseDown();
      70                 : 
      71                 :     CPLErr  PrepareCoverageBox( const char *pszWKT, double *padfGeoTransform );
      72                 :     CPLErr  WriteJP2Box( GDALJP2Box * );
      73                 : 
      74                 : #ifdef ECW_FW
      75                 :     CNCSJP2File::CNCSJPXAssocBox  m_oGMLAssoc;
      76                 : #endif
      77                 : 
      78                 :     // Data
      79                 : 
      80                 :     GDALDataset *m_poSrcDS;
      81                 : 
      82                 :     VSIIOStream m_OStream;
      83                 :     int m_nPercentComplete;
      84                 : 
      85                 :     int m_bCancelled;
      86                 : 
      87                 :     GDALProgressFunc  pfnProgress;
      88                 :     void             *pProgressData;
      89                 : 
      90                 :     NCSFileViewFileInfoEx sFileInfo;
      91                 :     GDALDataType eWorkDT;
      92                 : 
      93                 :     JP2UserBox** papoJP2UserBox;
      94                 :     int          nJP2UserBox;
      95                 : };
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                         GDALECWCompressor()                          */
      99                 : /************************************************************************/
     100                 : 
     101              33 : GDALECWCompressor::GDALECWCompressor()
     102                 : 
     103                 : {
     104              33 :     m_poSrcDS = NULL;
     105              33 :     m_nPercentComplete = -1;
     106              33 :     m_bCancelled = FALSE;
     107              33 :     pfnProgress = GDALDummyProgress;
     108              33 :     pProgressData = NULL;
     109              33 :     papoJP2UserBox = NULL;
     110              33 :     nJP2UserBox = 0;
     111              33 : }
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                         ~GDALECWCompressor()                         */
     115                 : /************************************************************************/
     116                 : 
     117              33 : GDALECWCompressor::~GDALECWCompressor()
     118                 : 
     119                 : {
     120                 :     int i;
     121              65 :     for(i=0;i<nJP2UserBox;i++)
     122              32 :         delete papoJP2UserBox[i];
     123              33 :     CPLFree(papoJP2UserBox);
     124              33 : }
     125                 : 
     126                 : /************************************************************************/
     127                 : /*                             CloseDown()                              */
     128                 : /************************************************************************/
     129                 : 
     130              17 : CPLErr GDALECWCompressor::CloseDown()
     131                 : 
     132                 : {
     133              52 :     for( int i = 0; i < sFileInfo.nBands; i++ )
     134                 :     {
     135              35 :         CPLFree( sFileInfo.pBands[i].szDesc );
     136                 :     }
     137              17 :     CPLFree( sFileInfo.pBands );
     138                 : 
     139              17 :     Close( true );
     140                 : 
     141              17 :     return CE_None;
     142                 : }
     143                 : 
     144                 : /************************************************************************/
     145                 : /*                           WriteReadLine()                            */
     146                 : /************************************************************************/
     147                 : 
     148             640 : CNCSError GDALECWCompressor::WriteReadLine( UINT32 nNextLine, 
     149                 :                                             void **ppInputArray )
     150                 : 
     151                 : {
     152                 :     int    iBand, *panBandMap;
     153                 :     CPLErr eErr;
     154                 :     GByte *pabyLineBuf;
     155             640 :     int nWordSize = GDALGetDataTypeSize( eWorkDT ) / 8;
     156                 : 
     157             640 :     panBandMap = (int *) CPLMalloc(sizeof(int) * sFileInfo.nBands);
     158            2350 :     for( iBand = 0; iBand < sFileInfo.nBands; iBand++ )
     159            1710 :         panBandMap[iBand] = iBand+1;
     160                 : 
     161                 :     pabyLineBuf = (GByte *) CPLMalloc( sFileInfo.nSizeX * sFileInfo.nBands
     162             640 :                                        * nWordSize );
     163                 : 
     164                 :     eErr = m_poSrcDS->RasterIO( GF_Read, 0, nNextLine, sFileInfo.nSizeX, 1, 
     165                 :                                 pabyLineBuf, sFileInfo.nSizeX, 1, 
     166                 :                                 eWorkDT, 
     167                 :                                 sFileInfo.nBands, panBandMap,
     168             640 :                                 nWordSize, 0, nWordSize * sFileInfo.nSizeX );
     169                 : 
     170            2350 :     for( iBand = 0; iBand < (int) sFileInfo.nBands; iBand++ )
     171                 :     {
     172                 :         memcpy( ppInputArray[iBand],
     173                 :                 pabyLineBuf + nWordSize * sFileInfo.nSizeX * iBand, 
     174            1710 :                 nWordSize * sFileInfo.nSizeX );
     175                 :     }
     176                 : 
     177             640 :     CPLFree( pabyLineBuf );
     178             640 :     CPLFree( panBandMap );
     179                 : 
     180             640 :     if( eErr == CE_None )
     181             640 :         return NCS_SUCCESS;
     182                 :     else
     183               0 :         return NCS_FILEIO_ERROR;
     184                 : }
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                            WriteStatus()                             */
     188                 : /************************************************************************/
     189                 : 
     190             640 : void GDALECWCompressor::WriteStatus( UINT32 nCurrentLine )
     191                 : 
     192                 : {
     193                 :     m_bCancelled = 
     194                 :         !pfnProgress( nCurrentLine / (float) sFileInfo.nSizeY, 
     195             640 :                       NULL, pProgressData );
     196             640 : }
     197                 : 
     198                 : /************************************************************************/
     199                 : /*                            WriteCancel()                             */
     200                 : /************************************************************************/
     201                 : 
     202             640 : bool GDALECWCompressor::WriteCancel()
     203                 : 
     204                 : {
     205             640 :     return (bool) m_bCancelled;
     206                 : }
     207                 : 
     208                 : /************************************************************************/
     209                 : /*                         PrepareCoverageBox()                         */
     210                 : /************************************************************************/
     211                 : 
     212               0 : CPLErr  GDALECWCompressor::PrepareCoverageBox( const char *pszWKT, 
     213                 :                                                double *padfGeoTransform )
     214                 : 
     215                 : {
     216                 : #ifndef ECW_FW
     217               0 :     return CE_Failure;
     218                 : #else
     219                 : /* -------------------------------------------------------------------- */
     220                 : /*      Try do determine a PCS or GCS code we can use.                  */
     221                 : /* -------------------------------------------------------------------- */
     222                 :     OGRSpatialReference oSRS;
     223                 :     char *pszWKTCopy = (char *) pszWKT;
     224                 :     int nEPSGCode = 0;
     225                 :     char szSRSName[100];
     226                 : 
     227                 :     if( oSRS.importFromWkt( &pszWKTCopy ) != OGRERR_NONE )
     228                 :         return CE_Failure;
     229                 : 
     230                 :     if( oSRS.IsProjected() )
     231                 :     {
     232                 :         const char *pszAuthName = oSRS.GetAuthorityName( "PROJCS" );
     233                 : 
     234                 :         if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
     235                 :         {
     236                 :             nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));
     237                 :         }
     238                 :     }
     239                 :     else if( oSRS.IsGeographic() )
     240                 :     {
     241                 :         const char *pszAuthName = oSRS.GetAuthorityName( "GEOGCS" );
     242                 : 
     243                 :         if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
     244                 :         {
     245                 :             nEPSGCode = atoi(oSRS.GetAuthorityCode( "GEOGCS" ));
     246                 :         }
     247                 :     }
     248                 : 
     249                 :     if( nEPSGCode != 0 )
     250                 :         sprintf( szSRSName, "urn:ogc:def:crs:EPSG::%d", nEPSGCode );
     251                 :     else
     252                 :         strcpy( szSRSName, 
     253                 :                 "gmljp2://xml/CRSDictionary.gml#ogrcrs1" );
     254                 : 
     255                 : /* -------------------------------------------------------------------- */
     256                 : /*      For now we hardcode for a minimal instance format.              */
     257                 : /* -------------------------------------------------------------------- */
     258                 :     char szDoc[4000];
     259                 : 
     260                 :     sprintf( szDoc, 
     261                 : "<gml:FeatureCollection\n"
     262                 : "   xmlns:gml=\"http://www.opengis.net/gml\"\n"
     263                 : "   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
     264                 : "   xsi:schemaLocation=\"http://www.opengis.net/gml http://www.math.ubc.ca/~burggraf/gml/gml4jp2.xsd\">\n"
     265                 : "  <gml:boundedBy>\n"
     266                 : "    <gml:Null>withheld</gml:Null>\n"
     267                 : "  </gml:boundedBy>\n"
     268                 : "  <gml:featureMember>\n"
     269                 : "    <gml:FeatureCollection>\n"
     270                 : "      <gml:featureMember>\n"
     271                 : "        <gml:RectifiedGridCoverage dimension=\"2\" gml:id=\"RGC0001\">\n"
     272                 : "          <gml:rectifiedGridDomain>\n"
     273                 : "            <gml:RectifiedGrid dimension=\"2\">\n"
     274                 : "              <gml:limits>\n"
     275                 : "                <gml:GridEnvelope>\n"
     276                 : "                  <gml:low>0 0</gml:low>\n"
     277                 : "                  <gml:high>%d %d</gml:high>\n"
     278                 : "                </gml:GridEnvelope>\n"
     279                 : "              </gml:limits>\n"
     280                 : "              <gml:axisName>x</gml:axisName>\n"
     281                 : "              <gml:axisName>y</gml:axisName>\n"
     282                 : "              <gml:origin>\n"
     283                 : "                <gml:Point gml:id=\"P0001\" srsName=\"%s\">\n"
     284                 : "                  <gml:pos>%.15g %.15g</gml:pos>\n"
     285                 : "                </gml:Point>\n"
     286                 : "              </gml:origin>\n"
     287                 : "              <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n"
     288                 : "              <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n"
     289                 : "            </gml:RectifiedGrid>\n"
     290                 : "          </gml:rectifiedGridDomain>\n"
     291                 : "          <gml:rangeSet>\n"
     292                 : "            <gml:File>\n"
     293                 : "              <gml:fileName>urn:ogc:tc:gmljp2:codestream:0</gml:fileName>\n"
     294                 : "              <gml:fileStructure>Record Interleaved</gml:fileStructure>\n"
     295                 : "            </gml:File>\n"
     296                 : "          </gml:rangeSet>\n"
     297                 : "        </gml:RectifiedGridCoverage>\n"
     298                 : "      </gml:featureMember>\n"
     299                 : "    </gml:FeatureCollection>\n"
     300                 : "  </gml:featureMember>\n"
     301                 : "</gml:FeatureCollection>\n",
     302                 :              sFileInfo.nSizeX-1, sFileInfo.nSizeY-1, 
     303                 :              szSRSName,
     304                 :              padfGeoTransform[0] + padfGeoTransform[1] * 0.5
     305                 :                                  + padfGeoTransform[4] * 0.5, 
     306                 :              padfGeoTransform[3] + padfGeoTransform[2] * 0.5
     307                 :                                  + padfGeoTransform[5] * 0.5,
     308                 :              szSRSName, 
     309                 :              padfGeoTransform[1], padfGeoTransform[2],
     310                 :              szSRSName,
     311                 :              padfGeoTransform[4], padfGeoTransform[5] );
     312                 : 
     313                 : /* -------------------------------------------------------------------- */
     314                 : /*      If we need a user defined CRSDictionary entry, prepare it       */
     315                 : /*      here.                                                           */
     316                 : /* -------------------------------------------------------------------- */
     317                 :     char *pszDictBox = NULL;
     318                 : 
     319                 :     if( nEPSGCode == 0 )
     320                 :     {
     321                 :         char *pszGMLDef = NULL;
     322                 : 
     323                 :         if( oSRS.exportToXML( &pszGMLDef, NULL ) == OGRERR_NONE )
     324                 :         {
     325                 :             pszDictBox = (char *) CPLMalloc(strlen(pszGMLDef) + 4000);
     326                 :             
     327                 :             sprintf( pszDictBox, 
     328                 : "<gml:Dictionary gml:id=\"CRSU1\" \n"
     329                 : "        xmlns:gml=\"http://www.opengis.net/gml\"\n"
     330                 : "        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
     331                 : "        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
     332                 : "  <gml:dictionaryEntry>\n"
     333                 : "%s\n"
     334                 : "  </gml:dictionaryEntry>\n"
     335                 : "</gml:Dictionary>\n",
     336                 :                      pszGMLDef );
     337                 :         }
     338                 :         CPLFree( pszGMLDef );
     339                 :     }
     340                 : 
     341                 : /* -------------------------------------------------------------------- */
     342                 : /*      Setup the various required boxes.                               */
     343                 : /* -------------------------------------------------------------------- */
     344                 :     JP2UserBox *poGMLData;
     345                 :     CNCSJP2File::CNCSJPXAssocBox *poAssoc;
     346                 :     CNCSJP2File::CNCSJPXLabelBox *poLabel;
     347                 : 
     348                 :     poLabel = new CNCSJP2File::CNCSJPXLabelBox();
     349                 :     poLabel->SetLabel( "gml.data" );
     350                 :     poLabel->m_bValid = true;
     351                 :     m_oGMLAssoc.m_OtherBoxes.push_back( poLabel );
     352                 :     m_oGMLAssoc.m_OwnedBoxes.push_back( poLabel );
     353                 :     
     354                 :     poAssoc = new CNCSJP2File::CNCSJPXAssocBox();
     355                 :     m_oGMLAssoc.m_OtherBoxes.push_back( poAssoc );
     356                 :     m_oGMLAssoc.m_OwnedBoxes.push_back( poAssoc );
     357                 :     poAssoc->m_bValid = true;
     358                 : 
     359                 :     poLabel = new CNCSJP2File::CNCSJPXLabelBox();
     360                 :     poLabel->SetLabel( "gml.root-instance" );
     361                 :     poLabel->m_bValid = true;
     362                 :     poAssoc->m_OtherBoxes.push_back( poLabel );
     363                 :     poAssoc->m_OwnedBoxes.push_back( poLabel );
     364                 : 
     365                 :     poGMLData = new JP2UserBox();
     366                 :     poGMLData->m_nTBox = 'xml ';
     367                 :     poGMLData->SetData( strlen( szDoc ), (unsigned char *) szDoc );
     368                 :     poAssoc->m_OtherBoxes.push_back( poGMLData );
     369                 :     poAssoc->m_OwnedBoxes.push_back( poGMLData );
     370                 : 
     371                 :     if( pszDictBox != NULL )
     372                 :     {
     373                 :         poAssoc = new CNCSJP2File::CNCSJPXAssocBox();
     374                 :         m_oGMLAssoc.m_OtherBoxes.push_back( poAssoc );
     375                 :         m_oGMLAssoc.m_OwnedBoxes.push_back( poAssoc );
     376                 :         poAssoc->m_bValid = true;
     377                 :         
     378                 :         poLabel = new CNCSJP2File::CNCSJPXLabelBox();
     379                 :         poLabel->SetLabel( "CRSDictionary.gml" );
     380                 :         poLabel->m_bValid = true;
     381                 :         poAssoc->m_OtherBoxes.push_back( poLabel );
     382                 :         poAssoc->m_OwnedBoxes.push_back( poLabel );
     383                 : 
     384                 :         poGMLData = new JP2UserBox();
     385                 :         poGMLData->m_nTBox = 'xml ';
     386                 :         poGMLData->SetData( strlen(pszDictBox), 
     387                 :                             (unsigned char *) pszDictBox );
     388                 :         poAssoc->m_OtherBoxes.push_back( poGMLData );
     389                 :         poAssoc->m_OwnedBoxes.push_back( poGMLData );
     390                 : 
     391                 :         CPLFree( pszDictBox );
     392                 :     }
     393                 : 
     394                 :     m_oGMLAssoc.m_bValid = true;
     395                 :     AddBox( &m_oGMLAssoc );
     396                 : 
     397                 :     return CE_None;
     398                 : #endif /* def ECW_FW */
     399                 : }
     400                 : 
     401                 : /************************************************************************/
     402                 : /*                            WriteJP2Box()                             */
     403                 : /************************************************************************/
     404                 : 
     405              34 : CPLErr GDALECWCompressor::WriteJP2Box( GDALJP2Box * poBox )
     406                 : 
     407                 : {
     408                 :     JP2UserBox  *poECWBox;
     409                 : 
     410              34 :     if( poBox == NULL )
     411               2 :         return CE_None;
     412                 : 
     413              32 :     poECWBox = new JP2UserBox();
     414              32 :     memcpy( &(poECWBox->m_nTBox), poBox->GetType(), 4 );
     415                 : 
     416                 :     poECWBox->SetData( poBox->GetDataLength(), 
     417              32 :                        poBox->GetWritableData() );
     418                 : 
     419              32 :     AddBox( poECWBox );
     420                 : 
     421              64 :     delete poBox;
     422                 : 
     423                 :     papoJP2UserBox =(JP2UserBox**) CPLRealloc(papoJP2UserBox,
     424              32 :                                     (nJP2UserBox + 1) * sizeof(JP2UserBox*));
     425              32 :     papoJP2UserBox[nJP2UserBox] = poECWBox;
     426              32 :     nJP2UserBox ++;
     427                 : 
     428              32 :     return CE_None;
     429                 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                        ECWTranslateFromWKT()                         */
     433                 : /************************************************************************/
     434                 : 
     435              16 : static int ECWTranslateFromWKT( const char *pszWKT, 
     436                 :                                 char *pszProjection,
     437                 :                                 int nProjectionLen,
     438                 :                                 char *pszDatum,
     439                 :                                 int nDatumLen)
     440                 : 
     441                 : {
     442              16 :     OGRSpatialReference oSRS;
     443              16 :     char *pszWKTIn = (char *) pszWKT;
     444                 : 
     445              16 :     strcpy( pszProjection, "RAW" );
     446              16 :     strcpy( pszDatum, "RAW" );
     447                 : 
     448              16 :     if( pszWKT == NULL || strlen(pszWKT) == 0 )
     449               1 :         return FALSE;
     450                 :     
     451              15 :     oSRS.importFromWkt( &pszWKTIn );
     452                 :     
     453              15 :     if( oSRS.IsLocal() )
     454               0 :         return TRUE;
     455                 : 
     456                 : /* -------------------------------------------------------------------- */
     457                 : /*      Do we have an overall EPSG number for this coordinate system?   */
     458                 : /* -------------------------------------------------------------------- */
     459              15 :     const char *pszAuthorityCode = NULL;
     460              15 :     const char *pszAuthorityName = NULL;
     461              15 :     UINT32 nEPSGCode = 0;
     462                 : 
     463              15 :     if( oSRS.IsProjected() )
     464                 :     {
     465               3 :         pszAuthorityCode =  oSRS.GetAuthorityCode( "PROJCS" );
     466               3 :         pszAuthorityName =  oSRS.GetAuthorityName( "PROJCS" );
     467                 :     }
     468              12 :     else if( oSRS.IsGeographic() )
     469                 :     {
     470              12 :         pszAuthorityCode =  oSRS.GetAuthorityCode( "GEOGCS" );
     471              12 :         pszAuthorityName =  oSRS.GetAuthorityName( "GEOGCS" );
     472                 :     }
     473                 : 
     474              15 :     if( pszAuthorityName != NULL && EQUAL(pszAuthorityName,"EPSG") 
     475                 :         && pszAuthorityCode != NULL && atoi(pszAuthorityCode) > 0 )
     476              15 :         nEPSGCode = (UINT32) atoi(pszAuthorityCode);
     477                 : 
     478              15 :     if( nEPSGCode != 0 )
     479                 :     {
     480              15 :         char *pszEPSGProj = NULL, *pszEPSGDatum = NULL;
     481              15 :         CNCSError oErr;
     482                 : 
     483                 :         oErr = 
     484                 :             CNCSJP2FileView::GetProjectionAndDatum( atoi(pszAuthorityCode), 
     485              15 :                                                  &pszEPSGProj, &pszEPSGDatum );
     486                 : 
     487                 :         CPLDebug( "ECW", "GetGDTProjDat(%d) = %s/%s", 
     488              15 :                   atoi(pszAuthorityCode), pszEPSGProj, pszEPSGDatum );
     489                 : 
     490              15 :         if( oErr.GetErrorNumber() == NCS_SUCCESS
     491                 :             && pszEPSGProj != NULL && pszEPSGDatum != NULL )
     492                 :         {
     493              15 :             strncpy( pszProjection, pszEPSGProj, nProjectionLen );
     494              15 :             strncpy( pszDatum, pszEPSGDatum, nDatumLen );
     495              15 :             pszProjection[nProjectionLen - 1] = 0;
     496              15 :             pszDatum[nDatumLen - 1] = 0;
     497              15 :             NCSFree( pszEPSGProj );
     498              15 :             NCSFree( pszEPSGDatum );
     499              15 :             return TRUE;
     500                 :         }
     501                 : 
     502               0 :         NCSFree( pszEPSGProj );
     503               0 :         NCSFree( pszEPSGDatum );
     504                 : 
     505                 :     }
     506                 : 
     507                 : /* -------------------------------------------------------------------- */
     508                 : /*      Fallback to translating based on the ecw_cs.wkt file, and       */
     509                 : /*      various jiffy rules.                                            */
     510                 : /* -------------------------------------------------------------------- */
     511                 :     char szUnits[32];
     512                 : 
     513               0 :     return oSRS.exportToERM( pszProjection, pszDatum, szUnits ) == OGRERR_NONE;
     514                 : }
     515                 : 
     516                 : /************************************************************************/
     517                 : /*                             Initialize()                             */
     518                 : /*                                                                      */
     519                 : /*      Initialize compressor output.                                   */
     520                 : /************************************************************************/
     521                 : 
     522              17 : CPLErr GDALECWCompressor::Initialize( 
     523                 :     const char *pszFilename, char **papszOptions, 
     524                 :     int nXSize, int nYSize, int nBands, 
     525                 :     GDALDataType eType, 
     526                 :     const char *pszWKT, double *padfGeoTransform,
     527                 :     int nGCPCount, const GDAL_GCP *pasGCPList,
     528                 :     int bIsJPEG2000 )
     529                 : 
     530                 : {
     531                 : /* -------------------------------------------------------------------- */
     532                 : /*      Do some rudimentary checking in input.                          */
     533                 : /* -------------------------------------------------------------------- */
     534              17 :     if( nBands == 0 )
     535                 :     {
     536                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     537               0 :                   "ECW driver requires at least one band." );
     538               0 :         return CE_Failure;
     539                 :     }
     540                 : 
     541                 : /* -------------------------------------------------------------------- */
     542                 : /*      Parse out some known options.                                   */
     543                 : /* -------------------------------------------------------------------- */
     544              17 :     float      fTargetCompression = 75.0;
     545                 : 
     546              17 :     if( CSLFetchNameValue(papszOptions, "TARGET") != NULL )
     547                 :     {
     548                 :         fTargetCompression = (float) 
     549               1 :             atof(CSLFetchNameValue(papszOptions, "TARGET"));
     550                 :         
     551               1 :         if( fTargetCompression < 0.0 || fTargetCompression > 99.0 )
     552                 :         {
     553                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     554                 :                       "TARGET compression of %.3f invalid, should be a\n"
     555                 :                       "value between 0 and 99 percent.\n", 
     556               0 :                       (double) fTargetCompression );
     557               0 :             return CE_Failure;
     558                 :         }
     559                 :     }
     560                 :         
     561                 : /* -------------------------------------------------------------------- */
     562                 : /*      Create and initialize compressor.                               */
     563                 : /* -------------------------------------------------------------------- */
     564              17 :     NCSFileViewFileInfoEx    *psClient = &(sFileInfo);
     565                 :     
     566              17 :     psClient->nBands = nBands;
     567              17 :     psClient->nSizeX = nXSize;
     568              17 :     psClient->nSizeY = nYSize;
     569              17 :     psClient->nCompressionRate = (int) MAX(1,100 / (100-fTargetCompression));
     570              17 :     psClient->eCellSizeUnits = ECW_CELL_UNITS_METERS;
     571                 : 
     572              17 :     if( nBands == 1 )
     573               8 :         psClient->eColorSpace = NCSCS_GREYSCALE;
     574               9 :     else if( nBands == 3 )
     575               4 :         psClient->eColorSpace = NCSCS_sRGB;
     576                 :     else
     577               5 :         psClient->eColorSpace = NCSCS_MULTIBAND;
     578                 : 
     579                 : /* -------------------------------------------------------------------- */
     580                 : /*      Figure out the data type.                                       */
     581                 : /* -------------------------------------------------------------------- */
     582              17 :     int bSigned = FALSE;
     583              17 :     int nBits = 8;
     584              17 :     eWorkDT = eType;
     585                 : 
     586              17 :     switch( eWorkDT  )
     587                 :     {
     588                 :         case GDT_Byte:
     589              11 :             psClient->eCellType = NCSCT_UINT8;
     590              11 :             nBits = 8;
     591              11 :             bSigned = FALSE;
     592              11 :             break;
     593                 :             
     594                 :         case GDT_UInt16:
     595               1 :             psClient->eCellType = NCSCT_UINT16;
     596               1 :             nBits = 16;
     597               1 :             bSigned = FALSE;
     598               1 :             break;
     599                 :             
     600                 :         case GDT_UInt32:
     601               1 :             psClient->eCellType = NCSCT_UINT32;
     602               1 :             nBits = 32;
     603               1 :             bSigned = FALSE;
     604               1 :             break;
     605                 :             
     606                 :         case GDT_Int16:
     607               2 :             psClient->eCellType = NCSCT_INT16;
     608               2 :             nBits = 16;
     609               2 :             bSigned = TRUE;
     610               2 :             break;
     611                 :             
     612                 :         case GDT_Int32:
     613               1 :             psClient->eCellType = NCSCT_INT32;
     614               1 :             nBits = 32;
     615               1 :             bSigned = TRUE;
     616               1 :             break;
     617                 :             
     618                 :         case GDT_Float32:
     619               1 :             psClient->eCellType = NCSCT_IEEE4;
     620               1 :             nBits = 32;
     621               1 :             bSigned = TRUE;
     622               1 :             break;
     623                 :             
     624                 :         case GDT_Float64:
     625               0 :             psClient->eCellType = NCSCT_IEEE8;
     626               0 :             nBits = 64;
     627               0 :             bSigned = TRUE;
     628               0 :             break;
     629                 : 
     630                 :         default:
     631                 :             // We treat complex types as float.  
     632               0 :             psClient->eCellType = NCSCT_IEEE4;
     633               0 :             nBits = 32;
     634               0 :             bSigned = TRUE;
     635               0 :             eWorkDT = GDT_Float32;
     636                 :             break;
     637                 :     }
     638                 : 
     639                 : /* -------------------------------------------------------------------- */
     640                 : /*      Create band information structures.                             */
     641                 : /* -------------------------------------------------------------------- */
     642                 :     int iBand;
     643                 : 
     644                 :     psClient->pBands = (NCSFileBandInfo *) 
     645              17 :         CPLMalloc( sizeof(NCSFileBandInfo) * nBands );
     646              52 :     for( iBand = 0; iBand < nBands; iBand++ )
     647                 :     {
     648              35 :         psClient->pBands[iBand].nBits = nBits;
     649              35 :         psClient->pBands[iBand].bSigned = bSigned;
     650              35 :         psClient->pBands[iBand].szDesc = CPLStrdup(
     651              35 :             CPLSPrintf("Band%d",iBand+1) );
     652                 :     }
     653                 : 
     654                 : /* -------------------------------------------------------------------- */
     655                 : /*      Allow CNCSFile::SetParameter() requests.                        */
     656                 : /* -------------------------------------------------------------------- */
     657                 :     const char *pszOption;
     658                 : 
     659              17 :     if( bIsJPEG2000 )
     660                 :     {
     661              16 :         pszOption = CSLFetchNameValue(papszOptions, "PROFILE");
     662              16 :         if( pszOption != NULL && EQUAL(pszOption,"BASELINE_0") ) 
     663                 :             SetParameter( 
     664               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_0 );
     665              16 :         else if( pszOption != NULL && EQUAL(pszOption,"BASELINE_1") ) 
     666                 :             SetParameter( 
     667               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_1 );
     668              16 :         else if( pszOption != NULL && EQUAL(pszOption,"BASELINE_2") )
     669                 :             SetParameter( 
     670               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_2 );
     671              19 :         else if( pszOption != NULL && EQUAL(pszOption,"NPJE") ) 
     672                 :             SetParameter( 
     673               3 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_NITF_BIIF_NPJE );
     674              13 :         else if( pszOption != NULL && EQUAL(pszOption,"EPJE") ) 
     675                 :             SetParameter( 
     676               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_NITF_BIIF_EPJE );
     677                 :         
     678              16 :         pszOption = CSLFetchNameValue(papszOptions, "CODESTREAM_ONLY" );
     679              16 :         if( pszOption != NULL ) 
     680                 :             SetParameter(
     681                 :                 CNCSJP2FileView::JP2_COMPRESS_CODESTREAM_ONLY, 
     682               3 :                 (bool) CSLTestBoolean( pszOption ) );
     683                 :         
     684              16 :         pszOption = CSLFetchNameValue(papszOptions, "LEVELS");
     685              16 :         if( pszOption != NULL )
     686                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_LEVELS, 
     687               0 :                                       (UINT32) atoi(pszOption) );
     688                 :         
     689              16 :         pszOption = CSLFetchNameValue(papszOptions, "LAYERS");
     690              16 :         if( pszOption != NULL )
     691                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_LAYERS, 
     692               0 :                                       (UINT32) atoi(pszOption) );
     693                 : 
     694              16 :         pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_WIDTH");
     695              16 :         if( pszOption != NULL )
     696                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_PRECINCT_WIDTH,
     697               0 :                                       (UINT32) atoi(pszOption) );
     698                 : 
     699              16 :         pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_HEIGHT");
     700              16 :         if( pszOption != NULL )
     701                 :             SetParameter(CNCSJP2FileView::JP2_COMPRESS_PRECINCT_HEIGHT, 
     702               0 :                                      (UINT32) atoi(pszOption) );
     703                 : 
     704              16 :         pszOption = CSLFetchNameValue(papszOptions, "TILE_WIDTH");
     705              16 :         if( pszOption != NULL )
     706                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_TILE_WIDTH, 
     707               0 :                                       (UINT32) atoi(pszOption) );
     708                 : 
     709              16 :         pszOption = CSLFetchNameValue(papszOptions, "TILE_HEIGHT");
     710              16 :         if( pszOption != NULL )
     711                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_TILE_HEIGHT, 
     712               0 :                                       (UINT32) atoi(pszOption) );
     713                 : 
     714              16 :         pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_SOP");
     715              16 :         if( pszOption != NULL )
     716                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_INCLUDE_SOP, 
     717               0 :                                       (bool) CSLTestBoolean( pszOption ) );
     718                 :     
     719              16 :         pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_EPH");
     720              16 :         if( pszOption != NULL )
     721                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_INCLUDE_EPH, 
     722               0 :                                       (bool) CSLTestBoolean( pszOption ) );
     723                 :     
     724              16 :         pszOption = CSLFetchNameValue(papszOptions, "PROGRESSION");
     725              16 :         if( pszOption != NULL && EQUAL(pszOption,"LRCP") )
     726                 :             SetParameter( 
     727               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_LRCP );
     728                 :                                   
     729              16 :         else if( pszOption != NULL && EQUAL(pszOption,"RLCP") )
     730                 :             SetParameter( 
     731               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_RLCP );
     732                 : 
     733              16 :         else if( pszOption != NULL && EQUAL(pszOption,"RPCL") )
     734                 :             SetParameter( 
     735               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_RPCL );
     736                 : 
     737              16 :         pszOption = CSLFetchNameValue(papszOptions, "GEODATA_USAGE");
     738              16 :         if( pszOption == NULL )
     739                 :             // Default to supressing ECW SDK geodata, just use our own stuff.
     740              16 :             SetGeodataUsage( JP2_GEODATA_USE_NONE );
     741               0 :         else if( EQUAL(pszOption,"NONE") )
     742               0 :             SetGeodataUsage( JP2_GEODATA_USE_NONE );
     743               0 :         else if( EQUAL(pszOption,"PCS_ONLY") )
     744               0 :             SetGeodataUsage( JP2_GEODATA_USE_PCS_ONLY );
     745               0 :         else if( EQUAL(pszOption,"GML_ONLY") )
     746               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_ONLY );
     747               0 :         else if( EQUAL(pszOption,"PCS_GML") )
     748               0 :             SetGeodataUsage( JP2_GEODATA_USE_PCS_GML );
     749               0 :         else if( EQUAL(pszOption,"GML_PCS") )
     750               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_PCS );
     751               0 :         else if( EQUAL(pszOption,"ALL") )
     752               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_PCS_WLD );
     753                 : 
     754              16 :         pszOption = CSLFetchNameValue(papszOptions, "DECOMPRESS_LAYERS");
     755              16 :         if( pszOption != NULL )
     756                 :             SetParameter( 
     757                 :                 CNCSJP2FileView::JP2_DECOMPRESS_LAYERS, 
     758               0 :                 (UINT32) atoi(pszOption) );
     759                 : 
     760                 :         pszOption = CSLFetchNameValue(papszOptions, 
     761              16 :                                       "DECOMPRESS_RECONSTRUCTION_PARAMETER");
     762              16 :         if( pszOption != NULL )
     763                 :             SetParameter( 
     764                 :                 CNCSJP2FileView::JPC_DECOMPRESS_RECONSTRUCTION_PARAMETER, 
     765               0 :                 (IEEE4) atof(pszOption) );
     766                 :     }
     767                 :                                   
     768                 : /* -------------------------------------------------------------------- */
     769                 : /*      Georeferencing.                                                 */
     770                 : /* -------------------------------------------------------------------- */
     771                 : 
     772              17 :     psClient->fOriginX = 0.0;
     773              17 :     psClient->fOriginY = psClient->nSizeY;
     774              17 :     psClient->fCellIncrementX = 1.0;
     775              17 :     psClient->fCellIncrementY = -1.0;
     776              17 :     psClient->fCWRotationDegrees = 0.0;
     777                 :     
     778              17 :     if( padfGeoTransform[2] != 0.0 || padfGeoTransform[4] != 0.0 )
     779                 :         CPLError( CE_Warning, CPLE_NotSupported, 
     780                 :                   "Rotational coefficients ignored, georeferencing of\n"
     781               0 :                   "output ECW file will be incorrect.\n" );
     782                 :     else
     783                 :     {
     784              17 :         psClient->fOriginX = padfGeoTransform[0];
     785              17 :         psClient->fOriginY = padfGeoTransform[3];
     786              17 :         psClient->fCellIncrementX = padfGeoTransform[1];
     787              17 :         psClient->fCellIncrementY = padfGeoTransform[5];
     788                 :     }
     789                 : 
     790                 : /* -------------------------------------------------------------------- */
     791                 : /*      Projection.                                                     */
     792                 : /* -------------------------------------------------------------------- */
     793                 :     char szProjection[128];
     794                 :     char szDatum[128];
     795                 : 
     796              17 :     strcpy( szProjection, "RAW" );
     797              17 :     strcpy( szDatum, "RAW" );
     798                 :     
     799              17 :     if( CSLFetchNameValue(papszOptions, "PROJ") != NULL )
     800                 :     {
     801                 :         strncpy( szProjection, 
     802               0 :                 CSLFetchNameValue(papszOptions, "PROJ"), sizeof(szProjection) );
     803               0 :         szProjection[sizeof(szProjection)-1] = 0;
     804                 :     }
     805                 : 
     806              17 :     if( CSLFetchNameValue(papszOptions, "DATUM") != NULL )
     807                 :     {
     808               0 :         strncpy( szDatum, CSLFetchNameValue(papszOptions, "DATUM"), sizeof(szDatum) );
     809               0 :         szDatum[sizeof(szDatum)-1] = 0;
     810               0 :         if( EQUAL(szProjection,"RAW") )
     811               0 :             strcpy( szProjection, "GEODETIC" );
     812                 :     }
     813                 : 
     814              17 :     if( EQUAL(szProjection,"RAW") && pszWKT != NULL )
     815                 :     {
     816              16 :         ECWTranslateFromWKT( pszWKT, szProjection, sizeof(szProjection), szDatum, sizeof(szDatum) );
     817                 :     }
     818                 : 
     819              17 :     psClient->szDatum = szDatum;
     820              17 :     psClient->szProjection = szProjection;
     821                 : 
     822                 :     CPLDebug( "ECW", "Writing with PROJ=%s, DATUM=%s", 
     823              17 :               szProjection, szDatum );
     824                 : 
     825                 : /* -------------------------------------------------------------------- */
     826                 : /*      Setup GML and GeoTIFF information.                              */
     827                 : /* -------------------------------------------------------------------- */
     828              17 :     GDALJP2Metadata oJP2MD;
     829                 : 
     830              17 :     oJP2MD.SetProjection( pszWKT );
     831              17 :     oJP2MD.SetGeoTransform( padfGeoTransform );
     832              17 :     oJP2MD.SetGCPs( nGCPCount, pasGCPList );
     833                 : 
     834              17 :     if( CSLFetchBoolean( papszOptions, "GMLJP2", TRUE ) )
     835              17 :         WriteJP2Box( oJP2MD.CreateGMLJP2(nXSize,nYSize) );
     836              17 :     if( CSLFetchBoolean( papszOptions, "GeoJP2", TRUE ) )
     837              17 :         WriteJP2Box( oJP2MD.CreateJP2GeoTIFF() );
     838                 : 
     839                 : /* -------------------------------------------------------------------- */
     840                 : /*      Handle special case of a JPEG2000 data stream in another file.  */
     841                 : /* -------------------------------------------------------------------- */
     842              17 :     FILE *fpVSIL = NULL;
     843                 : 
     844              17 :     if( EQUALN(pszFilename,"J2K_SUBFILE:",12) )
     845                 :     {
     846               3 :         int  subfile_offset=-1, subfile_size=-1;
     847               3 :         const char *real_filename = NULL;
     848                 : 
     849               3 :         if( sscanf( pszFilename, "J2K_SUBFILE:%d,%d", 
     850                 :                     &subfile_offset, &subfile_size ) != 2 )
     851                 :         {
     852                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     853               0 :                       "Failed to parse J2K_SUBFILE specification." );
     854               0 :             return CE_Failure;
     855                 :         }
     856                 : 
     857               3 :         real_filename = strstr(pszFilename,",");
     858               3 :         if( real_filename != NULL )
     859               3 :             real_filename = strstr(real_filename+1,",");
     860               3 :         if( real_filename != NULL )
     861               3 :             real_filename++;
     862                 :         else
     863                 :         {
     864                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     865               0 :                       "Failed to parse J2K_SUBFILE specification." );
     866               0 :             return CE_Failure;
     867                 :         }
     868                 : 
     869               6 :         fpVSIL = VSIFOpenL( real_filename, "rb+" );
     870               3 :         if( fpVSIL == NULL )
     871                 :         {
     872                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     873               0 :                       "Failed to open %s.",  real_filename );
     874               0 :             return CE_Failure;
     875                 :         }
     876                 : 
     877                 :         m_OStream.Access( fpVSIL, TRUE, real_filename,
     878               3 :                           subfile_offset, subfile_size );
     879                 :     }
     880                 : 
     881                 : 
     882                 : /* -------------------------------------------------------------------- */
     883                 : /*      Check if we can enable large files.  This option should only    */
     884                 : /*      be set when the application is adhering to one of the           */
     885                 : /*      ERMapper options for licensing larger than 500MB input          */
     886                 : /*      files.  See Bug 767.                                            */
     887                 : /* -------------------------------------------------------------------- */
     888              17 :     const char *pszLargeOK = CSLFetchNameValue(papszOptions, "LARGE_OK");
     889              17 :     if( pszLargeOK == NULL )
     890              17 :         pszLargeOK = "NO";
     891                 : 
     892              17 :     pszLargeOK = CPLGetConfigOption( "ECW_LARGE_OK", pszLargeOK );
     893                 : 
     894              17 :     if( CSLTestBoolean(pszLargeOK) )
     895                 :     {
     896               0 :         CNCSFile::SetKeySize();
     897               0 :         CPLDebug( "ECW", "Large file generation enabled." );
     898                 :     }
     899                 : 
     900                 : /* -------------------------------------------------------------------- */
     901                 : /*      Set the file info.                                              */
     902                 : /* -------------------------------------------------------------------- */
     903              17 :     CNCSError oError;
     904                 : 
     905              17 :     oError = SetFileInfo( sFileInfo );
     906                 : 
     907              17 :     if( oError.GetErrorNumber() == NCS_SUCCESS )
     908                 :     {
     909              17 :         if( fpVSIL == NULL )
     910              14 :             oError = Open( (char *) pszFilename, false, true );
     911                 :         else
     912               3 :             oError = CNCSJP2FileView::Open( &(m_OStream) );
     913                 :     }
     914                 : 
     915              17 :     if( oError.GetErrorNumber() == NCS_SUCCESS )
     916              17 :         return CE_None;
     917               0 :     else if( oError.GetErrorNumber() == NCS_INPUT_SIZE_EXCEEDED )
     918                 :     {
     919                 :         CPLError( CE_Failure, CPLE_AppDefined,
     920               0 :                   "ECW SDK 500MB compress limit exceeded." );
     921               0 :         return CE_Failure;
     922                 :     }
     923                 :     else
     924                 :     {
     925               0 :         char* pszErrorMessage = oError.GetErrorMessage();
     926                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     927               0 :                   "%s", pszErrorMessage );
     928               0 :         NCSFree(pszErrorMessage);
     929                 : 
     930               0 :         return CE_Failure;
     931               0 :     }
     932                 : }
     933                 : 
     934                 : /************************************************************************/
     935                 : /*                           ECWCreateCopy()                            */
     936                 : /************************************************************************/
     937                 : 
     938                 : static GDALDataset *
     939              15 : ECWCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     940                 :                int bStrict, char ** papszOptions, 
     941                 :                GDALProgressFunc pfnProgress, void * pProgressData,
     942                 :                int bIsJPEG2000 )
     943                 : 
     944                 : {
     945              15 :     ECWInitialize();
     946                 : 
     947                 : /* -------------------------------------------------------------------- */
     948                 : /*      Get various values from the source dataset.                     */
     949                 : /* -------------------------------------------------------------------- */
     950              15 :     int  nBands = poSrcDS->GetRasterCount();
     951              15 :     int  nXSize = poSrcDS->GetRasterXSize();
     952              15 :     int  nYSize = poSrcDS->GetRasterYSize();
     953                 : 
     954              15 :     if (nBands == 0)
     955                 :     {
     956                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     957               0 :                   "ECW driver does not support source dataset with zero band.\n");
     958               0 :         return NULL;
     959                 :     }
     960                 : 
     961              15 :     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     962                 : 
     963              15 :     const char *pszWKT = poSrcDS->GetProjectionRef();
     964              15 :     double adfGeoTransform[6] = { 0, 1, 0, 0, 0, 1 };;
     965                 : 
     966              15 :     poSrcDS->GetGeoTransform( adfGeoTransform );
     967                 : 
     968              15 :     if( poSrcDS->GetGCPCount() > 0 )
     969               1 :         pszWKT = poSrcDS->GetGCPProjection();
     970                 : 
     971                 : /* -------------------------------------------------------------------- */
     972                 : /*      Confirm the datatype is 8bit.  It appears no other datatype     */
     973                 : /*      is supported in ECW format.                                     */
     974                 : /* -------------------------------------------------------------------- */
     975              15 :     if( eType != GDT_Byte )
     976                 :     {
     977               5 :         if( bStrict )
     978                 :         {
     979                 :             CPLError( CE_Failure, CPLE_AppDefined,
     980                 :                       "Attempt to create ECW file with pixel data type %s failed.\n"
     981                 :                       "Only Byte data type supported.",
     982               5 :                       GDALGetDataTypeName( eType ) );
     983                 :         }
     984                 :         else
     985                 :         {
     986                 :             CPLError( CE_Warning, CPLE_AppDefined,
     987                 :                       "ECW only supports Byte pixel data type, ignoring request for %s.",
     988               0 :                       GDALGetDataTypeName( eType ) );
     989               0 :             eType = GDT_Byte;
     990                 :         }
     991                 :     }
     992                 : 
     993                 : /* -------------------------------------------------------------------- */
     994                 : /*      Setup the compressor.                                           */
     995                 : /* -------------------------------------------------------------------- */
     996              15 :     GDALECWCompressor         oCompressor;
     997                 : 
     998              15 :     oCompressor.pfnProgress = pfnProgress;
     999              15 :     oCompressor.pProgressData = pProgressData;
    1000              15 :     oCompressor.m_poSrcDS = poSrcDS;
    1001                 : 
    1002              15 :     if( !pfnProgress( 0.0, NULL, pProgressData ) )
    1003               0 :         return NULL;
    1004                 : 
    1005              30 :     if( oCompressor.Initialize( pszFilename, papszOptions, 
    1006                 :                                 nXSize, nYSize, nBands,
    1007                 :                                 eType, pszWKT, adfGeoTransform, 
    1008              15 :                                 poSrcDS->GetGCPCount(), 
    1009              15 :                                 poSrcDS->GetGCPs(),
    1010                 :                                 bIsJPEG2000 )
    1011                 :         != CE_None )
    1012               0 :         return NULL;
    1013                 : 
    1014                 : /* -------------------------------------------------------------------- */
    1015                 : /*      Start the compression.                                          */
    1016                 : /* -------------------------------------------------------------------- */
    1017              15 :     oCompressor.Write();
    1018                 : 
    1019                 : /* -------------------------------------------------------------------- */
    1020                 : /*      Cleanup, and return read-only handle.                           */
    1021                 : /* -------------------------------------------------------------------- */
    1022              15 :     oCompressor.CloseDown();
    1023              15 :     pfnProgress( 1.001, NULL, pProgressData );
    1024                 : 
    1025                 : /* -------------------------------------------------------------------- */
    1026                 : /*      Re-open dataset, and copy any auxilary pam information.         */
    1027                 : /* -------------------------------------------------------------------- */
    1028              15 :     GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly);
    1029                 :     GDALPamDataset *poDS;
    1030                 :     
    1031              15 :     if (bIsJPEG2000)
    1032              14 :         poDS = (GDALPamDataset*) ECWDatasetOpenJPEG2000(&oOpenInfo);
    1033                 :     else
    1034               1 :         poDS = (GDALPamDataset*) GDALOpen(pszFilename, GA_ReadOnly);
    1035                 : 
    1036              15 :     if( poDS )
    1037              15 :         poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    1038                 : 
    1039              15 :     return poDS;
    1040                 : }
    1041                 : 
    1042                 : /************************************************************************/
    1043                 : /*                          ECWCreateCopyECW()                          */
    1044                 : /************************************************************************/
    1045                 : 
    1046                 : GDALDataset *
    1047              17 : ECWCreateCopyECW( const char * pszFilename, GDALDataset *poSrcDS, 
    1048                 :                   int bStrict, char ** papszOptions, 
    1049                 :                   GDALProgressFunc pfnProgress, void * pProgressData )
    1050                 : 
    1051                 : {
    1052              17 :     int nBands = poSrcDS->GetRasterCount();
    1053              17 :     if (nBands == 0)
    1054                 :     {
    1055                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1056               1 :                   "ECW driver does not support source dataset with zero band.\n");
    1057               1 :         return NULL;
    1058                 :     }
    1059                 : 
    1060              16 :     if( !EQUAL(CPLGetExtension(pszFilename),"ecw") )
    1061                 :     {
    1062                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1063                 :                   "ECW driver does not support creating ECW files\n"
    1064              15 :                   "with an extension other than .ecw" );
    1065              15 :         return NULL;
    1066                 :     }
    1067                 : 
    1068               1 :     if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1069                 :         && bStrict )
    1070                 :     {
    1071                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1072                 :                   "ECW driver doesn't support data type %s. "
    1073                 :                   "Only eight bit bands supported.\n", 
    1074                 :                   GDALGetDataTypeName( 
    1075               0 :                       poSrcDS->GetRasterBand(1)->GetRasterDataType()) );
    1076                 : 
    1077               0 :         return NULL;
    1078                 :     }
    1079                 : 
    1080               1 :     if( poSrcDS->GetRasterXSize() < 128 
    1081                 :         || poSrcDS->GetRasterYSize() < 128 )
    1082                 :     {
    1083                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1084                 :                   "ECW driver requires image to be at least 128x128,\n"
    1085                 :                   "the source image is %dx%d.\n", 
    1086                 :                   poSrcDS->GetRasterXSize(),
    1087               0 :                   poSrcDS->GetRasterYSize() );
    1088                 :                   
    1089               0 :         return NULL;
    1090                 :     }
    1091                 :     
    1092               1 :     if (poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)
    1093                 :     {
    1094                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
    1095                 :                   "ECW driver ignores color table. "
    1096                 :                   "The source raster band will be considered as grey level.\n"
    1097               0 :                   "Consider using color table expansion (-expand option in gdal_translate)\n");
    1098               0 :         if (bStrict)
    1099               0 :             return NULL;
    1100                 :     }
    1101                 : 
    1102                 :     return ECWCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions, 
    1103               1 :                           pfnProgress, pProgressData, FALSE );
    1104                 : }
    1105                 : 
    1106                 : /************************************************************************/
    1107                 : /*                       ECWCreateCopyJPEG2000()                        */
    1108                 : /************************************************************************/
    1109                 : 
    1110                 : GDALDataset *
    1111              19 : ECWCreateCopyJPEG2000( const char * pszFilename, GDALDataset *poSrcDS, 
    1112                 :                        int bStrict, char ** papszOptions, 
    1113                 :                        GDALProgressFunc pfnProgress, void * pProgressData )
    1114                 : 
    1115                 : {
    1116              19 :     int nBands = poSrcDS->GetRasterCount();
    1117              19 :     if (nBands == 0)
    1118                 :     {
    1119                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1120               1 :                   "JP2ECW driver does not support source dataset with zero band.\n");
    1121               1 :         return NULL;
    1122                 :     }
    1123                 : 
    1124              18 :     if( EQUAL(CPLGetExtension(pszFilename),"ecw") )
    1125                 :     {
    1126                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1127                 :                   "JP2ECW driver does not support creating JPEG2000 files\n"
    1128               0 :                   "with a .ecw extension.  Please use anything else." );
    1129               0 :         return NULL;
    1130                 :     }
    1131                 : 
    1132              18 :     if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1133                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1134                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int16
    1135                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16
    1136                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int32
    1137                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt32
    1138                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Float32
    1139                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Float64
    1140                 :         && bStrict )
    1141                 :     {
    1142                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1143                 :                   "JP2ECW driver doesn't support data type %s. ",
    1144                 :                   GDALGetDataTypeName( 
    1145               4 :                       poSrcDS->GetRasterBand(1)->GetRasterDataType()) );
    1146                 : 
    1147               4 :         return NULL;
    1148                 :     }
    1149                 : 
    1150              14 :     if (poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)
    1151                 :     {
    1152                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
    1153                 :                   "JP2ECW driver ignores color table. "
    1154                 :                   "The source raster band will be considered as grey level.\n"
    1155               0 :                   "Consider using color table expansion (-expand option in gdal_translate)\n");
    1156               0 :         if (bStrict)
    1157               0 :             return NULL;
    1158                 :     }
    1159                 : 
    1160                 :     return ECWCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions, 
    1161              14 :                           pfnProgress, pProgressData, TRUE );
    1162                 : }
    1163                 : 
    1164                 : /************************************************************************/
    1165                 : /************************************************************************
    1166                 :  
    1167                 :                ECW/JPEG200 Create() Support
    1168                 :                ----------------------------
    1169                 : 
    1170                 :   The remainder of the file is code to implement the Create() method. 
    1171                 :   New dataset and raster band classes are defined specifically for the
    1172                 :   purpose of being write-only.  In particular, you cannot read back data
    1173                 :   from these datasets, and writing must occur in a pretty specific order.
    1174                 :   
    1175                 :   That is, you need to write all metadata (projection, georef, etc) first
    1176                 :   and then write the image data.  All bands data for the first scanline
    1177                 :   should be written followed by all bands for the second scanline and so on.
    1178                 : 
    1179                 :   Creation supports the same virtual subfile names as CreateCopy() supports. 
    1180                 : 
    1181                 :  ************************************************************************/
    1182                 : /************************************************************************/
    1183                 : 
    1184                 : /************************************************************************/
    1185                 : /* ==================================================================== */
    1186                 : /*        ECWWriteDataset       */
    1187                 : /* ==================================================================== */
    1188                 : /************************************************************************/
    1189                 : 
    1190                 : class ECWWriteRasterBand;
    1191                 : 
    1192                 : class CPL_DLL ECWWriteDataset : public GDALDataset
    1193                 : {
    1194                 :     friend class ECWWriteRasterBand;
    1195                 : 
    1196                 :     char      *pszFilename;
    1197                 : 
    1198                 :     int       bIsJPEG2000;
    1199                 :     GDALDataType eDataType;
    1200                 :     char    **papszOptions;
    1201                 :   
    1202                 :     char     *pszProjection;
    1203                 :     double    adfGeoTransform[6];
    1204                 : 
    1205                 :     GDALECWCompressor oCompressor;
    1206                 :     int       bCrystalized;
    1207                 :     
    1208                 :     int       nLoadedLine;
    1209                 :     GByte     *pabyBILBuffer;
    1210                 :     
    1211                 :     CPLErr    Crystalize();
    1212                 :     CPLErr    FlushLine();
    1213                 : 
    1214                 :   public:
    1215                 :         ECWWriteDataset( const char *, int, int, int, 
    1216                 :                                  GDALDataType, char **papszOptions,
    1217                 :                                  int );
    1218                 :         ~ECWWriteDataset();
    1219                 : 
    1220                 :     virtual void   FlushCache( void );
    1221                 :                 
    1222                 :     virtual CPLErr SetGeoTransform( double * );
    1223                 :     virtual CPLErr SetProjection( const char *pszWKT );
    1224                 : };
    1225                 : 
    1226                 : /************************************************************************/
    1227                 : /* ==================================================================== */
    1228                 : /*                         ECWWriteRasterBand                           */
    1229                 : /* ==================================================================== */
    1230                 : /************************************************************************/
    1231                 :  
    1232                 : class ECWWriteRasterBand : public GDALRasterBand
    1233              58 : {
    1234                 :     friend class ECWWriteDataset;
    1235                 :     
    1236                 :     // NOTE: poDS may be altered for NITF/JPEG2000 files!
    1237                 :     ECWWriteDataset     *poGDS;
    1238                 : 
    1239                 :     GDALColorInterp     eInterp;
    1240                 : 
    1241                 :   public:
    1242                 : 
    1243                 :                    ECWWriteRasterBand( ECWWriteDataset *, int );
    1244                 : 
    1245               0 :     virtual CPLErr SetColorInterpretation( GDALColorInterp eInterpIn ) 
    1246               0 :         { eInterp = eInterpIn; return CE_None; }
    1247               3 :     virtual GDALColorInterp GetColorInterpretation() 
    1248               3 :         { return eInterp; }
    1249                 : 
    1250                 :     virtual CPLErr IReadBlock( int, int, void * );
    1251                 :     virtual CPLErr IWriteBlock( int, int, void * );
    1252                 : };
    1253                 : 
    1254                 : /************************************************************************/
    1255                 : /*                          ECWWriteDataset()                           */
    1256                 : /************************************************************************/
    1257                 : 
    1258              18 : ECWWriteDataset::ECWWriteDataset( const char *pszFilename, 
    1259                 :                                   int nXSize, int nYSize, int nBandCount, 
    1260                 :                                   GDALDataType eType,
    1261              18 :                                   char **papszOptions, int bIsJPEG2000 )
    1262                 : 
    1263                 : {
    1264              18 :     bCrystalized = FALSE;
    1265              18 :     pabyBILBuffer = NULL;
    1266              18 :     nLoadedLine = -1;
    1267                 : 
    1268              18 :     this->bIsJPEG2000 = bIsJPEG2000;
    1269              18 :     this->eDataType = eType;
    1270              18 :     this->papszOptions = CSLDuplicate( papszOptions );
    1271              18 :     this->pszFilename = CPLStrdup( pszFilename );
    1272                 : 
    1273              18 :     nRasterXSize = nXSize;
    1274              18 :     nRasterYSize = nYSize;
    1275              18 :     pszProjection = NULL;
    1276                 : 
    1277              18 :     adfGeoTransform[0] = 0.0;
    1278              18 :     adfGeoTransform[1] = 1.0;
    1279              18 :     adfGeoTransform[2] = 0.0;
    1280              18 :     adfGeoTransform[3] = 0.0;
    1281              18 :     adfGeoTransform[4] = 0.0;
    1282              18 :     adfGeoTransform[5] = 1.0;
    1283                 : 
    1284                 :     // create band objects.
    1285              47 :     for( int iBand = 1; iBand <= nBandCount; iBand++ )
    1286                 :     {
    1287              29 :         SetBand( iBand, new ECWWriteRasterBand( this, iBand ) );
    1288                 :     }
    1289              18 : }
    1290                 : 
    1291                 : /************************************************************************/
    1292                 : /*                          ~ECWWriteDataset()                          */
    1293                 : /************************************************************************/
    1294                 : 
    1295              36 : ECWWriteDataset::~ECWWriteDataset()
    1296                 : 
    1297                 : {
    1298              18 :     FlushCache();
    1299                 : 
    1300              18 :     if( bCrystalized )
    1301                 :     {
    1302               2 :         if( nLoadedLine == nRasterYSize - 1 )
    1303               2 :             FlushLine();
    1304               2 :         oCompressor.CloseDown();
    1305                 :     }
    1306                 : 
    1307              18 :     CPLFree( pabyBILBuffer );
    1308              18 :     CPLFree( pszProjection );
    1309              18 :     CSLDestroy( papszOptions );
    1310              18 :     CPLFree( pszFilename );
    1311              36 : }
    1312                 : 
    1313                 : /************************************************************************/
    1314                 : /*                             FlushCache()                             */
    1315                 : /************************************************************************/
    1316                 : 
    1317              19 : void ECWWriteDataset::FlushCache()
    1318                 : 
    1319                 : {
    1320              19 :     BlockBasedFlushCache();
    1321              19 : }
    1322                 : 
    1323                 : /************************************************************************/
    1324                 : /*                          SetGeoTransform()                           */
    1325                 : /************************************************************************/
    1326                 : 
    1327               1 : CPLErr ECWWriteDataset::SetGeoTransform( double *padfGeoTransform )
    1328                 : 
    1329                 : {
    1330               1 :     memcpy( adfGeoTransform, padfGeoTransform, sizeof(double) * 6 );
    1331               1 :     return CE_None;
    1332                 : }
    1333                 : 
    1334                 : /************************************************************************/
    1335                 : /*                           SetProjection()                            */
    1336                 : /************************************************************************/
    1337                 : 
    1338               1 : CPLErr ECWWriteDataset::SetProjection( const char *pszWKT )
    1339                 : 
    1340                 : {
    1341               1 :     CPLFree( pszProjection );
    1342               1 :     pszProjection = CPLStrdup( pszWKT );
    1343                 : 
    1344               1 :     return CE_None;
    1345                 : }
    1346                 : 
    1347                 : 
    1348                 : /************************************************************************/
    1349                 : /*                             Crystalize()                             */
    1350                 : /************************************************************************/
    1351                 : 
    1352               2 : CPLErr ECWWriteDataset::Crystalize()
    1353                 : 
    1354                 : {
    1355               2 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1356                 : 
    1357                 :     CPLErr eErr;
    1358               2 :     CNCSError oError;
    1359                 : 
    1360               2 :     if( bCrystalized )
    1361               0 :         return CE_None;
    1362                 : 
    1363                 :     eErr = oCompressor.Initialize( pszFilename, papszOptions, 
    1364                 :                                    nRasterXSize, nRasterYSize, nBands, 
    1365                 :                                    eDataType, 
    1366                 :                                    pszProjection, adfGeoTransform, 
    1367                 :                                    0, NULL,
    1368               2 :                                    bIsJPEG2000 );
    1369                 : 
    1370               2 :     if( eErr == CE_None )
    1371               2 :         bCrystalized = TRUE;
    1372                 : 
    1373               2 :     nLoadedLine = -1;
    1374               2 :     pabyBILBuffer = (GByte *) CPLMalloc( nWordSize * nBands * nRasterXSize );
    1375                 : 
    1376               2 :     return eErr;
    1377                 : }
    1378                 : 
    1379                 : /************************************************************************/
    1380                 : /*                             FlushLine()                              */
    1381                 : /************************************************************************/
    1382                 : 
    1383             202 : CPLErr ECWWriteDataset::FlushLine()
    1384                 : 
    1385                 : {
    1386             202 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1387                 :     CPLErr eErr;
    1388                 : 
    1389                 : /* -------------------------------------------------------------------- */
    1390                 : /*      Crystalize if not already done.                                 */
    1391                 : /* -------------------------------------------------------------------- */
    1392             202 :     if( !bCrystalized )
    1393                 :     {
    1394               2 :         eErr = Crystalize();
    1395                 : 
    1396               2 :         if( eErr != CE_None )
    1397               0 :             return eErr;
    1398                 :     }
    1399                 : 
    1400                 : /* -------------------------------------------------------------------- */
    1401                 : /*      Write out the currently loaded line.                            */
    1402                 : /* -------------------------------------------------------------------- */
    1403             202 :     if( nLoadedLine != -1 )
    1404                 :     {
    1405             200 :         CNCSError oError;
    1406                 :         void **papOutputLine;
    1407                 : 
    1408             200 :         papOutputLine = (void **) CPLMalloc(sizeof(void*) * nBands);
    1409             600 :         for( int i = 0; i < nBands; i++ )
    1410             400 :             papOutputLine[i] = 
    1411             400 :                 (void *) (pabyBILBuffer + i * nWordSize * nRasterXSize);
    1412                 :         
    1413                 : 
    1414                 :         oError = oCompressor.WriteLineBIL( oCompressor.sFileInfo.eCellType, 
    1415             200 :                                            (UINT16) nBands, papOutputLine );
    1416             200 :         CPLFree( papOutputLine );
    1417             200 :         if( oError.GetErrorNumber() != NCS_SUCCESS )
    1418                 :         {
    1419               0 :             char* pszErrorMessage = oError.GetErrorMessage();
    1420                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1421                 :                       "Scanline write write failed.\n%s",
    1422               0 :                       pszErrorMessage );
    1423               0 :             NCSFree(pszErrorMessage);
    1424                 : 
    1425               0 :             return CE_Failure;
    1426               0 :         }
    1427                 :     }
    1428                 : 
    1429                 : /* -------------------------------------------------------------------- */
    1430                 : /*      Clear the buffer and increment the "current line" indicator.    */
    1431                 : /* -------------------------------------------------------------------- */
    1432             202 :     memset( pabyBILBuffer, 0, nWordSize * nRasterXSize * nBands );
    1433             202 :     nLoadedLine++;
    1434                 : 
    1435             202 :     return CE_None;
    1436                 : }
    1437                 : 
    1438                 : 
    1439                 : /************************************************************************/
    1440                 : /* ==================================================================== */
    1441                 : /*                          ECWWriteRasterBand                          */
    1442                 : /* ==================================================================== */
    1443                 : /************************************************************************/
    1444                 : 
    1445                 : /************************************************************************/
    1446                 : /*                         ECWWriteRasterBand()                         */
    1447                 : /************************************************************************/
    1448                 : 
    1449              29 : ECWWriteRasterBand::ECWWriteRasterBand( ECWWriteDataset *poDSIn,
    1450              29 :                                         int nBandIn )
    1451                 : 
    1452                 : {
    1453              29 :     nBand = nBandIn;
    1454              29 :     poDS = poDSIn;
    1455              29 :     poGDS = poDSIn;
    1456              29 :     nBlockXSize = poDSIn->GetRasterXSize();
    1457              29 :     nBlockYSize = 1;
    1458              29 :     eDataType = poDSIn->eDataType;
    1459              29 :     eInterp = GCI_Undefined;
    1460              29 : }
    1461                 : 
    1462                 : /************************************************************************/
    1463                 : /*                             IReadBlock()                             */
    1464                 : /************************************************************************/
    1465                 : 
    1466               0 : CPLErr ECWWriteRasterBand::IReadBlock( int nBlockX, int nBlockY, 
    1467                 :                                        void *pBuffer )
    1468                 : 
    1469                 : {
    1470               0 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1471                 : 
    1472                 :     // We zero stuff out here, but we can't really read stuff from
    1473                 :     // a write only stream. 
    1474                 : 
    1475               0 :     memset( pBuffer, 0, nBlockXSize * nWordSize );
    1476                 : 
    1477               0 :     return CE_None;
    1478                 : }
    1479                 : 
    1480                 : /************************************************************************/
    1481                 : /*                            IWriteBlock()                             */
    1482                 : /************************************************************************/
    1483                 : 
    1484             400 : CPLErr ECWWriteRasterBand::IWriteBlock( int nBlockX, int nBlockY, 
    1485                 :                                         void *pBuffer )
    1486                 : 
    1487                 : {
    1488             400 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1489                 :     CPLErr eErr;
    1490                 : 
    1491                 : /* -------------------------------------------------------------------- */
    1492                 : /*      Flush previous line if needed.                                  */
    1493                 : /* -------------------------------------------------------------------- */
    1494             400 :     if( nBlockY == poGDS->nLoadedLine + 1 )
    1495                 :     {
    1496             200 :         eErr = poGDS->FlushLine();
    1497             200 :         if( eErr != CE_None )
    1498               0 :             return eErr;
    1499                 :     }
    1500                 : 
    1501                 : /* -------------------------------------------------------------------- */
    1502                 : /*      Blow a gasket if we have been asked to write something out      */
    1503                 : /*      of order.                                                       */
    1504                 : /* -------------------------------------------------------------------- */
    1505             400 :     if( nBlockY != poGDS->nLoadedLine )
    1506                 :     {
    1507                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1508                 :                   "Apparent attempt to write to ECW non-sequentially.\n"
    1509                 :                   "Loaded line is %d, but %d of band %d was written to.",
    1510               0 :                   poGDS->nLoadedLine, nBlockY, nBand );
    1511               0 :         return CE_Failure;
    1512                 :     }
    1513                 : 
    1514                 : /* -------------------------------------------------------------------- */
    1515                 : /*      Copy passed data into current line buffer.                      */
    1516                 : /* -------------------------------------------------------------------- */
    1517                 :     memcpy( poGDS->pabyBILBuffer + (nBand-1) * nWordSize * nRasterXSize, 
    1518                 :             pBuffer, 
    1519             400 :             nWordSize * nRasterXSize );
    1520                 : 
    1521             400 :     return CE_None;
    1522                 : }
    1523                 : 
    1524                 : /************************************************************************/
    1525                 : /*                         ECWCreateJPEG2000()                          */
    1526                 : /************************************************************************/
    1527                 : 
    1528                 : GDALDataset *
    1529              18 : ECWCreateJPEG2000(const char *pszFilename, int nXSize, int nYSize, int nBands, 
    1530                 :                   GDALDataType eType, char **papszOptions )
    1531                 : 
    1532                 : {
    1533              18 :     ECWInitialize();
    1534                 : 
    1535                 :     return new ECWWriteDataset( pszFilename, nXSize, nYSize, nBands, 
    1536              18 :                                 eType, papszOptions, TRUE );
    1537                 : }
    1538                 : 
    1539                 : /************************************************************************/
    1540                 : /*                            ECWCreateECW()                            */
    1541                 : /************************************************************************/
    1542                 : 
    1543                 : GDALDataset *
    1544               0 : ECWCreateECW( const char *pszFilename, int nXSize, int nYSize, int nBands, 
    1545                 :               GDALDataType eType, char **papszOptions )
    1546                 : 
    1547                 : {
    1548               0 :     ECWInitialize();
    1549                 : 
    1550                 :     return new ECWWriteDataset( pszFilename, nXSize, nYSize, nBands, 
    1551               0 :                                 eType, papszOptions, FALSE );
    1552            1140 : }
    1553                 : 
    1554                 : #endif /* def FRMT_ecw && def HAVE_COMPRESS */

Generated by: LCOV version 1.7