LCOV - code coverage report
Current view: directory - frmts/ecw - ecwcreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 458 360 78.6 %
Date: 2012-04-28 Functions: 40 26 65.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ecwcreatecopy.cpp 23601 2011-12-19 20:04: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 23601 2011-12-19 20:04: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             100 : GDALECWCompressor::GDALECWCompressor()
      86                 : 
      87                 : {
      88             100 :     m_poSrcDS = NULL;
      89             100 :     m_nPercentComplete = -1;
      90             100 :     m_bCancelled = FALSE;
      91             100 :     pfnProgress = GDALDummyProgress;
      92             100 :     pProgressData = NULL;
      93             100 :     papoJP2UserBox = NULL;
      94             100 :     nJP2UserBox = 0;
      95             100 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                         ~GDALECWCompressor()                         */
      99                 : /************************************************************************/
     100                 : 
     101             100 : GDALECWCompressor::~GDALECWCompressor()
     102                 : 
     103                 : {
     104                 :     int i;
     105             180 :     for(i=0;i<nJP2UserBox;i++)
     106              80 :         delete papoJP2UserBox[i];
     107             100 :     CPLFree(papoJP2UserBox);
     108             100 : }
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                             CloseDown()                              */
     112                 : /************************************************************************/
     113                 : 
     114              40 : CPLErr GDALECWCompressor::CloseDown()
     115                 : 
     116                 : {
     117             120 :     for( int i = 0; i < sFileInfo.nBands; i++ )
     118                 :     {
     119              80 :         CPLFree( sFileInfo.pBands[i].szDesc );
     120                 :     }
     121              40 :     CPLFree( sFileInfo.pBands );
     122                 : 
     123              40 :     Close( true );
     124              40 :     m_OStream.Close();
     125                 : 
     126              40 :     return CE_None;
     127                 : }
     128                 : 
     129                 : /************************************************************************/
     130                 : /*                           WriteReadLine()                            */
     131                 : /************************************************************************/
     132                 : 
     133            3428 : CNCSError GDALECWCompressor::WriteReadLine( UINT32 nNextLine, 
     134                 :                                             void **ppInputArray )
     135                 : 
     136                 : {
     137                 :     int    iBand, *panBandMap;
     138                 :     CPLErr eErr;
     139                 :     GByte *pabyLineBuf;
     140            3428 :     int nWordSize = GDALGetDataTypeSize( eWorkDT ) / 8;
     141                 : 
     142            3428 :     panBandMap = (int *) CPLMalloc(sizeof(int) * sFileInfo.nBands);
     143            9196 :     for( iBand = 0; iBand < sFileInfo.nBands; iBand++ )
     144            5768 :         panBandMap[iBand] = iBand+1;
     145                 : 
     146                 :     pabyLineBuf = (GByte *) CPLMalloc( sFileInfo.nSizeX * sFileInfo.nBands
     147            3428 :                                        * 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            3428 :                                 nWordSize, 0, nWordSize * sFileInfo.nSizeX );
     154                 : 
     155            9196 :     for( iBand = 0; iBand < (int) sFileInfo.nBands; iBand++ )
     156                 :     {
     157                 :         memcpy( ppInputArray[iBand],
     158                 :                 pabyLineBuf + nWordSize * sFileInfo.nSizeX * iBand, 
     159            5768 :                 nWordSize * sFileInfo.nSizeX );
     160                 :     }
     161                 : 
     162            3428 :     CPLFree( pabyLineBuf );
     163            3428 :     CPLFree( panBandMap );
     164                 : 
     165            3428 :     if( eErr == CE_None )
     166            3428 :         return NCS_SUCCESS;
     167                 :     else
     168               0 :         return NCS_FILEIO_ERROR;
     169                 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /*                            WriteStatus()                             */
     173                 : /************************************************************************/
     174                 : 
     175            3428 : void GDALECWCompressor::WriteStatus( UINT32 nCurrentLine )
     176                 : 
     177                 : {
     178                 :     m_bCancelled = 
     179                 :         !pfnProgress( nCurrentLine / (float) sFileInfo.nSizeY, 
     180            3428 :                       NULL, pProgressData );
     181            3428 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                            WriteCancel()                             */
     185                 : /************************************************************************/
     186                 : 
     187            3428 : bool GDALECWCompressor::WriteCancel()
     188                 : 
     189                 : {
     190            3428 :     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              84 : CPLErr GDALECWCompressor::WriteJP2Box( GDALJP2Box * poBox )
     391                 : 
     392                 : {
     393                 :     JP2UserBox  *poECWBox;
     394                 : 
     395              84 :     if( poBox == NULL )
     396               4 :         return CE_None;
     397                 : 
     398              80 :     poECWBox = new JP2UserBox();
     399              80 :     memcpy( &(poECWBox->m_nTBox), poBox->GetType(), 4 );
     400              80 :     CPL_MSBPTR32( &(poECWBox->m_nTBox) );
     401                 : 
     402                 :     poECWBox->SetData( (int) poBox->GetDataLength(), 
     403              80 :                        poBox->GetWritableData() );
     404                 : 
     405              80 :     AddBox( poECWBox );
     406                 : 
     407             160 :     delete poBox;
     408                 : 
     409                 :     papoJP2UserBox =(JP2UserBox**) CPLRealloc(papoJP2UserBox,
     410              80 :                                     (nJP2UserBox + 1) * sizeof(JP2UserBox*));
     411              80 :     papoJP2UserBox[nJP2UserBox] = poECWBox;
     412              80 :     nJP2UserBox ++;
     413                 : 
     414              80 :     return CE_None;
     415                 : }
     416                 : 
     417                 : 
     418                 : /************************************************************************/
     419                 : /*                             Initialize()                             */
     420                 : /*                                                                      */
     421                 : /*      Initialize compressor output.                                   */
     422                 : /************************************************************************/
     423                 : 
     424              48 : 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              48 :     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              48 :     if( nBands > 1 ) 
     478              20 :         fTargetCompression = 95.0;
     479                 :     else
     480              28 :         fTargetCompression = 90.0;
     481                 : 
     482              48 :     if( CSLFetchNameValue(papszOptions, "TARGET") != NULL )
     483                 :     {
     484                 :         fTargetCompression = (float) 
     485              12 :             atof(CSLFetchNameValue(papszOptions, "TARGET"));
     486                 : 
     487                 :         /* The max allowed value should be 100 - 100 / 65535 = 99.9984740978 */
     488                 :         /* so that nCompressionRate fits on a uint16 (see below) */
     489                 :         /* No need to be so pedantic, so we will limit to 99.99 % */
     490                 :         /* (compression rate = 10 000) */
     491              12 :         if( fTargetCompression < 0.0 || fTargetCompression > 99.99 )
     492                 :         {
     493                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     494                 :                       "TARGET compression of %.3f invalid, should be a\n"
     495                 :                       "value between 0 and 99.99 percent.\n",
     496               0 :                       (double) fTargetCompression );
     497               0 :             return CE_Failure;
     498                 :         }
     499                 :     }
     500                 :         
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Create and initialize compressor.                               */
     503                 : /* -------------------------------------------------------------------- */
     504              48 :     NCSFileViewFileInfoEx    *psClient = &(sFileInfo);
     505                 :     
     506              48 :     psClient->nBands = (UINT16) nBands;
     507              48 :     psClient->nSizeX = nXSize;
     508              48 :     psClient->nSizeY = nYSize;
     509              48 :     psClient->nCompressionRate = (UINT16) MAX(1,100/(100-fTargetCompression));
     510              48 :     psClient->eCellSizeUnits = ECW_CELL_UNITS_METERS;
     511                 : 
     512              48 :     if( nBands == 1 )
     513              28 :         psClient->eColorSpace = NCSCS_GREYSCALE;
     514              20 :     else if( nBands == 3 )
     515              10 :         psClient->eColorSpace = NCSCS_sRGB;
     516                 : #if ECWSDK_VERSION >= 40
     517                 :     else if( nBands == 4 && bRGBA )
     518                 :         psClient->eColorSpace = NCSCS_sRGB;
     519                 : #endif
     520                 :     else
     521              10 :         psClient->eColorSpace = NCSCS_MULTIBAND;
     522                 : 
     523                 : /* -------------------------------------------------------------------- */
     524                 : /*      Figure out the data type.                                       */
     525                 : /* -------------------------------------------------------------------- */
     526              48 :     int bSigned = FALSE;
     527              48 :     int nBits = 8;
     528              48 :     eWorkDT = eType;
     529                 : 
     530              48 :     switch( eWorkDT  )
     531                 :     {
     532                 :         case GDT_Byte:
     533              36 :             psClient->eCellType = NCSCT_UINT8;
     534              36 :             nBits = 8;
     535              36 :             bSigned = FALSE;
     536              36 :             break;
     537                 :             
     538                 :         case GDT_UInt16:
     539               2 :             psClient->eCellType = NCSCT_UINT16;
     540               2 :             nBits = 16;
     541               2 :             bSigned = FALSE;
     542               2 :             break;
     543                 :             
     544                 :         case GDT_UInt32:
     545               2 :             psClient->eCellType = NCSCT_UINT32;
     546               2 :             nBits = 32;
     547               2 :             bSigned = FALSE;
     548               2 :             break;
     549                 :             
     550                 :         case GDT_Int16:
     551               4 :             psClient->eCellType = NCSCT_INT16;
     552               4 :             nBits = 16;
     553               4 :             bSigned = TRUE;
     554               4 :             break;
     555                 :             
     556                 :         case GDT_Int32:
     557               2 :             psClient->eCellType = NCSCT_INT32;
     558               2 :             nBits = 32;
     559               2 :             bSigned = TRUE;
     560               2 :             break;
     561                 :             
     562                 :         case GDT_Float32:
     563               2 :             psClient->eCellType = NCSCT_IEEE4;
     564               2 :             nBits = 32;
     565               2 :             bSigned = TRUE;
     566               2 :             break;
     567                 :             
     568                 :         case GDT_Float64:
     569               0 :             psClient->eCellType = NCSCT_IEEE8;
     570               0 :             nBits = 64;
     571               0 :             bSigned = TRUE;
     572               0 :             break;
     573                 : 
     574                 :         default:
     575                 :             // We treat complex types as float.  
     576               0 :             psClient->eCellType = NCSCT_IEEE4;
     577               0 :             nBits = 32;
     578               0 :             bSigned = TRUE;
     579               0 :             eWorkDT = GDT_Float32;
     580                 :             break;
     581                 :     }
     582                 : 
     583                 : /* -------------------------------------------------------------------- */
     584                 : /*      Create band information structures.                             */
     585                 : /* -------------------------------------------------------------------- */
     586                 :     int iBand;
     587                 : 
     588                 :     psClient->pBands = (NCSFileBandInfo *) 
     589              48 :         CPLMalloc( sizeof(NCSFileBandInfo) * nBands );
     590             136 :     for( iBand = 0; iBand < nBands; iBand++ )
     591                 :     {
     592              88 :         psClient->pBands[iBand].nBits = (UINT8) nBits;
     593              88 :         psClient->pBands[iBand].bSigned = (BOOLEAN)bSigned;
     594              88 :         psClient->pBands[iBand].szDesc = CPLStrdup(
     595              88 :             CPLSPrintf("Band%d",iBand+1) );
     596                 :     }
     597                 : 
     598                 : /* -------------------------------------------------------------------- */
     599                 : /*      Allow CNCSFile::SetParameter() requests.                        */
     600                 : /* -------------------------------------------------------------------- */
     601                 :     const char *pszOption;
     602                 : 
     603              48 :     if( bIsJPEG2000 )
     604                 :     {
     605              42 :         pszOption = CSLFetchNameValue(papszOptions, "PROFILE");
     606              42 :         if( pszOption != NULL && EQUAL(pszOption,"BASELINE_0") ) 
     607                 :             SetParameter( 
     608               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_0 );
     609              42 :         else if( pszOption != NULL && EQUAL(pszOption,"BASELINE_1") ) 
     610                 :             SetParameter( 
     611               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_1 );
     612              42 :         else if( pszOption != NULL && EQUAL(pszOption,"BASELINE_2") )
     613                 :             SetParameter( 
     614               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_2 );
     615              54 :         else if( pszOption != NULL && EQUAL(pszOption,"NPJE") ) 
     616                 :             SetParameter( 
     617              12 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_NITF_BIIF_NPJE );
     618              30 :         else if( pszOption != NULL && EQUAL(pszOption,"EPJE") ) 
     619                 :             SetParameter( 
     620               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROFILE_NITF_BIIF_EPJE );
     621                 :         
     622              42 :         pszOption = CSLFetchNameValue(papszOptions, "CODESTREAM_ONLY" );
     623              42 :         if( pszOption != NULL ) 
     624                 :             SetParameter(
     625                 :                 CNCSJP2FileView::JP2_COMPRESS_CODESTREAM_ONLY, 
     626               6 :                 (bool) CSLTestBoolean( pszOption ) );
     627                 :         
     628              42 :         pszOption = CSLFetchNameValue(papszOptions, "LEVELS");
     629              42 :         if( pszOption != NULL )
     630                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_LEVELS, 
     631               0 :                                       (UINT32) atoi(pszOption) );
     632                 :         
     633              42 :         pszOption = CSLFetchNameValue(papszOptions, "LAYERS");
     634              42 :         if( pszOption != NULL )
     635                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_LAYERS, 
     636               6 :                                       (UINT32) atoi(pszOption) );
     637                 : 
     638              42 :         pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_WIDTH");
     639              42 :         if( pszOption != NULL )
     640                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_PRECINCT_WIDTH,
     641               0 :                                       (UINT32) atoi(pszOption) );
     642                 : 
     643              42 :         pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_HEIGHT");
     644              42 :         if( pszOption != NULL )
     645                 :             SetParameter(CNCSJP2FileView::JP2_COMPRESS_PRECINCT_HEIGHT, 
     646               0 :                                      (UINT32) atoi(pszOption) );
     647                 : 
     648              42 :         pszOption = CSLFetchNameValue(papszOptions, "TILE_WIDTH");
     649              42 :         if( pszOption != NULL )
     650                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_TILE_WIDTH, 
     651               0 :                                       (UINT32) atoi(pszOption) );
     652                 : 
     653              42 :         pszOption = CSLFetchNameValue(papszOptions, "TILE_HEIGHT");
     654              42 :         if( pszOption != NULL )
     655                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_TILE_HEIGHT, 
     656               0 :                                       (UINT32) atoi(pszOption) );
     657                 : 
     658              42 :         pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_SOP");
     659              42 :         if( pszOption != NULL )
     660                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_INCLUDE_SOP, 
     661               0 :                                       (bool) CSLTestBoolean( pszOption ) );
     662                 :     
     663              42 :         pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_EPH");
     664              42 :         if( pszOption != NULL )
     665                 :             SetParameter( CNCSJP2FileView::JP2_COMPRESS_INCLUDE_EPH, 
     666               0 :                                       (bool) CSLTestBoolean( pszOption ) );
     667                 :     
     668              42 :         pszOption = CSLFetchNameValue(papszOptions, "PROGRESSION");
     669              42 :         if( pszOption != NULL && EQUAL(pszOption,"LRCP") )
     670                 :             SetParameter( 
     671               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_LRCP );
     672                 :                                   
     673              42 :         else if( pszOption != NULL && EQUAL(pszOption,"RLCP") )
     674                 :             SetParameter( 
     675               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_RLCP );
     676                 : 
     677              42 :         else if( pszOption != NULL && EQUAL(pszOption,"RPCL") )
     678                 :             SetParameter( 
     679               0 :                 CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_RPCL );
     680                 : 
     681              42 :         pszOption = CSLFetchNameValue(papszOptions, "GEODATA_USAGE");
     682              42 :         if( pszOption == NULL )
     683                 :             // Default to supressing ECW SDK geodata, just use our own stuff.
     684              42 :             SetGeodataUsage( JP2_GEODATA_USE_NONE );
     685               0 :         else if( EQUAL(pszOption,"NONE") )
     686               0 :             SetGeodataUsage( JP2_GEODATA_USE_NONE );
     687               0 :         else if( EQUAL(pszOption,"PCS_ONLY") )
     688               0 :             SetGeodataUsage( JP2_GEODATA_USE_PCS_ONLY );
     689               0 :         else if( EQUAL(pszOption,"GML_ONLY") )
     690               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_ONLY );
     691               0 :         else if( EQUAL(pszOption,"PCS_GML") )
     692               0 :             SetGeodataUsage( JP2_GEODATA_USE_PCS_GML );
     693               0 :         else if( EQUAL(pszOption,"GML_PCS") )
     694               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_PCS );
     695               0 :         else if( EQUAL(pszOption,"ALL") )
     696               0 :             SetGeodataUsage( JP2_GEODATA_USE_GML_PCS_WLD );
     697                 : 
     698              42 :         pszOption = CSLFetchNameValue(papszOptions, "DECOMPRESS_LAYERS");
     699              42 :         if( pszOption != NULL )
     700                 :             SetParameter( 
     701                 :                 CNCSJP2FileView::JP2_DECOMPRESS_LAYERS, 
     702               0 :                 (UINT32) atoi(pszOption) );
     703                 : 
     704                 :         pszOption = CSLFetchNameValue(papszOptions, 
     705              42 :                                       "DECOMPRESS_RECONSTRUCTION_PARAMETER");
     706              42 :         if( pszOption != NULL )
     707                 :             SetParameter( 
     708                 :                 CNCSJP2FileView::JPC_DECOMPRESS_RECONSTRUCTION_PARAMETER, 
     709               0 :                 (IEEE4) atof(pszOption) );
     710                 :     }
     711                 :                                   
     712                 : /* -------------------------------------------------------------------- */
     713                 : /*      Georeferencing.                                                 */
     714                 : /* -------------------------------------------------------------------- */
     715                 : 
     716              48 :     psClient->fOriginX = 0.0;
     717              48 :     psClient->fOriginY = psClient->nSizeY;
     718              48 :     psClient->fCellIncrementX = 1.0;
     719              48 :     psClient->fCellIncrementY = -1.0;
     720              48 :     psClient->fCWRotationDegrees = 0.0;
     721                 :     
     722              48 :     if( padfGeoTransform[2] != 0.0 || padfGeoTransform[4] != 0.0 )
     723                 :         CPLError( CE_Warning, CPLE_NotSupported, 
     724                 :                   "Rotational coefficients ignored, georeferencing of\n"
     725               0 :                   "output ECW file will be incorrect.\n" );
     726                 :     else
     727                 :     {
     728              48 :         psClient->fOriginX = padfGeoTransform[0];
     729              48 :         psClient->fOriginY = padfGeoTransform[3];
     730              48 :         psClient->fCellIncrementX = padfGeoTransform[1];
     731              48 :         psClient->fCellIncrementY = padfGeoTransform[5];
     732                 :     }
     733                 : 
     734                 : /* -------------------------------------------------------------------- */
     735                 : /*      Projection.                                                     */
     736                 : /* -------------------------------------------------------------------- */
     737                 :     char szProjection[128];
     738                 :     char szDatum[128];
     739                 :     char szUnits[128];
     740                 : 
     741              48 :     strcpy( szProjection, "RAW" );
     742              48 :     strcpy( szDatum, "RAW" );
     743                 :     
     744              48 :     if( CSLFetchNameValue(papszOptions, "PROJ") != NULL )
     745                 :     {
     746                 :         strncpy( szProjection, 
     747               0 :                 CSLFetchNameValue(papszOptions, "PROJ"), sizeof(szProjection) );
     748               0 :         szProjection[sizeof(szProjection)-1] = 0;
     749                 :     }
     750                 : 
     751              48 :     if( CSLFetchNameValue(papszOptions, "DATUM") != NULL )
     752                 :     {
     753               0 :         strncpy( szDatum, CSLFetchNameValue(papszOptions, "DATUM"), sizeof(szDatum) );
     754               0 :         szDatum[sizeof(szDatum)-1] = 0;
     755               0 :         if( EQUAL(szProjection,"RAW") )
     756               0 :             strcpy( szProjection, "GEODETIC" );
     757                 :     }
     758                 : 
     759              48 :     const char* pszUnits = CSLFetchNameValue(papszOptions, "UNITS");
     760              48 :     if( pszUnits != NULL )
     761                 :     {
     762               0 :         psClient->eCellSizeUnits = ECWTranslateToCellSizeUnits(pszUnits);
     763                 :     }
     764                 : 
     765              48 :     if( EQUAL(szProjection,"RAW") && pszWKT != NULL )
     766                 :     {
     767              46 :         ECWTranslateFromWKT( pszWKT, szProjection, sizeof(szProjection), szDatum, sizeof(szDatum), szUnits );
     768              46 :         psClient->eCellSizeUnits = ECWTranslateToCellSizeUnits(szUnits);
     769                 :     }
     770                 : 
     771              48 :     psClient->szDatum = szDatum;
     772              48 :     psClient->szProjection = szProjection;
     773                 : 
     774                 :     CPLDebug( "ECW", "Writing with PROJ=%s, DATUM=%s, UNITS=%s", 
     775              48 :               szProjection, szDatum, ECWTranslateFromCellSizeUnits(psClient->eCellSizeUnits) );
     776                 : 
     777                 : /* -------------------------------------------------------------------- */
     778                 : /*      Setup GML and GeoTIFF information.                              */
     779                 : /* -------------------------------------------------------------------- */
     780              48 :     GDALJP2Metadata oJP2MD;
     781                 : 
     782              48 :     oJP2MD.SetProjection( pszWKT );
     783              48 :     oJP2MD.SetGeoTransform( padfGeoTransform );
     784              48 :     oJP2MD.SetGCPs( nGCPCount, pasGCPList );
     785                 : 
     786              48 :     if( CSLFetchBoolean( papszOptions, "GMLJP2", TRUE ) )
     787              42 :         WriteJP2Box( oJP2MD.CreateGMLJP2(nXSize,nYSize) );
     788              48 :     if( CSLFetchBoolean( papszOptions, "GeoJP2", TRUE ) )
     789              42 :         WriteJP2Box( oJP2MD.CreateJP2GeoTIFF() );
     790                 : 
     791                 : /* -------------------------------------------------------------------- */
     792                 : /*      We handle all jpeg2000 files via the VSIIOStream, but ECW       */
     793                 : /*      files cannot be done this way for some reason.                  */
     794                 : /* -------------------------------------------------------------------- */
     795              48 :     VSILFILE *fpVSIL = NULL;
     796                 : 
     797              48 :     if( bIsJPEG2000 )
     798                 :     {
     799              42 :         fpVSIL = VSIFOpenL( pszFilename, "wb+" );
     800              42 :         if( fpVSIL == NULL )
     801                 :         {
     802                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     803               4 :                       "Failed to open %s.", pszFilename );
     804               4 :             return CE_Failure;
     805                 :         }
     806                 : 
     807              38 :         m_OStream.Access( fpVSIL, TRUE, pszFilename, 0, -1 );
     808                 :     }    
     809                 : 
     810                 : /* -------------------------------------------------------------------- */
     811                 : /*      Check if we can enable large files.  This option should only    */
     812                 : /*      be set when the application is adhering to one of the           */
     813                 : /*      ERMapper options for licensing larger than 500MB input          */
     814                 : /*      files.  See Bug 767.  This option no longer exists with         */
     815                 : /*      version 4+.                                                     */
     816                 : /* -------------------------------------------------------------------- */
     817                 : #if ECWSDK_VERSION < 40
     818              44 :     const char *pszLargeOK = CSLFetchNameValue(papszOptions, "LARGE_OK");
     819              44 :     if( pszLargeOK == NULL )
     820              44 :         pszLargeOK = "NO";
     821                 : 
     822              44 :     pszLargeOK = CPLGetConfigOption( "ECW_LARGE_OK", pszLargeOK );
     823                 : 
     824              44 :     if( CSLTestBoolean(pszLargeOK) )
     825                 :     {
     826               0 :         CNCSFile::SetKeySize();
     827               0 :         CPLDebug( "ECW", "Large file generation enabled." );
     828                 :     }
     829                 : #endif /* ECWSDK_VERSION < 40 */
     830                 : 
     831                 : /* -------------------------------------------------------------------- */
     832                 : /*      Set the file info.                                              */
     833                 : /* -------------------------------------------------------------------- */
     834              44 :     CNCSError oError;
     835                 : 
     836              44 :     oError = SetFileInfo( sFileInfo );
     837                 : 
     838              44 :     if( oError.GetErrorNumber() == NCS_SUCCESS )
     839                 :     {
     840              44 :         if( fpVSIL == NULL )
     841               6 :             oError = Open( (char *) pszFilename, false, true );
     842                 :         else
     843              38 :             oError = CNCSJP2FileView::Open( &(m_OStream) );
     844                 :     }
     845                 : 
     846              44 :     if( oError.GetErrorNumber() == NCS_SUCCESS )
     847              40 :         return CE_None;
     848               4 :     else if( oError.GetErrorNumber() == NCS_INPUT_SIZE_EXCEEDED )
     849                 :     {
     850                 :         CPLError( CE_Failure, CPLE_AppDefined,
     851               0 :                   "ECW SDK 500MB compress limit exceeded." );
     852               0 :         return CE_Failure;
     853                 :     }
     854                 :     else
     855                 :     {
     856               4 :         char* pszErrorMessage = oError.GetErrorMessage();
     857                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     858               4 :                   "%s", pszErrorMessage );
     859               4 :         NCSFree(pszErrorMessage);
     860                 : 
     861               4 :         return CE_Failure;
     862               0 :     }
     863                 : }
     864                 : 
     865                 : /************************************************************************/
     866                 : /*                           ECWCreateCopy()                            */
     867                 : /************************************************************************/
     868                 : 
     869                 : static GDALDataset *
     870              44 : ECWCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     871                 :                int bStrict, char ** papszOptions, 
     872                 :                GDALProgressFunc pfnProgress, void * pProgressData,
     873                 :                int bIsJPEG2000 )
     874                 : 
     875                 : {
     876              44 :     ECWInitialize();
     877                 : 
     878                 : /* -------------------------------------------------------------------- */
     879                 : /*      Get various values from the source dataset.                     */
     880                 : /* -------------------------------------------------------------------- */
     881              44 :     int  nBands = poSrcDS->GetRasterCount();
     882              44 :     int  nXSize = poSrcDS->GetRasterXSize();
     883              44 :     int  nYSize = poSrcDS->GetRasterYSize();
     884                 : 
     885              44 :     if (nBands == 0)
     886                 :     {
     887                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     888               0 :                   "ECW driver does not support source dataset with zero band.\n");
     889               0 :         return NULL;
     890                 :     }
     891                 : 
     892              44 :     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     893                 : 
     894              44 :     const char *pszWKT = poSrcDS->GetProjectionRef();
     895              44 :     double adfGeoTransform[6] = { 0, 1, 0, 0, 0, 1 };;
     896                 : 
     897              44 :     poSrcDS->GetGeoTransform( adfGeoTransform );
     898                 : 
     899              44 :     if( poSrcDS->GetGCPCount() > 0 )
     900               2 :         pszWKT = poSrcDS->GetGCPProjection();
     901                 : 
     902                 : /* -------------------------------------------------------------------- */
     903                 : /*      Confirm the datatype is 8bit.  It appears no other datatype     */
     904                 : /*      is supported in ECW format.                                     */
     905                 : /* -------------------------------------------------------------------- */
     906              44 :     if( eType != GDT_Byte && !bIsJPEG2000 )
     907                 :     {
     908               0 :         if( bStrict )
     909                 :         {
     910                 :             CPLError( CE_Failure, CPLE_AppDefined,
     911                 :                       "Attempt to create ECW file with pixel data type %s failed.\n"
     912                 :                       "Only Byte data type supported.",
     913               0 :                       GDALGetDataTypeName( eType ) );
     914                 :         }
     915                 :         else
     916                 :         {
     917                 :             CPLError( CE_Warning, CPLE_AppDefined,
     918                 :                       "ECW only supports Byte pixel data type, ignoring request for %s.",
     919               0 :                       GDALGetDataTypeName( eType ) );
     920               0 :             eType = GDT_Byte;
     921                 :         }
     922                 :     }
     923                 : 
     924                 : /* -------------------------------------------------------------------- */
     925                 : /*      Is the input RGBA?                                              */
     926                 : /* -------------------------------------------------------------------- */
     927              44 :     int bRGBA = FALSE;
     928                 : 
     929              44 :     if( nBands == 4 )
     930                 :     {
     931               2 :         bRGBA = (poSrcDS->GetRasterBand(4)->GetColorInterpretation() 
     932               4 :                  == GCI_AlphaBand);
     933                 :     }        
     934                 : 
     935                 : /* -------------------------------------------------------------------- */
     936                 : /*      Setup the compressor.                                           */
     937                 : /* -------------------------------------------------------------------- */
     938              44 :     GDALECWCompressor         oCompressor;
     939              44 :     CNCSError oErr;
     940                 : 
     941              44 :     oCompressor.pfnProgress = pfnProgress;
     942              44 :     oCompressor.pProgressData = pProgressData;
     943              44 :     oCompressor.m_poSrcDS = poSrcDS;
     944                 : 
     945              44 :     if( !pfnProgress( 0.0, NULL, pProgressData ) )
     946               0 :         return NULL;
     947                 : 
     948              88 :     if( oCompressor.Initialize( pszFilename, papszOptions, 
     949                 :                                 nXSize, nYSize, nBands, bRGBA,
     950                 :                                 eType, pszWKT, adfGeoTransform, 
     951              44 :                                 poSrcDS->GetGCPCount(), 
     952              44 :                                 poSrcDS->GetGCPs(),
     953                 :                                 bIsJPEG2000 )
     954                 :         != CE_None )
     955               8 :         return NULL;
     956                 : 
     957                 : /* -------------------------------------------------------------------- */
     958                 : /*      Start the compression.                                          */
     959                 : /* -------------------------------------------------------------------- */
     960              36 :     oErr = oCompressor.Write();
     961                 : 
     962              36 :     if( oErr.GetErrorNumber() != NCS_SUCCESS )
     963                 :     {
     964               0 :         char* pszErrorMessage = oErr.GetErrorMessage();
     965                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     966               0 :                   "%s", pszErrorMessage );
     967               0 :         NCSFree(pszErrorMessage);
     968                 :         
     969               0 :         return NULL;
     970                 :     }
     971                 : 
     972                 : /* -------------------------------------------------------------------- */
     973                 : /*      Cleanup, and return read-only handle.                           */
     974                 : /* -------------------------------------------------------------------- */
     975              36 :     oCompressor.CloseDown();
     976              36 :     pfnProgress( 1.001, NULL, pProgressData );
     977                 : 
     978                 : /* -------------------------------------------------------------------- */
     979                 : /*      Re-open dataset, and copy any auxilary pam information.         */
     980                 : /* -------------------------------------------------------------------- */
     981              36 :     GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly);
     982                 :     GDALPamDataset *poDS;
     983                 :     
     984              36 :     if (bIsJPEG2000)
     985              34 :         poDS = (GDALPamDataset*) ECWDatasetOpenJPEG2000(&oOpenInfo);
     986                 :     else
     987               2 :         poDS = (GDALPamDataset*) GDALOpen(pszFilename, GA_ReadOnly);
     988                 : 
     989              36 :     if( poDS )
     990              36 :         poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
     991                 : 
     992              36 :     return poDS;
     993                 : }
     994                 : 
     995                 : /************************************************************************/
     996                 : /*                          ECWCreateCopyECW()                          */
     997                 : /************************************************************************/
     998                 : 
     999                 : GDALDataset *
    1000              38 : ECWCreateCopyECW( const char * pszFilename, GDALDataset *poSrcDS, 
    1001                 :                   int bStrict, char ** papszOptions, 
    1002                 :                   GDALProgressFunc pfnProgress, void * pProgressData )
    1003                 : 
    1004                 : {
    1005              38 :     int nBands = poSrcDS->GetRasterCount();
    1006              38 :     if (nBands == 0)
    1007                 :     {
    1008                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1009               2 :                   "ECW driver does not support source dataset with zero band.\n");
    1010               2 :         return NULL;
    1011                 :     }
    1012                 : 
    1013              36 :     if( !EQUAL(CPLGetExtension(pszFilename),"ecw") )
    1014                 :     {
    1015                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1016                 :                   "ECW driver does not support creating ECW files\n"
    1017               0 :                   "with an extension other than .ecw" );
    1018               0 :         return NULL;
    1019                 :     }
    1020                 : 
    1021              36 :     if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1022                 :         && bStrict )
    1023                 :     {
    1024                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1025                 :                   "ECW driver doesn't support data type %s. "
    1026                 :                   "Only eight bit bands supported.\n", 
    1027                 :                   GDALGetDataTypeName( 
    1028              20 :                       poSrcDS->GetRasterBand(1)->GetRasterDataType()) );
    1029                 : 
    1030              20 :         return NULL;
    1031                 :     }
    1032                 : 
    1033              16 :     if( poSrcDS->GetRasterXSize() < 128 || poSrcDS->GetRasterYSize() < 128 )
    1034                 :     {
    1035                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1036                 :                   "ECW driver requires image to be at least 128x128,\n"
    1037                 :                   "the source image is %dx%d.\n", 
    1038                 :                   poSrcDS->GetRasterXSize(),
    1039              10 :                   poSrcDS->GetRasterYSize() );
    1040                 :                   
    1041              10 :         return NULL;
    1042                 :     }
    1043                 : 
    1044               6 :     if (poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)
    1045                 :     {
    1046                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
    1047                 :                   "ECW driver ignores color table. "
    1048                 :                   "The source raster band will be considered as grey level.\n"
    1049               0 :                   "Consider using color table expansion (-expand option in gdal_translate)\n");
    1050               0 :         if (bStrict)
    1051               0 :             return NULL;
    1052                 :     }
    1053                 : 
    1054                 :     return ECWCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions, 
    1055               6 :                           pfnProgress, pProgressData, FALSE );
    1056                 : }
    1057                 : 
    1058                 : /************************************************************************/
    1059                 : /*                       ECWCreateCopyJPEG2000()                        */
    1060                 : /************************************************************************/
    1061                 : 
    1062                 : GDALDataset *
    1063              48 : ECWCreateCopyJPEG2000( const char * pszFilename, GDALDataset *poSrcDS, 
    1064                 :                        int bStrict, char ** papszOptions, 
    1065                 :                        GDALProgressFunc pfnProgress, void * pProgressData )
    1066                 : 
    1067                 : {
    1068              48 :     int nBands = poSrcDS->GetRasterCount();
    1069              48 :     if (nBands == 0)
    1070                 :     {
    1071                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1072               2 :                   "JP2ECW driver does not support source dataset with zero band.\n");
    1073               2 :         return NULL;
    1074                 :     }
    1075                 : 
    1076              46 :     if( EQUAL(CPLGetExtension(pszFilename),"ecw") )
    1077                 :     {
    1078                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1079                 :                   "JP2ECW driver does not support creating JPEG2000 files\n"
    1080               0 :                   "with a .ecw extension.  Please use anything else." );
    1081               0 :         return NULL;
    1082                 :     }
    1083                 : 
    1084              46 :     if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1085                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
    1086                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int16
    1087                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16
    1088                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int32
    1089                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt32
    1090                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Float32
    1091                 :         && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Float64
    1092                 :         && bStrict )
    1093                 :     {
    1094                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1095                 :                   "JP2ECW driver doesn't support data type %s. ",
    1096                 :                   GDALGetDataTypeName( 
    1097               8 :                       poSrcDS->GetRasterBand(1)->GetRasterDataType()) );
    1098                 : 
    1099               8 :         return NULL;
    1100                 :     }
    1101                 : 
    1102              38 :     if (poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)
    1103                 :     {
    1104                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
    1105                 :                   "JP2ECW driver ignores color table. "
    1106                 :                   "The source raster band will be considered as grey level.\n"
    1107               0 :                   "Consider using color table expansion (-expand option in gdal_translate)\n");
    1108               0 :         if (bStrict)
    1109               0 :             return NULL;
    1110                 :     }
    1111                 : 
    1112                 :     return ECWCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions, 
    1113              38 :                           pfnProgress, pProgressData, TRUE );
    1114                 : }
    1115                 : 
    1116                 : /************************************************************************/
    1117                 : /************************************************************************
    1118                 :  
    1119                 :                ECW/JPEG200 Create() Support
    1120                 :                ----------------------------
    1121                 : 
    1122                 :   The remainder of the file is code to implement the Create() method. 
    1123                 :   New dataset and raster band classes are defined specifically for the
    1124                 :   purpose of being write-only.  In particular, you cannot read back data
    1125                 :   from these datasets, and writing must occur in a pretty specific order.
    1126                 :   
    1127                 :   That is, you need to write all metadata (projection, georef, etc) first
    1128                 :   and then write the image data.  All bands data for the first scanline
    1129                 :   should be written followed by all bands for the second scanline and so on.
    1130                 : 
    1131                 :   Creation supports the same virtual subfile names as CreateCopy() supports. 
    1132                 : 
    1133                 :  ************************************************************************/
    1134                 : /************************************************************************/
    1135                 : 
    1136                 : /************************************************************************/
    1137                 : /* ==================================================================== */
    1138                 : /*        ECWWriteDataset       */
    1139                 : /* ==================================================================== */
    1140                 : /************************************************************************/
    1141                 : 
    1142                 : class ECWWriteRasterBand;
    1143                 : 
    1144                 : class CPL_DLL ECWWriteDataset : public GDALDataset
    1145                 : {
    1146                 :     friend class ECWWriteRasterBand;
    1147                 : 
    1148                 :     char      *pszFilename;
    1149                 : 
    1150                 :     int       bIsJPEG2000;
    1151                 :     GDALDataType eDataType;
    1152                 :     char    **papszOptions;
    1153                 :   
    1154                 :     char     *pszProjection;
    1155                 :     double    adfGeoTransform[6];
    1156                 : 
    1157                 :     GDALECWCompressor oCompressor;
    1158                 :     int       bCrystalized;
    1159                 :     
    1160                 :     int       nLoadedLine;
    1161                 :     GByte     *pabyBILBuffer;
    1162                 :     
    1163                 :     CPLErr    Crystalize();
    1164                 :     CPLErr    FlushLine();
    1165                 : 
    1166                 :   public:
    1167                 :         ECWWriteDataset( const char *, int, int, int, 
    1168                 :                                  GDALDataType, char **papszOptions,
    1169                 :                                  int );
    1170                 :         ~ECWWriteDataset();
    1171                 : 
    1172                 :     virtual void   FlushCache( void );
    1173                 : 
    1174                 :     virtual CPLErr GetGeoTransform( double * );
    1175                 :     virtual const char* GetProjectionRef();
    1176                 :     virtual CPLErr SetGeoTransform( double * );
    1177                 :     virtual CPLErr SetProjection( const char *pszWKT );
    1178                 : };
    1179                 : 
    1180                 : /************************************************************************/
    1181                 : /* ==================================================================== */
    1182                 : /*                         ECWWriteRasterBand                           */
    1183                 : /* ==================================================================== */
    1184                 : /************************************************************************/
    1185                 :  
    1186                 : class ECWWriteRasterBand : public GDALRasterBand
    1187             118 : {
    1188                 :     friend class ECWWriteDataset;
    1189                 :     
    1190                 :     // NOTE: poDS may be altered for NITF/JPEG2000 files!
    1191                 :     ECWWriteDataset     *poGDS;
    1192                 : 
    1193                 :     GDALColorInterp     eInterp;
    1194                 : 
    1195                 :   public:
    1196                 : 
    1197                 :                    ECWWriteRasterBand( ECWWriteDataset *, int );
    1198                 : 
    1199               0 :     virtual CPLErr SetColorInterpretation( GDALColorInterp eInterpIn ) 
    1200               0 :         { eInterp = eInterpIn; return CE_None; }
    1201               6 :     virtual GDALColorInterp GetColorInterpretation() 
    1202               6 :         { return eInterp; }
    1203                 : 
    1204                 :     virtual CPLErr IReadBlock( int, int, void * );
    1205                 :     virtual CPLErr IWriteBlock( int, int, void * );
    1206                 : };
    1207                 : 
    1208                 : /************************************************************************/
    1209                 : /*                          ECWWriteDataset()                           */
    1210                 : /************************************************************************/
    1211                 : 
    1212              56 : ECWWriteDataset::ECWWriteDataset( const char *pszFilename, 
    1213                 :                                   int nXSize, int nYSize, int nBandCount, 
    1214                 :                                   GDALDataType eType,
    1215              56 :                                   char **papszOptions, int bIsJPEG2000 )
    1216                 : 
    1217                 : {
    1218              56 :     bCrystalized = FALSE;
    1219              56 :     pabyBILBuffer = NULL;
    1220              56 :     nLoadedLine = -1;
    1221                 : 
    1222              56 :     eAccess = GA_Update;
    1223                 : 
    1224              56 :     this->bIsJPEG2000 = bIsJPEG2000;
    1225              56 :     this->eDataType = eType;
    1226              56 :     this->papszOptions = CSLDuplicate( papszOptions );
    1227              56 :     this->pszFilename = CPLStrdup( pszFilename );
    1228                 : 
    1229              56 :     nRasterXSize = nXSize;
    1230              56 :     nRasterYSize = nYSize;
    1231              56 :     pszProjection = NULL;
    1232                 : 
    1233              56 :     adfGeoTransform[0] = 0.0;
    1234              56 :     adfGeoTransform[1] = 1.0;
    1235              56 :     adfGeoTransform[2] = 0.0;
    1236              56 :     adfGeoTransform[3] = 0.0;
    1237              56 :     adfGeoTransform[4] = 0.0;
    1238              56 :     adfGeoTransform[5] = 1.0;
    1239                 : 
    1240                 :     // create band objects.
    1241             174 :     for( int iBand = 1; iBand <= nBandCount; iBand++ )
    1242                 :     {
    1243             118 :         SetBand( iBand, new ECWWriteRasterBand( this, iBand ) );
    1244                 :     }
    1245              56 : }
    1246                 : 
    1247                 : /************************************************************************/
    1248                 : /*                          ~ECWWriteDataset()                          */
    1249                 : /************************************************************************/
    1250                 : 
    1251              56 : ECWWriteDataset::~ECWWriteDataset()
    1252                 : 
    1253                 : {
    1254              56 :     FlushCache();
    1255                 : 
    1256              56 :     if( bCrystalized )
    1257                 :     {
    1258               4 :         if( nLoadedLine == nRasterYSize - 1 )
    1259               4 :             FlushLine();
    1260               4 :         oCompressor.CloseDown();
    1261                 :     }
    1262                 : 
    1263              56 :     CPLFree( pabyBILBuffer );
    1264              56 :     CPLFree( pszProjection );
    1265              56 :     CSLDestroy( papszOptions );
    1266              56 :     CPLFree( pszFilename );
    1267              56 : }
    1268                 : 
    1269                 : /************************************************************************/
    1270                 : /*                             FlushCache()                             */
    1271                 : /************************************************************************/
    1272                 : 
    1273              58 : void ECWWriteDataset::FlushCache()
    1274                 : 
    1275                 : {
    1276              58 :     BlockBasedFlushCache();
    1277              58 : }
    1278                 : 
    1279                 : /************************************************************************/
    1280                 : /*                         GetProjectionRef()                           */
    1281                 : /************************************************************************/
    1282                 : 
    1283               0 : const char*  ECWWriteDataset::GetProjectionRef()
    1284                 : {
    1285               0 :     return pszProjection;
    1286                 : }
    1287                 : 
    1288                 : /************************************************************************/
    1289                 : /*                          GetGeoTransform()                           */
    1290                 : /************************************************************************/
    1291                 : 
    1292              52 : CPLErr ECWWriteDataset::GetGeoTransform( double *padfGeoTransform )
    1293                 : 
    1294                 : {
    1295              52 :     memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 );
    1296              52 :     return CE_None;
    1297                 : }
    1298                 : 
    1299                 : /************************************************************************/
    1300                 : /*                          SetGeoTransform()                           */
    1301                 : /************************************************************************/
    1302                 : 
    1303              54 : CPLErr ECWWriteDataset::SetGeoTransform( double *padfGeoTransform )
    1304                 : 
    1305                 : {
    1306              54 :     memcpy( adfGeoTransform, padfGeoTransform, sizeof(double) * 6 );
    1307              54 :     return CE_None;
    1308                 : }
    1309                 : 
    1310                 : /************************************************************************/
    1311                 : /*                           SetProjection()                            */
    1312                 : /************************************************************************/
    1313                 : 
    1314              54 : CPLErr ECWWriteDataset::SetProjection( const char *pszWKT )
    1315                 : 
    1316                 : {
    1317              54 :     CPLFree( pszProjection );
    1318              54 :     pszProjection = CPLStrdup( pszWKT );
    1319                 : 
    1320              54 :     return CE_None;
    1321                 : }
    1322                 : 
    1323                 : 
    1324                 : /************************************************************************/
    1325                 : /*                             Crystalize()                             */
    1326                 : /************************************************************************/
    1327                 : 
    1328               4 : CPLErr ECWWriteDataset::Crystalize()
    1329                 : 
    1330                 : {
    1331               4 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1332                 : 
    1333                 :     CPLErr eErr;
    1334               4 :     CNCSError oError;
    1335                 : 
    1336               4 :     if( bCrystalized )
    1337               0 :         return CE_None;
    1338                 : 
    1339                 :     eErr = oCompressor.Initialize( pszFilename, papszOptions, 
    1340                 :                                    nRasterXSize, nRasterYSize, nBands, FALSE,
    1341                 :                                    eDataType, 
    1342                 :                                    pszProjection, adfGeoTransform, 
    1343                 :                                    0, NULL,
    1344               4 :                                    bIsJPEG2000 );
    1345                 : 
    1346               4 :     if( eErr == CE_None )
    1347               4 :         bCrystalized = TRUE;
    1348                 : 
    1349               4 :     nLoadedLine = -1;
    1350               4 :     pabyBILBuffer = (GByte *) CPLMalloc( nWordSize * nBands * nRasterXSize );
    1351                 : 
    1352               4 :     return eErr;
    1353                 : }
    1354                 : 
    1355                 : /************************************************************************/
    1356                 : /*                             FlushLine()                              */
    1357                 : /************************************************************************/
    1358                 : 
    1359             404 : CPLErr ECWWriteDataset::FlushLine()
    1360                 : 
    1361                 : {
    1362             404 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1363                 :     CPLErr eErr;
    1364                 : 
    1365                 : /* -------------------------------------------------------------------- */
    1366                 : /*      Crystalize if not already done.                                 */
    1367                 : /* -------------------------------------------------------------------- */
    1368             404 :     if( !bCrystalized )
    1369                 :     {
    1370               4 :         eErr = Crystalize();
    1371                 : 
    1372               4 :         if( eErr != CE_None )
    1373               0 :             return eErr;
    1374                 :     }
    1375                 : 
    1376                 : /* -------------------------------------------------------------------- */
    1377                 : /*      Write out the currently loaded line.                            */
    1378                 : /* -------------------------------------------------------------------- */
    1379             404 :     if( nLoadedLine != -1 )
    1380                 :     {
    1381             400 :         CNCSError oError;
    1382                 :         void **papOutputLine;
    1383                 : 
    1384             400 :         papOutputLine = (void **) CPLMalloc(sizeof(void*) * nBands);
    1385            1200 :         for( int i = 0; i < nBands; i++ )
    1386             800 :             papOutputLine[i] = 
    1387             800 :                 (void *) (pabyBILBuffer + i * nWordSize * nRasterXSize);
    1388                 :         
    1389                 : 
    1390                 :         oError = oCompressor.WriteLineBIL( oCompressor.sFileInfo.eCellType, 
    1391             400 :                                            (UINT16) nBands, papOutputLine );
    1392             400 :         CPLFree( papOutputLine );
    1393             400 :         if( oError.GetErrorNumber() != NCS_SUCCESS )
    1394                 :         {
    1395               0 :             char* pszErrorMessage = oError.GetErrorMessage();
    1396                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1397                 :                       "Scanline write write failed.\n%s",
    1398               0 :                       pszErrorMessage );
    1399               0 :             NCSFree(pszErrorMessage);
    1400                 : 
    1401               0 :             return CE_Failure;
    1402               0 :         }
    1403                 :     }
    1404                 : 
    1405                 : /* -------------------------------------------------------------------- */
    1406                 : /*      Clear the buffer and increment the "current line" indicator.    */
    1407                 : /* -------------------------------------------------------------------- */
    1408             404 :     memset( pabyBILBuffer, 0, nWordSize * nRasterXSize * nBands );
    1409             404 :     nLoadedLine++;
    1410                 : 
    1411             404 :     return CE_None;
    1412                 : }
    1413                 : 
    1414                 : 
    1415                 : /************************************************************************/
    1416                 : /* ==================================================================== */
    1417                 : /*                          ECWWriteRasterBand                          */
    1418                 : /* ==================================================================== */
    1419                 : /************************************************************************/
    1420                 : 
    1421                 : /************************************************************************/
    1422                 : /*                         ECWWriteRasterBand()                         */
    1423                 : /************************************************************************/
    1424                 : 
    1425             118 : ECWWriteRasterBand::ECWWriteRasterBand( ECWWriteDataset *poDSIn,
    1426             118 :                                         int nBandIn )
    1427                 : 
    1428                 : {
    1429             118 :     nBand = nBandIn;
    1430             118 :     poDS = poDSIn;
    1431             118 :     poGDS = poDSIn;
    1432             118 :     nBlockXSize = poDSIn->GetRasterXSize();
    1433             118 :     nBlockYSize = 1;
    1434             118 :     eDataType = poDSIn->eDataType;
    1435             118 :     eInterp = GCI_Undefined;
    1436             118 : }
    1437                 : 
    1438                 : /************************************************************************/
    1439                 : /*                             IReadBlock()                             */
    1440                 : /************************************************************************/
    1441                 : 
    1442               0 : CPLErr ECWWriteRasterBand::IReadBlock( int nBlockX, int nBlockY, 
    1443                 :                                        void *pBuffer )
    1444                 : 
    1445                 : {
    1446               0 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1447                 : 
    1448                 :     // We zero stuff out here, but we can't really read stuff from
    1449                 :     // a write only stream. 
    1450                 : 
    1451               0 :     memset( pBuffer, 0, nBlockXSize * nWordSize );
    1452                 : 
    1453               0 :     return CE_None;
    1454                 : }
    1455                 : 
    1456                 : /************************************************************************/
    1457                 : /*                            IWriteBlock()                             */
    1458                 : /************************************************************************/
    1459                 : 
    1460             800 : CPLErr ECWWriteRasterBand::IWriteBlock( int nBlockX, int nBlockY, 
    1461                 :                                         void *pBuffer )
    1462                 : 
    1463                 : {
    1464             800 :     int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
    1465                 :     CPLErr eErr;
    1466                 : 
    1467                 : /* -------------------------------------------------------------------- */
    1468                 : /*      Flush previous line if needed.                                  */
    1469                 : /* -------------------------------------------------------------------- */
    1470             800 :     if( nBlockY == poGDS->nLoadedLine + 1 )
    1471                 :     {
    1472             400 :         eErr = poGDS->FlushLine();
    1473             400 :         if( eErr != CE_None )
    1474               0 :             return eErr;
    1475                 :     }
    1476                 : 
    1477                 : /* -------------------------------------------------------------------- */
    1478                 : /*      Blow a gasket if we have been asked to write something out      */
    1479                 : /*      of order.                                                       */
    1480                 : /* -------------------------------------------------------------------- */
    1481             800 :     if( nBlockY != poGDS->nLoadedLine )
    1482                 :     {
    1483                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1484                 :                   "Apparent attempt to write to ECW non-sequentially.\n"
    1485                 :                   "Loaded line is %d, but %d of band %d was written to.",
    1486               0 :                   poGDS->nLoadedLine, nBlockY, nBand );
    1487               0 :         return CE_Failure;
    1488                 :     }
    1489                 : 
    1490                 : /* -------------------------------------------------------------------- */
    1491                 : /*      Copy passed data into current line buffer.                      */
    1492                 : /* -------------------------------------------------------------------- */
    1493                 :     memcpy( poGDS->pabyBILBuffer + (nBand-1) * nWordSize * nRasterXSize, 
    1494                 :             pBuffer, 
    1495             800 :             nWordSize * nRasterXSize );
    1496                 : 
    1497             800 :     return CE_None;
    1498                 : }
    1499                 : 
    1500                 : /************************************************************************/
    1501                 : /*                         ECWCreateJPEG2000()                          */
    1502                 : /************************************************************************/
    1503                 : 
    1504                 : GDALDataset *
    1505              56 : ECWCreateJPEG2000(const char *pszFilename, int nXSize, int nYSize, int nBands, 
    1506                 :                   GDALDataType eType, char **papszOptions )
    1507                 : 
    1508                 : {
    1509              56 :     ECWInitialize();
    1510                 : 
    1511                 :     return new ECWWriteDataset( pszFilename, nXSize, nYSize, nBands, 
    1512              56 :                                 eType, papszOptions, TRUE );
    1513                 : }
    1514                 : 
    1515                 : /************************************************************************/
    1516                 : /*                            ECWCreateECW()                            */
    1517                 : /************************************************************************/
    1518                 : 
    1519                 : GDALDataset *
    1520               0 : ECWCreateECW( const char *pszFilename, int nXSize, int nYSize, int nBands, 
    1521                 :               GDALDataType eType, char **papszOptions )
    1522                 : 
    1523                 : {
    1524               0 :     ECWInitialize();
    1525                 : 
    1526                 :     return new ECWWriteDataset( pszFilename, nXSize, nYSize, nBands, 
    1527               0 :                                 eType, papszOptions, FALSE );
    1528            4029 : }
    1529                 : 
    1530                 : #endif /* def FRMT_ecw && def HAVE_COMPRESS */

Generated by: LCOV version 1.7