Line data Source code
1 : #ifndef __STDC_LIMIT_MACROS
2 : // Needed on RHEL 6 for SIZE_MAX availability, needed by Jasper
3 : #define __STDC_LIMIT_MACROS 1
4 : #endif
5 :
6 : #include "cpl_port.h"
7 :
8 : #include <stdio.h>
9 : #include <stdlib.h>
10 : #include <string.h>
11 :
12 : #include "gdal_pam.h"
13 : #include "cpl_conv.h"
14 :
15 : CPL_C_START
16 : #include "grib2.h"
17 : CPL_C_END
18 :
19 15 : int dec_jpeg2000(const void *injpc,g2int bufsize,g2int **outfld,g2int outpixels)
20 : /*$$$ SUBPROGRAM DOCUMENTATION BLOCK
21 : * . . . .
22 : * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream
23 : * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02
24 : *
25 : * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the
26 : * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using a GDAL JPEG2000
27 : * capable driver.
28 : *
29 : * PROGRAM HISTORY LOG:
30 : * 2002-12-02 Gilbert
31 : *
32 : * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld)
33 : *
34 : * INPUT ARGUMENTS:
35 : * injpc - Input JPEG2000 code stream.
36 : * bufsize - Length (in bytes) of the input JPEG2000 code stream.
37 : *
38 : * OUTPUT ARGUMENTS:
39 : * outfld - Output matrix of grayscale image values.
40 : *
41 : * RETURN VALUES :
42 : * 0 = Successful decode
43 : * -3 = Error decode jpeg2000 code stream.
44 : * -5 = decoded image had multiple color components.
45 : * Only grayscale is expected.
46 :
47 : * ATTRIBUTES:
48 : * LANGUAGE: C
49 : * MACHINE: IBM SP
50 : *
51 : *$$$*/
52 :
53 : {
54 : // create "memory file" from buffer
55 : const CPLString osFileName(
56 30 : VSIMemGenerateHiddenFilename("temp_grib.jpc"));
57 :
58 15 : VSIFCloseL( VSIFileFromMemBuffer(
59 : osFileName, (unsigned char*)injpc, bufsize,
60 : FALSE ) ); // TRUE to let vsi delete the buffer when done
61 :
62 : // Open memory buffer for reading
63 15 : const char* const apszAllowedDrivers[] = {"JP2KAK", "JP2ECW", "JP2MRSID", "JP2GROK", "JP2OPENJPEG", nullptr };
64 : auto poJ2KDataset = std::unique_ptr<GDALDataset>(
65 30 : GDALDataset::Open(osFileName, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, apszAllowedDrivers ));
66 :
67 15 : if( poJ2KDataset == nullptr )
68 : {
69 0 : fprintf(stderr, "dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n"
70 : "Is the JPEG2000 driver available?" );
71 0 : VSIUnlink( osFileName );
72 0 : return -3;
73 : }
74 :
75 15 : if( poJ2KDataset->GetRasterCount() != 1 )
76 : {
77 0 : fprintf(stderr, "dec_jpeg2000: Found color image. Grayscale expected.\n");
78 0 : VSIUnlink( osFileName );
79 0 : return (-5);
80 : }
81 :
82 : // Fulfill administration: initialize parameters required for RasterIO
83 15 : const int nXSize = poJ2KDataset->GetRasterXSize();
84 15 : const int nYSize = poJ2KDataset->GetRasterYSize();
85 : // Do not test strict equality, since there are cases where the image
86 : // is actually smaller than the requested number of pixels
87 15 : if( nYSize == 0 || nXSize > outpixels / nYSize )
88 : {
89 0 : fprintf(stderr, "dec_jpeg2000: Image contains %ld pixels > %d.\n",
90 0 : (long)nXSize * nYSize, outpixels);
91 0 : VSIUnlink( osFileName );
92 0 : return (-5);
93 : }
94 : // But on the other side if the image is much smaller than it is suspicious
95 15 : if( nXSize < outpixels / nYSize / 100 )
96 : {
97 0 : fprintf(stderr, "dec_jpeg2000: Image contains %ld pixels << %d.\n",
98 0 : (long)nXSize * nYSize, outpixels);
99 0 : VSIUnlink( osFileName );
100 0 : return (-5);
101 : }
102 15 : *outfld=(g2int *)calloc(outpixels,sizeof(g2int));
103 15 : if ( *outfld == nullptr ) {
104 0 : fprintf(stderr, "Could not allocate space in jpcunpack.\n"
105 : "Data field NOT unpacked.\n");
106 0 : VSIUnlink( osFileName );
107 0 : return(-5);
108 : }
109 15 : int nXOff = 0;
110 15 : int nYOff = 0;
111 15 : int nBufXSize = nXSize;
112 15 : int nBufYSize = nYSize;
113 15 : GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int*
114 15 : int nBandCount = 1;
115 15 : int* panBandMap = nullptr;
116 15 : int nPixelSpace = 0;
117 15 : int nLineSpace = 0;
118 15 : int nBandSpace = 0;
119 :
120 : // Decompress the JPEG2000 into the output integer array.
121 15 : const CPLErr eErr = poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize,
122 : *outfld, nBufXSize, nBufYSize, eBufType,
123 : nBandCount, panBandMap,
124 : nPixelSpace, nLineSpace, nBandSpace, nullptr );
125 :
126 : // close source file, and "unlink" it.
127 15 : poJ2KDataset.reset();
128 15 : VSIUnlink( osFileName );
129 :
130 15 : return (eErr == CE_None) ? 0 : -3;
131 : }
|