LCOV - code coverage report
Current view: directory - frmts/ecw - ecwcreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 451 357 79.2 %
Date: 2012-12-26 Functions: 37 24 64.9 %

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

Generated by: LCOV version 1.7