| 10 | | |
|---|
| | 16 | #endif /* USE_JPEG2000_J2KSUBFILE */ |
|---|
| | 17 | |
|---|
| | 18 | #ifdef __cplusplus |
|---|
| | 19 | extern "C" { |
|---|
| | 20 | #endif /* __cplusplus */ |
|---|
| | 21 | |
|---|
| | 22 | #ifdef USE_JPEG2000_J2KSUBFILE |
|---|
| | 23 | |
|---|
| | 24 | #define J2K_SIGNATURE 0x6a502020 /* Signature, string "jP " */ |
|---|
| | 25 | #define FILE_TYPE 0x66747970 /* File Type, string "ftyp" */ |
|---|
| | 26 | #define J2K_CODESTREAM 0x6a703263 /* Code Stream, string "jp2c" */ |
|---|
| | 27 | #define MAGIC_NUMBER 0x0d0a870a /* Magic number */ |
|---|
| | 28 | #define MAJOR_VERSION 0x6a703220 /* Major version, string "jp2 " */ |
|---|
| | 29 | #define MINOR_VERSION 0 |
|---|
| | 30 | |
|---|
| | 31 | void writeChar(char c, char** buf) |
|---|
| | 32 | { |
|---|
| | 33 | **buf = c; |
|---|
| | 34 | ++(*buf); |
|---|
| | 35 | } |
|---|
| | 36 | |
|---|
| | 37 | void writeUInt32(g2intu i, char **buf) |
|---|
| | 38 | { |
|---|
| | 39 | writeChar((i >> 24) & 0xff, buf); |
|---|
| | 40 | writeChar((i >> 16) & 0xff, buf); |
|---|
| | 41 | writeChar((i >> 8) & 0xff, buf); |
|---|
| | 42 | writeChar(i & 0xff, buf); |
|---|
| | 43 | } |
|---|
| | 44 | |
|---|
| | 45 | void writeJ2KHeaders(char* buf) |
|---|
| | 46 | { |
|---|
| | 47 | // signature box |
|---|
| | 48 | writeUInt32(12, &buf); // size = 12 bytes: 4 size, 4 type, 4 magic |
|---|
| | 49 | writeUInt32(J2K_SIGNATURE, &buf); |
|---|
| | 50 | writeUInt32(MAGIC_NUMBER, &buf); |
|---|
| | 51 | |
|---|
| | 52 | // file type box |
|---|
| | 53 | writeUInt32(20, &buf); // size = 20 bytes: 4 size, 4 type, 4 majver, 4 minver, 4 compatibility code |
|---|
| | 54 | writeUInt32(FILE_TYPE, &buf); |
|---|
| | 55 | writeUInt32(MAJOR_VERSION, &buf); |
|---|
| | 56 | writeUInt32(MINOR_VERSION, &buf); |
|---|
| | 57 | writeUInt32(MAJOR_VERSION, &buf); // repeat majver as "compatibility code" |
|---|
| | 58 | |
|---|
| | 59 | // code stream box: j2k_data follows |
|---|
| | 60 | writeUInt32(0, &buf); // size = 0 means rest of buffer contains j2k_data |
|---|
| | 61 | writeUInt32(J2K_CODESTREAM, &buf); |
|---|
| | 62 | } |
|---|
| | 63 | |
|---|
| | 64 | #endif /* USE_JPEG2000_J2KSUBFILE */ |
|---|
| | 107 | |
|---|
| | 108 | #ifdef USE_JPEG2000_J2KSUBFILE |
|---|
| | 109 | |
|---|
| | 110 | // J2K_SUBFILE method |
|---|
| | 111 | |
|---|
| | 112 | // Specifically ECW needs a few JP2 headers (the so-called "boxes") .. prepend them to the memory buffer |
|---|
| | 113 | // Does Kakadu need them as well? |
|---|
| | 114 | const int headersize = 40; // 40 bytes of headers will be prepended |
|---|
| | 115 | char* jpcbuf = injpc; // remember old buffer |
|---|
| | 116 | injpc = (char*)malloc(bufsize + headersize); // old buffer is too small, thus allocate new buffer |
|---|
| | 117 | writeJ2KHeaders(injpc); // write out the 40 header bytes |
|---|
| | 118 | memcpy(injpc + headersize, jpcbuf, bufsize); // append the jpeg2000 data |
|---|
| | 119 | |
|---|
| | 120 | // create "memory file" from buffer |
|---|
| | 121 | int fileNumber = 0; |
|---|
| | 122 | VSIStatBufL sStatBuf; |
|---|
| | 123 | char *pszFileName = CPLStrdup( "/vsimem/work.jp2" ); |
|---|
| | 124 | |
|---|
| | 125 | // ensure we don't overwrite an existing file accidentally |
|---|
| | 126 | while ( VSIStatL( pszFileName, &sStatBuf ) == 0 ) { |
|---|
| | 127 | CPLFree( pszFileName ); |
|---|
| | 128 | pszFileName = CPLStrdup( CPLSPrintf( "/vsimem/work%d.jp2", ++fileNumber ) ); |
|---|
| | 129 | } |
|---|
| | 130 | |
|---|
| | 131 | VSIFCloseL( VSIFileFromMemBuffer( pszFileName, (unsigned char*)injpc, bufsize + headersize, TRUE ) ); // TRUE to let vsi delete the buffer when done |
|---|
| | 132 | |
|---|
| | 133 | // Open it with a JPEG2000 driver supporting J2K_SUBFILE |
|---|
| | 134 | char *pszDSName = CPLStrdup( CPLSPrintf( "J2K_SUBFILE:%d,%d,%s", 0, bufsize, pszFileName ) ); |
|---|
| | 135 | |
|---|
| | 136 | // Open memory buffer for reading |
|---|
| | 137 | GDALDataset* poJ2KDataset = (GDALDataset *)GDALOpen( pszDSName, GA_ReadOnly ); // This goes to CNCSJP2FileView |
|---|
| | 138 | //GDALDataset* poJ2KDataset = (GDALDataset *)GDALOpen( "/vsimem/work.jp2", GA_ReadOnly ); // This goes to CNCSJP2File, and fails |
|---|
| | 139 | |
|---|
| | 140 | if( poJ2KDataset == NULL ) |
|---|
| | 141 | { |
|---|
| | 142 | printf("dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n" |
|---|
| | 143 | "Is the JPEG2000 driver available?" ); |
|---|
| | 144 | return -3; |
|---|
| | 145 | } |
|---|
| | 146 | |
|---|
| | 147 | if( poJ2KDataset->GetRasterCount() != 1 ) |
|---|
| | 148 | { |
|---|
| | 149 | printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); |
|---|
| | 150 | return (-5); |
|---|
| | 151 | } |
|---|
| | 152 | |
|---|
| | 153 | GDALRasterBand *poBand = poJ2KDataset->GetRasterBand(1); |
|---|
| | 154 | |
|---|
| | 155 | // Fulfill administration: initialize parameters required for RasterIO |
|---|
| | 156 | int nXSize = poJ2KDataset->GetRasterXSize(); |
|---|
| | 157 | int nYSize = poJ2KDataset->GetRasterYSize(); |
|---|
| | 158 | int nXOff = 0; |
|---|
| | 159 | int nYOff = 0; |
|---|
| | 160 | int nBufXSize = nXSize; |
|---|
| | 161 | int nBufYSize = nYSize; |
|---|
| | 162 | GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int* |
|---|
| | 163 | int nBandCount = 1; |
|---|
| | 164 | int* panBandMap = NULL; |
|---|
| | 165 | int nPixelSpace = 0; |
|---|
| | 166 | int nLineSpace = 0; |
|---|
| | 167 | int nBandSpace = 0; |
|---|
| | 168 | |
|---|
| | 169 | // Decompress the JPEG2000 into the output integer array. |
|---|
| | 170 | poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize, |
|---|
| | 171 | outfld, nBufXSize, nBufYSize, eBufType, |
|---|
| | 172 | nBandCount, panBandMap, |
|---|
| | 173 | nPixelSpace, nLineSpace, nBandSpace ); |
|---|
| | 174 | |
|---|
| | 175 | // close source file, and "unlink" it. |
|---|
| | 176 | GDALClose( poJ2KDataset ); |
|---|
| | 177 | VSIUnlink( pszFileName ); |
|---|
| | 178 | |
|---|
| | 179 | CPLFree( pszDSName ); |
|---|
| | 180 | CPLFree( pszFileName ); |
|---|
| | 181 | |
|---|
| | 182 | return 0; |
|---|
| | 183 | |
|---|
| | 184 | #else /* USE_JPEG2000_J2KSUBFILE */ |
|---|
| | 185 | |
|---|
| | 186 | // JasPer method |
|---|
| | 187 | |
|---|