1 /******************************************************************************
2  * $Id: jpeg2000dataset.cpp 29171 2015-05-07 19:49:07Z rouault $
3  *
4  * Project:  JPEG-2000
5  * Purpose:  Partial implementation of the ISO/IEC 15444-1 standard
6  * Author:   Andrey Kiselev, dron@ak4719.spb.edu
7  *
8  ******************************************************************************
9  * Copyright (c) 2002, Andrey Kiselev <dron@ak4719.spb.edu>
10  * Copyright (c) 2007-2013, Even Rouault <even dot rouault at mines-paris dot org>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #include "gdaljp2abstractdataset.h"
32 #include "gdaljp2metadata.h"
33 #include "cpl_string.h"
34 
35 #include <jasper/jasper.h>
36 #include "jpeg2000_vsil_io.h"
37 
38 CPL_CVSID("$Id: jpeg2000dataset.cpp 29171 2015-05-07 19:49:07Z rouault $");
39 
40 CPL_C_START
41 void    GDALRegister_JPEG2000(void);
42 CPL_C_END
43 
44 // XXX: Part of code below extracted from the JasPer internal headers and
45 // must be in sync with JasPer version (this one works with JasPer 1.900.1)
46 #define JP2_FTYP_MAXCOMPATCODES 32
47 #define JP2_BOX_IHDR    0x69686472      /* Image Header */
48 #define JP2_BOX_BPCC    0x62706363      /* Bits Per Component */
49 #define	JP2_BOX_PCLR	0x70636c72	/* Palette */
50 #define JP2_BOX_UUID    0x75756964      /* UUID */
51 extern "C" {
52 typedef struct {
53         uint_fast32_t magic;
54 } jp2_jp_t;
55 typedef struct {
56         uint_fast32_t majver;
57         uint_fast32_t minver;
58         uint_fast32_t numcompatcodes;
59         uint_fast32_t compatcodes[JP2_FTYP_MAXCOMPATCODES];
60 } jp2_ftyp_t;
61 typedef struct {
62         uint_fast32_t width;
63         uint_fast32_t height;
64         uint_fast16_t numcmpts;
65         uint_fast8_t bpc;
66         uint_fast8_t comptype;
67         uint_fast8_t csunk;
68         uint_fast8_t ipr;
69 } jp2_ihdr_t;
70 typedef struct {
71         uint_fast16_t numcmpts;
72         uint_fast8_t *bpcs;
73 } jp2_bpcc_t;
74 typedef struct {
75         uint_fast8_t method;
76         uint_fast8_t pri;
77         uint_fast8_t approx;
78         uint_fast32_t csid;
79         uint_fast8_t *iccp;
80         int iccplen;
81 } jp2_colr_t;
82 typedef struct {
83         uint_fast16_t numlutents;
84         uint_fast8_t numchans;
85         int_fast32_t *lutdata;
86         uint_fast8_t *bpc;
87 } jp2_pclr_t;
88 typedef struct {
89         uint_fast16_t channo;
90         uint_fast16_t type;
91         uint_fast16_t assoc;
92 } jp2_cdefchan_t;
93 typedef struct {
94         uint_fast16_t numchans;
95         jp2_cdefchan_t *ents;
96 } jp2_cdef_t;
97 typedef struct {
98         uint_fast16_t cmptno;
99         uint_fast8_t map;
100         uint_fast8_t pcol;
101 } jp2_cmapent_t;
102 
103 typedef struct {
104         uint_fast16_t numchans;
105         jp2_cmapent_t *ents;
106 } jp2_cmap_t;
107 
108 #ifdef HAVE_JASPER_UUID
109 typedef struct {
110         uint_fast32_t datalen;
111         uint_fast8_t uuid[16];
112         uint_fast8_t *data;
113 } jp2_uuid_t;
114 #endif
115 
116 struct jp2_boxops_s;
117 typedef struct {
118 
119         struct jp2_boxops_s *ops;
120         struct jp2_boxinfo_s *info;
121 
122         uint_fast32_t type;
123 
124         /* The length of the box including the (variable-length) header. */
125         uint_fast32_t len;
126 
127         /* The length of the box data. */
128         uint_fast32_t datalen;
129 
130         union {
131                 jp2_jp_t jp;
132                 jp2_ftyp_t ftyp;
133                 jp2_ihdr_t ihdr;
134                 jp2_bpcc_t bpcc;
135                 jp2_colr_t colr;
136                 jp2_pclr_t pclr;
137                 jp2_cdef_t cdef;
138                 jp2_cmap_t cmap;
139 #ifdef HAVE_JASPER_UUID
140                 jp2_uuid_t uuid;
141 #endif
142         } data;
143 
144 } jp2_box_t;
145 
146 typedef struct jp2_boxops_s {
147         void (*init)(jp2_box_t *box);
148         void (*destroy)(jp2_box_t *box);
149         int (*getdata)(jp2_box_t *box, jas_stream_t *in);
150         int (*putdata)(jp2_box_t *box, jas_stream_t *out);
151         void (*dumpdata)(jp2_box_t *box, FILE *out);
152 } jp2_boxops_t;
153 
154 extern jp2_box_t *jp2_box_create(int type);
155 extern void jp2_box_destroy(jp2_box_t *box);
156 extern jp2_box_t *jp2_box_get(jas_stream_t *in);
157 extern int jp2_box_put(jp2_box_t *box, jas_stream_t *out);
158 #ifdef HAVE_JASPER_UUID
159 int jp2_encode_uuid(jas_image_t *image, jas_stream_t *out,
160                     char *optstr, jp2_box_t *uuid);
161 #endif
162 }
163 // XXX: End of JasPer header.
164 
165 /************************************************************************/
166 /* ==================================================================== */
167 /*                              JPEG2000Dataset                         */
168 /* ==================================================================== */
169 /************************************************************************/
170 
171 class JPEG2000Dataset : public GDALJP2AbstractDataset
172 {
173     friend class JPEG2000RasterBand;
174 
175     jas_stream_t *psStream;
176     jas_image_t *psImage;
177     int         iFormat;
178     int         bPromoteTo8Bit;
179 
180     int         bAlreadyDecoded;
181     int         DecodeImage();
182 
183   public:
184                 JPEG2000Dataset();
185                 ~JPEG2000Dataset();
186 
187     static int           Identify( GDALOpenInfo * );
188     static GDALDataset  *Open( GDALOpenInfo * );
189 };
190 
191 /************************************************************************/
192 /* ==================================================================== */
193 /*                            JPEG2000RasterBand                        */
194 /* ==================================================================== */
195 /************************************************************************/
196 
197 class JPEG2000RasterBand : public GDALPamRasterBand
198 {
199     friend class JPEG2000Dataset;
200 
201     // NOTE: poDS may be altered for NITF/JPEG2000 files!
202     JPEG2000Dataset     *poGDS;
203 
204     jas_matrix_t        *psMatrix;
205 
206     int                  iDepth;
207     int                  bSignedness;
208 
209   public:
210 
211                 JPEG2000RasterBand( JPEG2000Dataset *, int, int, int );
212                 ~JPEG2000RasterBand();
213 
214     virtual CPLErr IReadBlock( int, int, void * );
215     virtual GDALColorInterp GetColorInterpretation();
216 };
217 
218 
219 /************************************************************************/
220 /*                           JPEG2000RasterBand()                       */
221 /************************************************************************/
222 
JPEG2000RasterBand(JPEG2000Dataset * poDS,int nBand,int iDepth,int bSignedness)223 JPEG2000RasterBand::JPEG2000RasterBand( JPEG2000Dataset *poDS, int nBand,
224                 int iDepth, int bSignedness )
225 
226 {
227     this->poDS = poDS;
228     poGDS = poDS;
229     this->nBand = nBand;
230     this->iDepth = iDepth;
231     this->bSignedness = bSignedness;
232 
233     // XXX: JasPer can't handle data with depth > 32 bits
234     // Maximum possible depth for JPEG2000 is 38!
235     switch ( bSignedness )
236     {
237         case 1:                         // Signed component
238         if (iDepth <= 8)
239             this->eDataType = GDT_Byte; // FIXME: should be signed,
240                                         // but we haven't signed byte
241                                         // data type in GDAL
242         else if (iDepth <= 16)
243             this->eDataType = GDT_Int16;
244         else if (iDepth <= 32)
245             this->eDataType = GDT_Int32;
246         break;
247         case 0:                         // Unsigned component
248         default:
249         if (iDepth <= 8)
250             this->eDataType = GDT_Byte;
251         else if (iDepth <= 16)
252             this->eDataType = GDT_UInt16;
253         else if (iDepth <= 32)
254             this->eDataType = GDT_UInt32;
255         break;
256     }
257     // FIXME: Figure out optimal block size!
258     // Should the block size be fixed or determined dynamically?
259     nBlockXSize = MIN(256, poDS->nRasterXSize);
260     nBlockYSize = MIN(256, poDS->nRasterYSize);
261     psMatrix = jas_matrix_create(nBlockYSize, nBlockXSize);
262 
263     if( iDepth % 8 != 0 && !poDS->bPromoteTo8Bit )
264     {
265         SetMetadataItem( "NBITS",
266                          CPLString().Printf("%d",iDepth),
267                          "IMAGE_STRUCTURE" );
268     }
269     SetMetadataItem( "COMPRESSION", "JP2000", "IMAGE_STRUCTURE" );
270 }
271 
272 /************************************************************************/
273 /*                         ~JPEG2000RasterBand()                        */
274 /************************************************************************/
275 
~JPEG2000RasterBand()276 JPEG2000RasterBand::~JPEG2000RasterBand()
277 {
278     if ( psMatrix )
279         jas_matrix_destroy( psMatrix );
280 }
281 
282 /************************************************************************/
283 /*                             IReadBlock()                             */
284 /************************************************************************/
285 
IReadBlock(int nBlockXOff,int nBlockYOff,void * pImage)286 CPLErr JPEG2000RasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
287                                       void * pImage )
288 {
289     int             i, j;
290 
291     // Decode image from the stream, if not yet
292     if ( !poGDS->DecodeImage() )
293     {
294         return CE_Failure;
295     }
296 
297     // Now we can calculate the pixel offset of the top left by multiplying
298     // block offset with the block size.
299 
300     /* In case the dimensions of the image are not multiple of the block dimensions */
301     /* take care of not requesting more pixels than available for the blocks at the */
302     /* right or bottom of the image */
303     int nWidthToRead = MIN(nBlockXSize, poGDS->nRasterXSize - nBlockXOff * nBlockXSize);
304     int nHeightToRead = MIN(nBlockYSize, poGDS->nRasterYSize - nBlockYOff * nBlockYSize);
305 
306     jas_image_readcmpt( poGDS->psImage, nBand - 1,
307                         nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize,
308                         nWidthToRead, nHeightToRead, psMatrix );
309 
310     int nWordSize = GDALGetDataTypeSize(eDataType) / 8;
311     int nLineSize = nBlockXSize * nWordSize;
312     GByte* ptr = (GByte*)pImage;
313 
314     /* Pad incomplete blocks at the right or bottom of the image */
315     if (nWidthToRead != nBlockXSize || nHeightToRead != nBlockYSize)
316         memset(pImage, 0, nLineSize * nBlockYSize);
317 
318     for( i = 0; i < nHeightToRead; i++, ptr += nLineSize )
319     {
320         for( j = 0; j < nWidthToRead; j++ )
321         {
322             // XXX: We need casting because matrix element always
323             // has 32 bit depth in JasPer
324             // FIXME: what about float values?
325             switch( eDataType )
326             {
327                 case GDT_Int16:
328                 {
329                     ((GInt16*)ptr)[j] = (GInt16)jas_matrix_get(psMatrix, i, j);
330                 }
331                 break;
332                 case GDT_Int32:
333                 {
334                     ((GInt32*)ptr)[j] = (GInt32)jas_matrix_get(psMatrix, i, j);
335                 }
336                 break;
337                 case GDT_UInt16:
338                 {
339                     ((GUInt16*)ptr)[j] = (GUInt16)jas_matrix_get(psMatrix, i, j);
340                 }
341                 break;
342                 case GDT_UInt32:
343                 {
344                     ((GUInt32*)ptr)[j] = (GUInt32)jas_matrix_get(psMatrix, i, j);
345                 }
346                 break;
347                 case GDT_Byte:
348                 default:
349                 {
350                     ((GByte*)ptr)[j] = (GByte)jas_matrix_get(psMatrix, i, j);
351                 }
352                 break;
353             }
354         }
355     }
356 
357     if( poGDS->bPromoteTo8Bit && nBand == 4 )
358     {
359         ptr = (GByte*)pImage;
360         for( i = 0; i < nHeightToRead; i++, ptr += nLineSize )
361         {
362             for( j = 0; j < nWidthToRead; j++ )
363             {
364                 ((GByte*)ptr)[j] *= 255;
365             }
366         }
367     }
368 
369     return CE_None;
370 }
371 
372 /************************************************************************/
373 /*                       GetColorInterpretation()                       */
374 /************************************************************************/
375 
GetColorInterpretation()376 GDALColorInterp JPEG2000RasterBand::GetColorInterpretation()
377 {
378     // Decode image from the stream, if not yet
379     if ( !poGDS->DecodeImage() )
380     {
381         return GCI_Undefined;
382     }
383 
384     if ( jas_clrspc_fam( jas_image_clrspc( poGDS->psImage ) ) ==
385          JAS_CLRSPC_FAM_GRAY )
386         return GCI_GrayIndex;
387     else if ( jas_clrspc_fam( jas_image_clrspc( poGDS->psImage ) ) ==
388               JAS_CLRSPC_FAM_RGB )
389     {
390         switch ( jas_image_cmpttype( poGDS->psImage, nBand - 1 ) )
391         {
392             case JAS_IMAGE_CT_RGB_R:
393                 return GCI_RedBand;
394             case JAS_IMAGE_CT_RGB_G:
395                 return GCI_GreenBand;
396             case JAS_IMAGE_CT_RGB_B:
397                 return GCI_BlueBand;
398             case JAS_IMAGE_CT_OPACITY:
399                 return GCI_AlphaBand;
400             default:
401                 return GCI_Undefined;
402         }
403     }
404     else
405         return GCI_Undefined;
406 }
407 
408 /************************************************************************/
409 /* ==================================================================== */
410 /*                              JPEG2000Dataset                         */
411 /* ==================================================================== */
412 /************************************************************************/
413 
414 /************************************************************************/
415 /*                           JPEG2000Dataset()                          */
416 /************************************************************************/
417 
JPEG2000Dataset()418 JPEG2000Dataset::JPEG2000Dataset()
419 {
420     psStream = NULL;
421     psImage = NULL;
422     nBands = 0;
423     bAlreadyDecoded = FALSE;
424     bPromoteTo8Bit = FALSE;
425 
426     poDriver = (GDALDriver *)GDALGetDriverByName("JPEG2000");
427 }
428 
429 /************************************************************************/
430 /*                            ~JPEG2000Dataset()                        */
431 /************************************************************************/
432 
~JPEG2000Dataset()433 JPEG2000Dataset::~JPEG2000Dataset()
434 
435 {
436     FlushCache();
437 
438     if ( psStream )
439         jas_stream_close( psStream );
440     if ( psImage )
441         jas_image_destroy( psImage );
442 }
443 
444 /************************************************************************/
445 /*                             DecodeImage()                            */
446 /************************************************************************/
DecodeImage()447 int JPEG2000Dataset::DecodeImage()
448 {
449     if (bAlreadyDecoded)
450         return psImage != NULL;
451 
452     bAlreadyDecoded = TRUE;
453     if ( !( psImage = jas_image_decode(psStream, iFormat, 0) ) )
454     {
455         CPLDebug( "JPEG2000", "Unable to decode image. Format: %s, %d",
456                   jas_image_fmttostr( iFormat ), iFormat );
457         return FALSE;
458     }
459 
460     /* Case of a JP2 image : check that the properties given by */
461     /* the JP2 boxes match the ones of the code stream */
462     if (nBands != 0)
463     {
464         if (nBands != jas_image_numcmpts( psImage ))
465         {
466             CPLError(CE_Failure, CPLE_AppDefined,
467                      "The number of components indicated in the IHDR box (%d) mismatch "
468                      "the value specified in the code stream (%d)",
469                      nBands, jas_image_numcmpts( psImage ));
470             jas_image_destroy( psImage );
471             psImage = NULL;
472             return FALSE;
473         }
474 
475         if (nRasterXSize != jas_image_cmptwidth( psImage, 0 ) ||
476             nRasterYSize != jas_image_cmptheight( psImage, 0 ) )
477         {
478             CPLError(CE_Failure, CPLE_AppDefined,
479                      "The dimensions indicated in the IHDR box (%d x %d) mismatch "
480                      "the value specified in the code stream (%d x %d)",
481                      nRasterXSize, nRasterYSize,
482                      (int)jas_image_cmptwidth( psImage, 0 ),
483                      (int)jas_image_cmptheight( psImage, 0 ));
484             jas_image_destroy( psImage );
485             psImage = NULL;
486             return FALSE;
487         }
488 
489         int iBand;
490         for ( iBand = 0; iBand < nBands; iBand++ )
491         {
492             JPEG2000RasterBand* poBand = (JPEG2000RasterBand*) GetRasterBand(iBand+1);
493             if (poBand->iDepth != jas_image_cmptprec( psImage, iBand ) ||
494                 poBand->bSignedness != jas_image_cmptsgnd( psImage, iBand ))
495             {
496                 CPLError(CE_Failure, CPLE_AppDefined,
497                          "The bit depth of band %d indicated in the IHDR box (%d) mismatch "
498                          "the value specified in the code stream (%d)",
499                          iBand + 1, poBand->iDepth, jas_image_cmptprec( psImage, iBand ));
500                 jas_image_destroy( psImage );
501                 psImage = NULL;
502                 return FALSE;
503             }
504         }
505     }
506 
507     /* Ask for YCbCr -> RGB translation */
508     if ( jas_clrspc_fam( jas_image_clrspc( psImage ) ) ==
509               JAS_CLRSPC_FAM_YCBCR )
510     {
511         jas_image_t *psRGBImage;
512         jas_cmprof_t *psRGBProf;
513         CPLDebug( "JPEG2000", "forcing conversion to sRGB");
514         if (!(psRGBProf = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) {
515             CPLDebug( "JPEG2000", "cannot create sRGB profile");
516             return TRUE;
517         }
518         if (!(psRGBImage = jas_image_chclrspc(psImage, psRGBProf, JAS_CMXFORM_INTENT_PER))) {
519             CPLDebug( "JPEG2000", "cannot convert to sRGB");
520             jas_cmprof_destroy(psRGBProf);
521             return TRUE;
522         }
523         jas_image_destroy(psImage);
524         jas_cmprof_destroy(psRGBProf);
525         psImage = psRGBImage;
526     }
527 
528     return TRUE;
529 }
530 
JPEG2000Init()531 static void JPEG2000Init()
532 {
533     static int bHasInit = FALSE;
534     if (!bHasInit)
535     {
536         bHasInit = TRUE;
537         jas_init();
538     }
539 }
540 
541 /************************************************************************/
542 /*                            Identify()                                */
543 /************************************************************************/
544 
Identify(GDALOpenInfo * poOpenInfo)545 int JPEG2000Dataset::Identify( GDALOpenInfo * poOpenInfo )
546 
547 {
548     static const unsigned char jpc_header[] = {0xff,0x4f};
549     static const unsigned char jp2_box_jp[] = {0x6a,0x50,0x20,0x20}; /* 'jP  ' */
550 
551     if( poOpenInfo->nHeaderBytes >= 16
552         && (memcmp( poOpenInfo->pabyHeader, jpc_header,
553                     sizeof(jpc_header) ) == 0
554             || memcmp( poOpenInfo->pabyHeader + 4, jp2_box_jp,
555                     sizeof(jp2_box_jp) ) == 0
556             /* PGX file*/
557             || (memcmp( poOpenInfo->pabyHeader, "PG", 2) == 0 &&
558                 (poOpenInfo->pabyHeader[2] == ' ' || poOpenInfo->pabyHeader[2] == '\t') &&
559                 (memcmp( poOpenInfo->pabyHeader + 3, "ML", 2) == 0 ||
560                  memcmp( poOpenInfo->pabyHeader + 3, "LM", 2) == 0))) )
561         return TRUE;
562 
563     else
564         return FALSE;
565 }
566 
567 /************************************************************************/
568 /*                                Open()                                */
569 /************************************************************************/
570 
Open(GDALOpenInfo * poOpenInfo)571 GDALDataset *JPEG2000Dataset::Open( GDALOpenInfo * poOpenInfo )
572 
573 {
574     int         iFormat;
575     char        *pszFormatName = NULL;
576     jas_stream_t *sS;
577 
578     if (!Identify(poOpenInfo))
579         return NULL;
580 
581     JPEG2000Init();
582     if( !(sS = JPEG2000_VSIL_fopen( poOpenInfo->pszFilename, "rb" )) )
583     {
584         return NULL;
585     }
586 
587     iFormat = jas_image_getfmt( sS );
588     if ( !(pszFormatName = jas_image_fmttostr( iFormat )) )
589     {
590         jas_stream_close( sS );
591         return NULL;
592     }
593     if ( strlen( pszFormatName ) < 3 ||
594         (!EQUALN( pszFormatName, "jp2", 3 ) &&
595          !EQUALN( pszFormatName, "jpc", 3 ) &&
596          !EQUALN( pszFormatName, "pgx", 3 )) )
597     {
598         CPLDebug( "JPEG2000", "JasPer reports file is format type `%s'.",
599                   pszFormatName );
600         jas_stream_close( sS );
601         return NULL;
602     }
603 
604 /* -------------------------------------------------------------------- */
605 /*      Confirm the requested access is supported.                      */
606 /* -------------------------------------------------------------------- */
607     if( poOpenInfo->eAccess == GA_Update )
608     {
609         jas_stream_close(sS);
610         CPLError( CE_Failure, CPLE_NotSupported,
611                   "The JPEG2000 driver does not support update access to existing"
612                   " datasets.\n" );
613         return NULL;
614     }
615 /* -------------------------------------------------------------------- */
616 /*      Create a corresponding GDALDataset.                             */
617 /* -------------------------------------------------------------------- */
618     JPEG2000Dataset     *poDS;
619     int                 *paiDepth = NULL, *pabSignedness = NULL;
620     int                 iBand;
621 
622     poDS = new JPEG2000Dataset();
623 
624     poDS->psStream = sS;
625     poDS->iFormat = iFormat;
626 
627     if ( EQUALN( pszFormatName, "jp2", 3 ) )
628     {
629         // XXX: Hack to read JP2 boxes from input file. JasPer hasn't public
630         // API call for such things, so we will use internal JasPer functions.
631         jp2_box_t *box;
632         box = 0;
633         while ( ( box = jp2_box_get(poDS->psStream) ) )
634         {
635             switch (box->type)
636             {
637                 case JP2_BOX_IHDR:
638                 poDS->nBands = box->data.ihdr.numcmpts;
639                 poDS->nRasterXSize = box->data.ihdr.width;
640                 poDS->nRasterYSize = box->data.ihdr.height;
641                 CPLDebug( "JPEG2000",
642                           "IHDR box found. Dump: "
643                           "width=%d, height=%d, numcmpts=%d, bpp=%d",
644                           (int)box->data.ihdr.width, (int)box->data.ihdr.height,
645                           (int)box->data.ihdr.numcmpts, (box->data.ihdr.bpc & 0x7F) + 1 );
646                 /* ISO/IEC 15444-1:2004 I.5.3.1 specifies that 255 means that all */
647                 /* components have not the same bit depth and/or sign and that a */
648                 /* BPCC box must then follow to specify them for each component */
649                 if ( box->data.ihdr.bpc != 255 )
650                 {
651                     paiDepth = (int *)CPLMalloc(poDS->nBands * sizeof(int));
652                     pabSignedness = (int *)CPLMalloc(poDS->nBands * sizeof(int));
653                     for ( iBand = 0; iBand < poDS->nBands; iBand++ )
654                     {
655                         paiDepth[iBand] = (box->data.ihdr.bpc & 0x7F) + 1;
656                         pabSignedness[iBand] = box->data.ihdr.bpc >> 7;
657                         CPLDebug( "JPEG2000",
658                                   "Component %d: bpp=%d, signedness=%d",
659                                   iBand, paiDepth[iBand], pabSignedness[iBand] );
660                     }
661                 }
662                 break;
663 
664                 case JP2_BOX_BPCC:
665                 CPLDebug( "JPEG2000", "BPCC box found. Dump:" );
666                 if ( !paiDepth && !pabSignedness )
667                 {
668                     paiDepth = (int *)
669                         CPLMalloc( box->data.bpcc.numcmpts * sizeof(int) );
670                     pabSignedness = (int *)
671                         CPLMalloc( box->data.bpcc.numcmpts * sizeof(int) );
672                     for( iBand = 0; iBand < (int)box->data.bpcc.numcmpts; iBand++ )
673                     {
674                         paiDepth[iBand] = (box->data.bpcc.bpcs[iBand] & 0x7F) + 1;
675                         pabSignedness[iBand] = box->data.bpcc.bpcs[iBand] >> 7;
676                         CPLDebug( "JPEG2000",
677                                   "Component %d: bpp=%d, signedness=%d",
678                                   iBand, paiDepth[iBand], pabSignedness[iBand] );
679                     }
680                 }
681                 break;
682 
683                 case JP2_BOX_PCLR:
684                 CPLDebug( "JPEG2000",
685                           "PCLR box found. Dump: number of LUT entries=%d, "
686                           "number of resulting channels=%d",
687                           (int)box->data.pclr.numlutents, box->data.pclr.numchans );
688                 poDS->nBands = box->data.pclr.numchans;
689                 if ( paiDepth )
690                     CPLFree( paiDepth );
691                 if ( pabSignedness )
692                     CPLFree( pabSignedness );
693                 paiDepth = (int *)
694                         CPLMalloc( box->data.pclr.numchans * sizeof(int) );
695                 pabSignedness = (int *)
696                         CPLMalloc( box->data.pclr.numchans * sizeof(int) );
697                 for( iBand = 0; iBand < (int)box->data.pclr.numchans; iBand++ )
698                 {
699                     paiDepth[iBand] = (box->data.pclr.bpc[iBand] & 0x7F) + 1;
700                     pabSignedness[iBand] = box->data.pclr.bpc[iBand] >> 7;
701                     CPLDebug( "JPEG2000",
702                               "Component %d: bpp=%d, signedness=%d",
703                               iBand, paiDepth[iBand], pabSignedness[iBand] );
704                 }
705                 break;
706             }
707             jp2_box_destroy( box );
708             box = 0;
709         }
710         if( !paiDepth || !pabSignedness )
711         {
712             delete poDS;
713             CPLDebug( "JPEG2000", "Unable to read JP2 header boxes.\n" );
714             return NULL;
715         }
716         if ( jas_stream_rewind( poDS->psStream ) < 0 )
717         {
718             delete poDS;
719             CPLDebug( "JPEG2000", "Unable to rewind input stream.\n" );
720             return NULL;
721         }
722     }
723     else
724     {
725         if ( !poDS->DecodeImage() )
726         {
727             delete poDS;
728             return NULL;
729         }
730 
731         poDS->nBands = jas_image_numcmpts( poDS->psImage );
732         poDS->nRasterXSize = jas_image_cmptwidth( poDS->psImage, 0 );
733         poDS->nRasterYSize = jas_image_cmptheight( poDS->psImage, 0 );
734         paiDepth = (int *)CPLMalloc( poDS->nBands * sizeof(int) );
735         pabSignedness = (int *)CPLMalloc( poDS->nBands * sizeof(int) );
736         for ( iBand = 0; iBand < poDS->nBands; iBand++ )
737         {
738             paiDepth[iBand] = jas_image_cmptprec( poDS->psImage, iBand );
739             pabSignedness[iBand] = jas_image_cmptsgnd( poDS->psImage, iBand );
740         }
741     }
742 
743     if ( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
744          !GDALCheckBandCount(poDS->nBands, 0) )
745     {
746         CPLFree( paiDepth );
747         CPLFree( pabSignedness );
748         delete poDS;
749         return NULL;
750     }
751 
752 /* -------------------------------------------------------------------- */
753 /*      Should we promote alpha channel to 8 bits ?                     */
754 /* -------------------------------------------------------------------- */
755     poDS->bPromoteTo8Bit = (poDS->nBands == 4 &&
756                             paiDepth[0] == 8 &&
757                             paiDepth[1] == 8 &&
758                             paiDepth[2] == 8 &&
759                             paiDepth[3] == 1 &&
760                             CSLFetchBoolean(poOpenInfo->papszOpenOptions, "1BIT_ALPHA_PROMOTION", TRUE));
761     if( poDS->bPromoteTo8Bit )
762         CPLDebug( "JPEG2000",  "Fourth (alpha) band is promoted from 1 bit to 8 bit");
763 
764 /* -------------------------------------------------------------------- */
765 
766 /*      Create band information objects.                                */
767 /* -------------------------------------------------------------------- */
768 
769 
770     for( iBand = 1; iBand <= poDS->nBands; iBand++ )
771     {
772         poDS->SetBand( iBand, new JPEG2000RasterBand( poDS, iBand,
773             paiDepth[iBand - 1], pabSignedness[iBand - 1] ) );
774 
775     }
776 
777     if ( paiDepth )
778         CPLFree( paiDepth );
779     if ( pabSignedness )
780         CPLFree( pabSignedness );
781 
782     poDS->LoadJP2Metadata(poOpenInfo);
783 
784 /* -------------------------------------------------------------------- */
785 /*      Initialize any PAM information.                                 */
786 /* -------------------------------------------------------------------- */
787     poDS->SetDescription( poOpenInfo->pszFilename );
788     poDS->TryLoadXML();
789 
790 /* -------------------------------------------------------------------- */
791 /*      Check for overviews.                                            */
792 /* -------------------------------------------------------------------- */
793     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
794 
795 /* -------------------------------------------------------------------- */
796 /*      Vector layers                                                   */
797 /* -------------------------------------------------------------------- */
798     if( poOpenInfo->nOpenFlags & GDAL_OF_VECTOR )
799     {
800         poDS->LoadVectorLayers(
801             CSLFetchBoolean(poOpenInfo->papszOpenOptions, "OPEN_REMOTE_GML", FALSE));
802 
803         // If file opened in vector-only mode and there's no vector,
804         // return
805         if( (poOpenInfo->nOpenFlags & GDAL_OF_RASTER) == 0 &&
806             poDS->GetLayerCount() == 0 )
807         {
808             delete poDS;
809             return NULL;
810         }
811     }
812 
813     return( poDS );
814 }
815 
816 /************************************************************************/
817 /*                      JPEG2000CreateCopy()                            */
818 /************************************************************************/
819 
820 static GDALDataset *
JPEG2000CreateCopy(const char * pszFilename,GDALDataset * poSrcDS,int bStrict,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressData)821 JPEG2000CreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
822                     int bStrict, char ** papszOptions,
823                     GDALProgressFunc pfnProgress, void * pProgressData )
824 
825 {
826     int  nBands = poSrcDS->GetRasterCount();
827     int  nXSize = poSrcDS->GetRasterXSize();
828     int  nYSize = poSrcDS->GetRasterYSize();
829     int                 iBand;
830     GDALRasterBand      *poBand;
831 
832     if( nBands == 0 )
833     {
834         CPLError( CE_Failure, CPLE_NotSupported,
835                   "Unable to export files with zero bands." );
836         return NULL;
837     }
838 
839     if (poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)
840     {
841         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported,
842                   "JPEG2000 driver ignores color table. "
843                   "The source raster band will be considered as grey level.\n"
844                   "Consider using color table expansion (-expand option in gdal_translate)\n");
845         if (bStrict)
846             return NULL;
847     }
848 
849     for ( iBand = 0; iBand < nBands; iBand++ )
850     {
851         poBand = poSrcDS->GetRasterBand( iBand + 1);
852 
853         switch ( poBand->GetRasterDataType() )
854         {
855             case GDT_Byte:
856             case GDT_Int16:
857             case GDT_UInt16:
858                 break;
859 
860             default:
861                 if( !CSLTestBoolean(CPLGetConfigOption("JPEG2000_FORCE_CREATION", "NO")) )
862                 {
863                     CPLError(CE_Failure, CPLE_AppDefined,
864                              "A band of the source dataset is of type %s, which might cause crashes in libjasper. "
865                              "Set JPEG2000_FORCE_CREATION configuration option to YES to attempt the creation of the file.",
866                              GDALGetDataTypeName(poBand->GetRasterDataType()));
867                     return NULL;
868                 }
869                 break;
870         }
871     }
872 
873     if( !pfnProgress( 0.0, NULL, pProgressData ) )
874         return NULL;
875 
876 /* -------------------------------------------------------------------- */
877 /*      Create the dataset.                                             */
878 /* -------------------------------------------------------------------- */
879     jas_stream_t        *psStream;
880     jas_image_t         *psImage;
881 
882     JPEG2000Init();
883     const char* pszAccess = EQUALN(pszFilename, "/vsisubfile/", 12) ? "r+b" : "w+b";
884     if( !(psStream = JPEG2000_VSIL_fopen( pszFilename, pszAccess) ) )
885     {
886         CPLError( CE_Failure, CPLE_FileIO, "Unable to create file %s.\n",
887                   pszFilename );
888         return NULL;
889     }
890 
891     if ( !(psImage = jas_image_create0()) )
892     {
893         CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create image %s.\n",
894                   pszFilename );
895         return NULL;
896     }
897 
898 /* -------------------------------------------------------------------- */
899 /*      Loop over image, copying image data.                            */
900 /* -------------------------------------------------------------------- */
901     GUInt32             *paiScanline;
902     int                 iLine, iPixel;
903     CPLErr              eErr = CE_None;
904     jas_matrix_t        *psMatrix;
905     jas_image_cmptparm_t *sComps; // Array of pointers to image components
906 
907     sComps = (jas_image_cmptparm_t*)
908         CPLMalloc( nBands * sizeof(jas_image_cmptparm_t) );
909 
910     if ( !(psMatrix = jas_matrix_create( 1, nXSize )) )
911     {
912         CPLError( CE_Failure, CPLE_OutOfMemory,
913                   "Unable to create matrix with size %dx%d.\n", 1, nYSize );
914         CPLFree( sComps );
915         jas_image_destroy( psImage );
916         return NULL;
917     }
918     paiScanline = (GUInt32 *) CPLMalloc( nXSize *
919                             GDALGetDataTypeSize(GDT_UInt32) / 8 );
920 
921     for ( iBand = 0; iBand < nBands; iBand++ )
922     {
923         poBand = poSrcDS->GetRasterBand( iBand + 1);
924 
925         sComps[iBand].tlx = sComps[iBand].tly = 0;
926         sComps[iBand].hstep = sComps[iBand].vstep = 1;
927         sComps[iBand].width = nXSize;
928         sComps[iBand].height = nYSize;
929         sComps[iBand].prec = GDALGetDataTypeSize( poBand->GetRasterDataType() );
930         switch ( poBand->GetRasterDataType() )
931         {
932             case GDT_Int16:
933             case GDT_Int32:
934             case GDT_Float32:
935             case GDT_Float64:
936             sComps[iBand].sgnd = 1;
937             break;
938             case GDT_Byte:
939             case GDT_UInt16:
940             case GDT_UInt32:
941             default:
942             sComps[iBand].sgnd = 0;
943             break;
944         }
945         jas_image_addcmpt(psImage, iBand, sComps);
946 
947         for( iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
948         {
949             eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
950                               paiScanline, nXSize, 1, GDT_UInt32,
951                               sizeof(GUInt32), sizeof(GUInt32) * nXSize, NULL );
952             for ( iPixel = 0; iPixel < nXSize; iPixel++ )
953                 jas_matrix_setv( psMatrix, iPixel, paiScanline[iPixel] );
954 
955             if( (jas_image_writecmpt(psImage, iBand, 0, iLine,
956                               nXSize, 1, psMatrix)) < 0 )
957             {
958                 CPLError( CE_Failure, CPLE_AppDefined,
959                     "Unable to write scanline %d of the component %d.\n",
960                     iLine, iBand );
961                 jas_matrix_destroy( psMatrix );
962                 CPLFree( paiScanline );
963                 CPLFree( sComps );
964                 jas_image_destroy( psImage );
965                 return NULL;
966             }
967 
968             if( eErr == CE_None &&
969             !pfnProgress( ((iLine + 1) + iBand * nYSize) /
970                           ((double) nYSize * nBands),
971                          NULL, pProgressData) )
972             {
973                 eErr = CE_Failure;
974                 CPLError( CE_Failure, CPLE_UserInterrupt,
975                       "User terminated CreateCopy()" );
976             }
977         }
978     }
979 
980 /* -------------------------------------------------------------------- */
981 /*       Read compression parameters and encode the image.              */
982 /* -------------------------------------------------------------------- */
983     int             i, j;
984     const int       OPTSMAX = 4096;
985     const char      *pszFormatName;
986     char            pszOptionBuf[OPTSMAX + 1];
987 
988     const char  *apszComprOptions[]=
989     {
990         "imgareatlx",
991         "imgareatly",
992         "tilegrdtlx",
993         "tilegrdtly",
994         "tilewidth",
995         "tileheight",
996         "prcwidth",
997         "prcheight",
998         "cblkwidth",
999         "cblkheight",
1000         "mode",
1001         "rate",
1002         "ilyrrates",
1003         "prg",
1004         "numrlvls",
1005         "sop",
1006         "eph",
1007         "lazy",
1008         "termall",
1009         "segsym",
1010         "vcausal",
1011         "pterm",
1012         "resetprob",
1013         "numgbits",
1014         NULL
1015     };
1016 
1017     pszFormatName = CSLFetchNameValue( papszOptions, "FORMAT" );
1018     if ( !pszFormatName ||
1019          (!EQUALN( pszFormatName, "jp2", 3 ) &&
1020           !EQUALN( pszFormatName, "jpc", 3 ) ) )
1021         pszFormatName = "jp2";
1022 
1023     pszOptionBuf[0] = '\0';
1024     if ( papszOptions )
1025     {
1026         CPLDebug( "JPEG2000", "User supplied parameters:" );
1027         for ( i = 0; papszOptions[i] != NULL; i++ )
1028         {
1029             CPLDebug( "JPEG2000", "%s\n", papszOptions[i] );
1030             for ( j = 0; apszComprOptions[j] != NULL; j++ )
1031                 if( EQUALN( apszComprOptions[j], papszOptions[i],
1032                             strlen(apszComprOptions[j]) ) )
1033                 {
1034                     int m, n;
1035 
1036                     n = strlen( pszOptionBuf );
1037                     m = n + strlen( papszOptions[i] ) + 1;
1038                     if ( m > OPTSMAX )
1039                         break;
1040                     if ( n > 0 )
1041                     {
1042                         strcat( pszOptionBuf, "\n" );
1043                     }
1044                     strcat( pszOptionBuf, papszOptions[i] );
1045                 }
1046         }
1047     }
1048     CPLDebug( "JPEG2000", "Parameters, delivered to the JasPer library:" );
1049     CPLDebug( "JPEG2000", "%s", pszOptionBuf );
1050 
1051     if ( nBands == 1 )                      // Grayscale
1052     {
1053         jas_image_setclrspc( psImage, JAS_CLRSPC_SGRAY );
1054         jas_image_setcmpttype( psImage, 0, JAS_IMAGE_CT_GRAY_Y );
1055     }
1056     else if ( nBands == 3 || nBands == 4 )  // Assume as RGB(A)
1057     {
1058         jas_image_setclrspc( psImage, JAS_CLRSPC_SRGB );
1059         for ( iBand = 0; iBand < nBands; iBand++ )
1060         {
1061             poBand = poSrcDS->GetRasterBand( iBand + 1);
1062             switch ( poBand->GetColorInterpretation() )
1063             {
1064                 case GCI_RedBand:
1065                 jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_RGB_R );
1066                 break;
1067                 case GCI_GreenBand:
1068                 jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_RGB_G );
1069                 break;
1070                 case GCI_BlueBand:
1071                 jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_RGB_B );
1072                 break;
1073                 case GCI_AlphaBand:
1074                 jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_OPACITY );
1075                 break;
1076                 default:
1077                 jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_UNKNOWN );
1078                 break;
1079             }
1080         }
1081     }
1082     else                                    // Unknown
1083     {
1084         /* JAS_CLRSPC_UNKNOWN causes crashes in Jasper jp2_enc.c at line 231 */
1085         /* iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); */
1086         /* but if we explictely set the cmprof, it does not work better */
1087         /* since it would abort at line 281 later ... */
1088         /* So the best option is to switch to gray colorspace */
1089         /* And we need to switch at the band level too, otherwise Kakadu or */
1090         /* JP2MrSID don't like it */
1091         //jas_image_setclrspc( psImage, JAS_CLRSPC_UNKNOWN );
1092         jas_image_setclrspc( psImage, JAS_CLRSPC_SGRAY );
1093         for ( iBand = 0; iBand < nBands; iBand++ )
1094             //jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_UNKNOWN );
1095             jas_image_setcmpttype( psImage, iBand, JAS_IMAGE_CT_GRAY_Y );
1096     }
1097 
1098 /* -------------------------------------------------------------------- */
1099 /*      Set the GeoTIFF box if georeferencing is available, and this    */
1100 /*      is a JP2 file.                                                  */
1101 /* -------------------------------------------------------------------- */
1102     if ( EQUALN( pszFormatName, "jp2", 3 ) )
1103     {
1104 #ifdef HAVE_JASPER_UUID
1105         double  adfGeoTransform[6];
1106         if( CSLFetchBoolean( papszOptions, "GeoJP2", TRUE ) &&
1107             ((poSrcDS->GetGeoTransform(adfGeoTransform) == CE_None
1108                  && (adfGeoTransform[0] != 0.0
1109                      || adfGeoTransform[1] != 1.0
1110                      || adfGeoTransform[2] != 0.0
1111                      || adfGeoTransform[3] != 0.0
1112                      || adfGeoTransform[4] != 0.0
1113                      || ABS(adfGeoTransform[5]) != 1.0))
1114                 || poSrcDS->GetGCPCount() > 0
1115                 || poSrcDS->GetMetadata("RPC") != NULL ) )
1116         {
1117             GDALJP2Metadata oJP2Geo;
1118 
1119             if( poSrcDS->GetGCPCount() > 0 )
1120             {
1121                 oJP2Geo.SetProjection( poSrcDS->GetGCPProjection() );
1122                 oJP2Geo.SetGCPs( poSrcDS->GetGCPCount(), poSrcDS->GetGCPs() );
1123             }
1124             else
1125             {
1126                 oJP2Geo.SetProjection( poSrcDS->GetProjectionRef() );
1127                 oJP2Geo.SetGeoTransform( adfGeoTransform );
1128             }
1129 
1130             oJP2Geo.SetRPCMD(  poSrcDS->GetMetadata("RPC") );
1131 
1132             const char* pszAreaOrPoint = poSrcDS->GetMetadataItem(GDALMD_AREA_OR_POINT);
1133             oJP2Geo.bPixelIsPoint = pszAreaOrPoint != NULL && EQUAL(pszAreaOrPoint, GDALMD_AOP_POINT);
1134 
1135             GDALJP2Box *poBox = oJP2Geo.CreateJP2GeoTIFF();
1136             jp2_box_t  *box = jp2_box_create( JP2_BOX_UUID );
1137             memcpy( box->data.uuid.uuid, poBox->GetUUID(), 16 );
1138             box->data.uuid.datalen = poBox->GetDataLength() - 16;
1139             box->data.uuid.data =
1140                 (uint_fast8_t *)jas_malloc( poBox->GetDataLength() - 16 );
1141             memcpy( box->data.uuid.data, poBox->GetWritableData() + 16,
1142                     poBox->GetDataLength() - 16 );
1143             delete poBox;
1144             poBox = NULL;
1145 
1146             if ( jp2_encode_uuid( psImage, psStream, pszOptionBuf, box) < 0 )
1147             {
1148                 CPLError( CE_Failure, CPLE_FileIO,
1149                           "Unable to encode image %s.", pszFilename );
1150                 jp2_box_destroy( box );
1151                 jas_matrix_destroy( psMatrix );
1152                 CPLFree( paiScanline );
1153                 CPLFree( sComps );
1154                 jas_image_destroy( psImage );
1155                 return NULL;
1156             }
1157             jp2_box_destroy( box );
1158         }
1159         else
1160         {
1161 #endif
1162             if ( jp2_encode( psImage, psStream, pszOptionBuf) < 0 )
1163             {
1164                 CPLError( CE_Failure, CPLE_FileIO,
1165                           "Unable to encode image %s.", pszFilename );
1166                 jas_matrix_destroy( psMatrix );
1167                 CPLFree( paiScanline );
1168                 CPLFree( sComps );
1169                 jas_image_destroy( psImage );
1170                 return NULL;
1171             }
1172 #ifdef HAVE_JASPER_UUID
1173         }
1174 #endif
1175     }
1176     else    // Write JPC code stream
1177     {
1178         if ( jpc_encode(psImage, psStream, pszOptionBuf) < 0 )
1179         {
1180             CPLError( CE_Failure, CPLE_FileIO,
1181                       "Unable to encode image %s.\n", pszFilename );
1182             jas_matrix_destroy( psMatrix );
1183             CPLFree( paiScanline );
1184             CPLFree( sComps );
1185             jas_image_destroy( psImage );
1186             return NULL;
1187         }
1188     }
1189 
1190     jas_stream_flush( psStream );
1191 
1192     jas_matrix_destroy( psMatrix );
1193     CPLFree( paiScanline );
1194     CPLFree( sComps );
1195     jas_image_destroy( psImage );
1196     if ( jas_stream_close( psStream ) )
1197     {
1198         CPLError( CE_Failure, CPLE_FileIO, "Unable to close file %s.\n",
1199                   pszFilename );
1200         return NULL;
1201     }
1202 
1203 /* -------------------------------------------------------------------- */
1204 /*      Add GMLJP2 box at end of file.                                  */
1205 /* -------------------------------------------------------------------- */
1206     if ( EQUALN( pszFormatName, "jp2", 3 ) )
1207     {
1208         double  adfGeoTransform[6];
1209         if( CSLFetchBoolean( papszOptions, "GMLJP2", TRUE ) &&
1210             poSrcDS->GetGeoTransform(adfGeoTransform) == CE_None &&
1211             poSrcDS->GetProjectionRef() != NULL &&
1212             poSrcDS->GetProjectionRef()[0] != '\0' )
1213         {
1214             VSILFILE* fp = VSIFOpenL(pszFilename, "rb+");
1215             if( fp )
1216             {
1217                 // Look for jp2c box and patch its LBox to be the real box size
1218                 // instead of zero
1219                 int bOK = FALSE;
1220                 GUInt32   nLBox;
1221                 GUInt32   nTBox;
1222 
1223                 while(TRUE)
1224                 {
1225                     if( VSIFReadL(&nLBox, 4, 1, fp) != 1 ||
1226                         VSIFReadL(&nTBox, 4, 1, fp) != 1 )
1227                         break;
1228                     nLBox = CPL_MSBWORD32( nLBox );
1229                     if( memcmp(&nTBox, "jp2c", 4) == 0 )
1230                     {
1231                         if( nLBox >= 8 )
1232                         {
1233                             bOK = TRUE;
1234                             break;
1235                         }
1236                         if( nLBox == 0 )
1237                         {
1238                             vsi_l_offset nPos = VSIFTellL(fp);
1239                             VSIFSeekL(fp, 0, SEEK_END);
1240                             vsi_l_offset nEnd = VSIFTellL(fp);
1241                             VSIFSeekL(fp, nPos - 8, SEEK_SET);
1242                             nLBox = (GUInt32)(8 + nEnd - nPos);
1243                             if( nLBox == (vsi_l_offset)8 + nEnd - nPos )
1244                             {
1245                                 nLBox = CPL_MSBWORD32( nLBox );
1246                                 VSIFWriteL(&nLBox, 1, 4, fp);
1247                                 bOK = TRUE;
1248                             }
1249                         }
1250                         break;
1251                     }
1252                     if( nLBox < 8 )
1253                         break;
1254                     VSIFSeekL(fp, nLBox - 8, SEEK_CUR);
1255                 }
1256 
1257                 // Can write GMLJP2 box
1258                 if( bOK )
1259                 {
1260                     GDALJP2Metadata oJP2MD;
1261                     oJP2MD.SetProjection( poSrcDS->GetProjectionRef() );
1262                     oJP2MD.SetGeoTransform( adfGeoTransform );
1263                     GDALJP2Box *poBox;
1264                     const char* pszGMLJP2V2Def = CSLFetchNameValue( papszOptions, "GMLJP2V2_DEF" );
1265                     if( pszGMLJP2V2Def != NULL )
1266                         poBox = oJP2MD.CreateGMLJP2V2(nXSize,nYSize,pszGMLJP2V2Def,poSrcDS);
1267                     else
1268                         poBox = oJP2MD.CreateGMLJP2(nXSize,nYSize);
1269 
1270                     nLBox = (int) poBox->GetDataLength() + 8;
1271                     nLBox = CPL_MSBWORD32( nLBox );
1272                     memcpy(&nTBox, poBox->GetType(), 4);
1273 
1274                     VSIFSeekL(fp, 0, SEEK_END);
1275                     VSIFWriteL( &nLBox, 4, 1, fp );
1276                     VSIFWriteL( &nTBox, 4, 1, fp );
1277                     VSIFWriteL(poBox->GetWritableData(), 1, (int) poBox->GetDataLength(), fp);
1278                     VSIFCloseL(fp);
1279 
1280                     delete poBox;
1281                 }
1282             }
1283         }
1284     }
1285 
1286 /* -------------------------------------------------------------------- */
1287 /*      Do we need a world file?                                        */
1288 /* -------------------------------------------------------------------- */
1289     if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) )
1290     {
1291         double      adfGeoTransform[6];
1292 
1293         poSrcDS->GetGeoTransform( adfGeoTransform );
1294         GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform );
1295     }
1296 
1297 /* -------------------------------------------------------------------- */
1298 /*      Re-open dataset, and copy any auxiliary pam information.         */
1299 /* -------------------------------------------------------------------- */
1300     GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly);
1301     GDALPamDataset *poDS = (GDALPamDataset*) JPEG2000Dataset::Open(&oOpenInfo);
1302 
1303     if( poDS )
1304     {
1305         poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT & (~GCIF_METADATA) );
1306 
1307         /* Only write relevant metadata to PAM, and if needed */
1308         char** papszSrcMD = CSLDuplicate(poSrcDS->GetMetadata());
1309         papszSrcMD = CSLSetNameValue(papszSrcMD, GDALMD_AREA_OR_POINT, NULL);
1310         papszSrcMD = CSLSetNameValue(papszSrcMD, "Corder", NULL);
1311         for(char** papszSrcMDIter = papszSrcMD;
1312                 papszSrcMDIter && *papszSrcMDIter; )
1313         {
1314             /* Remove entries like KEY= (without value) */
1315             if( (*papszSrcMDIter)[0] &&
1316                 (*papszSrcMDIter)[strlen((*papszSrcMDIter))-1] == '=' )
1317             {
1318                 CPLFree(*papszSrcMDIter);
1319                 memmove(papszSrcMDIter, papszSrcMDIter + 1,
1320                         sizeof(char*) * (CSLCount(papszSrcMDIter + 1) + 1));
1321             }
1322             else
1323                 ++papszSrcMDIter;
1324         }
1325         char** papszMD = CSLDuplicate(poDS->GetMetadata());
1326         papszMD = CSLSetNameValue(papszMD, GDALMD_AREA_OR_POINT, NULL);
1327         if( papszSrcMD && papszSrcMD[0] != NULL &&
1328             CSLCount(papszSrcMD) != CSLCount(papszMD) )
1329         {
1330             poDS->SetMetadata(papszSrcMD);
1331         }
1332         CSLDestroy(papszSrcMD);
1333         CSLDestroy(papszMD);
1334     }
1335 
1336     return poDS;
1337 }
1338 
1339 /************************************************************************/
1340 /*                        GDALRegister_JPEG2000()                       */
1341 /************************************************************************/
1342 
GDALRegister_JPEG2000()1343 void GDALRegister_JPEG2000()
1344 
1345 {
1346     GDALDriver  *poDriver;
1347 
1348     if (! GDAL_CHECK_VERSION("JPEG2000 driver"))
1349         return;
1350 
1351     if( GDALGetDriverByName( "JPEG2000" ) == NULL )
1352     {
1353         poDriver = new GDALDriver();
1354 
1355         poDriver->SetDescription( "JPEG2000" );
1356         poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
1357         poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
1358         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
1359                                    "JPEG-2000 part 1 (ISO/IEC 15444-1), based on Jasper library" );
1360         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
1361                                    "frmt_jpeg2000.html" );
1362         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES,
1363                                    "Byte Int16 UInt16 Int32 UInt32" );
1364         poDriver->SetMetadataItem( GDAL_DMD_MIMETYPE, "image/jp2" );
1365         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "jp2" );
1366 
1367         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
1368 
1369         poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST,
1370 "<OpenOptionList>"
1371 "   <Option name='1BIT_ALPHA_PROMOTION' type='boolean' description='Whether a 1-bit alpha channel should be promoted to 8-bit' default='YES'/>"
1372 "   <Option name='OPEN_REMOTE_GML' type='boolean' description='Whether to load remote vector layers referenced by a link in a GMLJP2 v2 box' default='NO'/>"
1373 "</OpenOptionList>" );
1374 
1375         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
1376 "<CreationOptionList>"
1377 "   <Option name='FORMAT' type='string-select' default='according to file extension. If unknown, default to J2K'>"
1378 "       <Value>JP2</Value>"
1379 "       <Value>JPC</Value>"
1380 "   </Option>"
1381 "   <Option name='GeoJP2' type='boolean' description='Whether to emit a GeoJP2 box' default='YES'/>"
1382 "   <Option name='GMLJP2' type='boolean' description='Whether to emit a GMLJP2 v1 box' default='YES'/>"
1383 "   <Option name='GMLJP2V2_DEF' type='string' description='Definition file to describe how a GMLJP2 v2 box should be generated. If set to YES, a minimal instance will be created'/>"
1384 "   <Option name='WORLDFILE' type='boolean' description='Whether to write a worldfile .wld' default='NO'/>"
1385 "   <Option name='imgareatlx' type='string' />"
1386 "   <Option name='imgareatly' type='string' />"
1387 "   <Option name='tilegrdtlx' type='string' />"
1388 "   <Option name='tilegrdtly' type='string' />"
1389 "   <Option name='tilewidth' type='string' />"
1390 "   <Option name='tileheight' type='string' />"
1391 "   <Option name='prcwidth' type='string' />"
1392 "   <Option name='prcheight' type='string' />"
1393 "   <Option name='cblkwidth' type='string' />"
1394 "   <Option name='cblkheight' type='string' />"
1395 "   <Option name='mode' type='string' />"
1396 "   <Option name='rate' type='string' />"
1397 "   <Option name='ilyrrates' type='string' />"
1398 "   <Option name='prg' type='string' />"
1399 "   <Option name='numrlvls' type='string' />"
1400 "   <Option name='sop' type='string' />"
1401 "   <Option name='eph' type='string' />"
1402 "   <Option name='lazy' type='string' />"
1403 "   <Option name='termall' type='string' />"
1404 "   <Option name='segsym' type='string' />"
1405 "   <Option name='vcausal' type='string' />"
1406 "   <Option name='pterm' type='string' />"
1407 "   <Option name='resetprob' type='string' />"
1408 "   <Option name='numgbits' type='string' />"
1409 "</CreationOptionList>"  );
1410 
1411         poDriver->pfnIdentify = JPEG2000Dataset::Identify;
1412         poDriver->pfnOpen = JPEG2000Dataset::Open;
1413         poDriver->pfnCreateCopy = JPEG2000CreateCopy;
1414 
1415         GetGDALDriverManager()->RegisterDriver( poDriver );
1416     }
1417 }
1418 
1419