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 : GDALDataset* poJ2KDataset = (GDALDataset *) 64 15 : GDALOpen( osFileName, GA_ReadOnly ); 65 : 66 15 : if( poJ2KDataset == nullptr ) 67 : { 68 0 : fprintf(stderr, "dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n" 69 : "Is the JPEG2000 driver available?" ); 70 0 : VSIUnlink( osFileName ); 71 0 : return -3; 72 : } 73 : 74 15 : if( poJ2KDataset->GetRasterCount() != 1 ) 75 : { 76 0 : fprintf(stderr, "dec_jpeg2000: Found color image. Grayscale expected.\n"); 77 0 : GDALClose( poJ2KDataset ); 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 : GDALClose( poJ2KDataset ); 92 0 : VSIUnlink( osFileName ); 93 0 : return (-5); 94 : } 95 : // But on the other side if the image is much smaller than it is suspicious 96 15 : if( nXSize < outpixels / nYSize / 100 ) 97 : { 98 0 : fprintf(stderr, "dec_jpeg2000: Image contains %ld pixels << %d.\n", 99 0 : (long)nXSize * nYSize, outpixels); 100 0 : GDALClose( poJ2KDataset ); 101 0 : VSIUnlink( osFileName ); 102 0 : return (-5); 103 : } 104 15 : *outfld=(g2int *)calloc(outpixels,sizeof(g2int)); 105 15 : if ( *outfld == nullptr ) { 106 0 : fprintf(stderr, "Could not allocate space in jpcunpack.\n" 107 : "Data field NOT unpacked.\n"); 108 0 : GDALClose( poJ2KDataset ); 109 0 : VSIUnlink( osFileName ); 110 0 : return(-5); 111 : } 112 15 : int nXOff = 0; 113 15 : int nYOff = 0; 114 15 : int nBufXSize = nXSize; 115 15 : int nBufYSize = nYSize; 116 15 : GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int* 117 15 : int nBandCount = 1; 118 15 : int* panBandMap = nullptr; 119 15 : int nPixelSpace = 0; 120 15 : int nLineSpace = 0; 121 15 : int nBandSpace = 0; 122 : 123 : // Decompress the JPEG2000 into the output integer array. 124 15 : const CPLErr eErr = poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize, 125 : *outfld, nBufXSize, nBufYSize, eBufType, 126 : nBandCount, panBandMap, 127 : nPixelSpace, nLineSpace, nBandSpace, nullptr ); 128 : 129 : // close source file, and "unlink" it. 130 15 : GDALClose( poJ2KDataset ); 131 15 : VSIUnlink( osFileName ); 132 : 133 15 : return (eErr == CE_None) ? 0 : -3; 134 : }