LCOV - code coverage report
Current view: directory - frmts/ecw - ecwcreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 458 359 78.4 %
Date: 2011-12-18 Functions: 40 26 65.0 %

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

Generated by: LCOV version 1.7