static SEXP GDALColorTable2Matrix(GDALColorTableH ctab) { installErrorHandler(); int ncol = GDALGetColorEntryCount(ctab); uninstallErrorHandlerAndTriggerError(); SEXP cmat = allocMatrix(INTSXP, ncol, 4); installErrorHandler(); for (int i = 0; i < ncol; ++i) { const GDALColorEntry* ce = GDALGetColorEntry(ctab, i); INTEGER(cmat)[i] = static_cast<int>(ce->c1); INTEGER(cmat)[i + ncol] = static_cast<int>(ce->c2); INTEGER(cmat)[i + 2 * ncol] = static_cast<int>(ce->c3); INTEGER(cmat)[i + 3 * ncol] = static_cast<int>(ce->c4); } uninstallErrorHandlerAndTriggerError(); return(cmat); }
GByte * gdal_to_rgba( GDALDatasetH hDS ) { int nXSize, nYSize; GByte *pabyRGBABuf = NULL; /* validation of input parameters */ g_return_val_if_fail( hDS != NULL, NULL ); /* -------------------------------------------------------------------- */ /* Allocate RGBA Raster buffer. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); CPLDebug( "OpenEV", "creating buffer of (%d,%d)", nXSize, nYSize ); pabyRGBABuf = (GByte *) CPLMalloc( nXSize * nYSize * 4 ); /* -------------------------------------------------------------------- */ /* Handle case where source is already presumed to be RGBA. */ /* -------------------------------------------------------------------- */ if( GDALGetRasterCount(hDS) == 4 ) { GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+0, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 2 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+1, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 3 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+2, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 4 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+3, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); } /* -------------------------------------------------------------------- */ /* Source is RGB. Set Alpha to 255. */ /* -------------------------------------------------------------------- */ else if( GDALGetRasterCount(hDS) == 3 ) { memset( pabyRGBABuf, 255, 4 * nXSize * nYSize ); GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+0, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 2 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+1, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 3 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+2, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); } /* -------------------------------------------------------------------- */ /* Source is pseudocolored. Load and then convert to RGBA. */ /* -------------------------------------------------------------------- */ else if( GDALGetRasterCount(hDS) == 1 && GDALGetRasterColorTable( GDALGetRasterBand( hDS, 1 )) != NULL ) { int i; GDALColorTableH hTable; GByte abyPCT[1024]; /* Load color table, and produce 256 entry table to RGBA. */ hTable = GDALGetRasterColorTable( GDALGetRasterBand( hDS, 1 ) ); for( i = 0; i < MIN(256,GDALGetColorEntryCount( hTable )); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); abyPCT[i*4+0] = sEntry.c1; abyPCT[i*4+1] = sEntry.c2; abyPCT[i*4+2] = sEntry.c3; abyPCT[i*4+3] = sEntry.c4; } /* Fill in any missing colors with greyscale. */ for( i = GDALGetColorEntryCount( hTable ); i < 256; i++ ) { abyPCT[i*4+0] = i; abyPCT[i*4+1] = i; abyPCT[i*4+2] = i; abyPCT[i*4+3] = 255; } /* Read indexed raster */ GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+0, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); /* Convert to RGBA using palette. */ for( i = nXSize * nYSize - 1; i >= 0; i-- ) { memcpy( pabyRGBABuf + i*4, abyPCT + pabyRGBABuf[i*4]*4, 4 ); } } /* -------------------------------------------------------------------- */ /* Source band is greyscale. Load it into Red, Green and Blue. */ /* -------------------------------------------------------------------- */ else if( GDALGetRasterCount(hDS) == 1 ) { memset( pabyRGBABuf, 255, 4 * nXSize * nYSize ); GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+0, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+1, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); GDALRasterIO( GDALGetRasterBand( hDS, 1 ), GF_Read, 0, 0, nXSize, nYSize, pabyRGBABuf+2, nXSize, nYSize, GDT_Byte, 4, nXSize * 4 ); } return pabyRGBABuf; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE; if( !GDALBridgeInitialize( "..", stderr ) ) { fprintf( stderr, "Unable to intiailize GDAL bridge.\n" ); exit( 10 ); } if( argc > 1 && strcmp(argv[1],"-mm") == 0 ) { bComputeMinMax = TRUE; argv++; } GDALAllRegister(); hDataset = GDALOpen( argv[1], GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( GDALGetGCPCount( hDataset ) > 0 ) { printf( "GCP Projection = %s\n", GDALGetGCPProjection(hDataset) ); for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%g,%g) -> (%g,%g,%g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( papszMetadata != NULL ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata; int nBlockXSize, nBlockYSize; hBand = GDALGetRasterBand( hDataset, iBand+1 ); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%d, ColorInterp=%d\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetRasterDataType(hBand), GDALGetRasterColorInterpretation(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); printf( " Min=%.3f/%d, Max=%.3f/%d", dfMin, bGotMin, dfMax, bGotMax); if( bComputeMinMax ) { GDALComputeRasterMinMax( hBand, TRUE, adfCMinMax ); printf( ", Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } printf( "\n" ); dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } papszMetadata = GDALGetMetadata( hBand, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex ) { GDALColorTableH hTable; int i; hTable = GDALGetRasterColorTable( hBand ); printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } GDALClose( hDataset ); exit( 0 ); }
/** * @param theBandNumber the number of the band for which you want a color table * @param theList a pointer the object that will hold the color table * @return true of a color table was able to be read, false otherwise */ QList<QgsColorRampShader::ColorRampItem> QgsGdalProviderBase::colorTable( GDALDatasetH gdalDataset, int theBandNumber )const { QgsDebugMsg( "entered." ); QList<QgsColorRampShader::ColorRampItem> ct; //Invalid band number, segfault prevention if ( 0 >= theBandNumber ) { QgsDebugMsg( "Invalid parameter" ); return ct; } GDALRasterBandH myGdalBand = GDALGetRasterBand( gdalDataset, theBandNumber ); GDALColorTableH myGdalColorTable = GDALGetRasterColorTable( myGdalBand ); if ( myGdalColorTable ) { QgsDebugMsg( "Color table found" ); // load category labels char ** categoryNames = GDALGetRasterCategoryNames( myGdalBand ); QVector<QString> labels; if ( categoryNames ) { int i = 0; while ( categoryNames[i] ) { labels.append( QString( categoryNames[i] ) ); i++; } } int myEntryCount = GDALGetColorEntryCount( myGdalColorTable ); GDALColorInterp myColorInterpretation = GDALGetRasterColorInterpretation( myGdalBand ); QgsDebugMsg( "Color Interpretation: " + QString::number(( int )myColorInterpretation ) ); GDALPaletteInterp myPaletteInterpretation = GDALGetPaletteInterpretation( myGdalColorTable ); QgsDebugMsg( "Palette Interpretation: " + QString::number(( int )myPaletteInterpretation ) ); const GDALColorEntry* myColorEntry = 0; for ( int myIterator = 0; myIterator < myEntryCount; myIterator++ ) { myColorEntry = GDALGetColorEntry( myGdalColorTable, myIterator ); if ( !myColorEntry ) { continue; } else { QString label = labels.value( myIterator ); if ( label.isEmpty() ) { label = QString::number( myIterator ); } //Branch on the color interpretation type if ( myColorInterpretation == GCI_GrayIndex ) { QgsColorRampShader::ColorRampItem myColorRampItem; myColorRampItem.value = ( double )myIterator; myColorRampItem.label = label; myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 ); ct.append( myColorRampItem ); } else if ( myColorInterpretation == GCI_PaletteIndex ) { QgsColorRampShader::ColorRampItem myColorRampItem; myColorRampItem.value = ( double )myIterator; myColorRampItem.label = label; //Branch on palette interpretation if ( myPaletteInterpretation == GPI_RGB ) { myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 ); } else if ( myPaletteInterpretation == GPI_CMYK ) { myColorRampItem.color = QColor::fromCmyk( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 ); } else if ( myPaletteInterpretation == GPI_HLS ) { myColorRampItem.color = QColor::fromHsv( myColorEntry->c1, myColorEntry->c3, myColorEntry->c2, myColorEntry->c4 ); } else { myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 ); } ct.append( myColorRampItem ); } else { QgsDebugMsg( "Color interpretation type not supported yet" ); return ct; } } } } else { QgsDebugMsg( "No color table found for band " + QString::number( theBandNumber ) ); return ct; } QgsDebugMsg( "Color table loaded successfully" ); return ct; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE, bSample = FALSE; int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE; int bStats = FALSE, bApproxStats = TRUE, iMDD; int bShowColorTable = TRUE, bComputeChecksum = FALSE; int bReportHistograms = FALSE; const char *pszFilename = NULL; char **papszExtraMDDomains = NULL, **papszFileList; const char *pszProjection = NULL; OGRCoordinateTransformationH hTransform = NULL; /* Check that we are running against at least GDAL 1.5 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") ) { CPLSetConfigOption( argv[i+1], argv[i+2] ); i += 2; } } GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i], "-mm") ) bComputeMinMax = TRUE; else if( EQUAL(argv[i], "-hist") ) bReportHistograms = TRUE; else if( EQUAL(argv[i], "-stats") ) { bStats = TRUE; bApproxStats = FALSE; } else if( EQUAL(argv[i], "-approx_stats") ) { bStats = TRUE; bApproxStats = TRUE; } else if( EQUAL(argv[i], "-sample") ) bSample = TRUE; else if( EQUAL(argv[i], "-checksum") ) bComputeChecksum = TRUE; else if( EQUAL(argv[i], "-nogcp") ) bShowGCPs = FALSE; else if( EQUAL(argv[i], "-nomd") ) bShowMetadata = FALSE; else if( EQUAL(argv[i], "-norat") ) bShowRAT = FALSE; else if( EQUAL(argv[i], "-noct") ) bShowColorTable = FALSE; else if( EQUAL(argv[i], "-mdd") && i < argc-1 ) papszExtraMDDomains = CSLAddString( papszExtraMDDomains, argv[++i] ); else if( argv[i][0] == '-' ) Usage(); else if( pszFilename == NULL ) pszFilename = argv[i]; else Usage(); } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpen( pszFilename, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "gdalinfo failed - unable to open '%s'.\n", pszFilename ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); papszFileList = GDALGetFileList( hDataset ); if( CSLCount(papszFileList) == 0 ) { printf( "Files: none associated\n" ); } else { printf( "Files: %s\n", papszFileList[0] ); for( i = 1; papszFileList[i] != NULL; i++ ) printf( " %s\n", papszFileList[i] ); } CSLDestroy( papszFileList ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ) { printf( "Origin = (%.15f,%.15f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.15f,%.15f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } else printf( "GeoTransform =\n" " %.16g, %.16g, %.16g\n" " %.16g, %.16g, %.16g\n", adfGeoTransform[0], adfGeoTransform[1], adfGeoTransform[2], adfGeoTransform[3], adfGeoTransform[4], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 ) { if (GDALGetGCPProjection(hDataset) != NULL) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetGCPProjection( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "GCP Projection = \n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "GCP Projection = %s\n", GDALGetGCPProjection( hDataset ) ); OSRDestroySpatialReference( hSRS ); } for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } for( iMDD = 0; bShowMetadata && iMDD < CSLCount(papszExtraMDDomains); iMDD++ ) { papszMetadata = GDALGetMetadata( hDataset, papszExtraMDDomains[iMDD] ); if( CSLCount(papszMetadata) > 0 ) { printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } } /* -------------------------------------------------------------------- */ /* Report "IMAGE_STRUCTURE" metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( CSLCount(papszMetadata) > 0 ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report geolocation. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "GEOLOCATION" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Geolocation:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report RPCs */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "RPC" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "RPC Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Setup projected to lat/long transform if appropriate. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) pszProjection = GDALGetProjectionRef(hDataset); if( pszProjection != NULL && strlen(pszProjection) > 0 ) { OGRSpatialReferenceH hProj, hLatLong = NULL; hProj = OSRNewSpatialReference( pszProjection ); if( hProj != NULL ) hLatLong = OSRCloneGeogCS( hProj ); if( hLatLong != NULL ) { CPLPushErrorHandler( CPLQuietErrorHandler ); hTransform = OCTNewCoordinateTransformation( hProj, hLatLong ); CPLPopErrorHandler(); OSRDestroySpatialReference( hLatLong ); } if( hProj != NULL ) OSRDestroySpatialReference( hProj ); } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, hTransform, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, hTransform, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, hTransform, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); if( hTransform != NULL ) { OCTDestroyCoordinateTransformation( hTransform ); hTransform = NULL; } /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata, bSuccess; int nBlockXSize, nBlockYSize, nMaskFlags; double dfMean, dfStdDev; GDALColorTableH hTable; CPLErr eErr; hBand = GDALGetRasterBand( hDataset, iBand+1 ); if( bSample ) { float afSample[10000]; int nCount; nCount = GDALGetRandomRasterSample( hBand, 10000, afSample ); printf( "Got %d samples.\n", nCount ); } GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetDataTypeName( GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); if( GDALGetDescription( hBand ) != NULL && strlen(GDALGetDescription( hBand )) > 0 ) printf( " Description = %s\n", GDALGetDescription(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); if( bGotMin || bGotMax || bComputeMinMax ) { printf( " " ); if( bGotMin ) printf( "Min=%.3f ", dfMin ); if( bGotMax ) printf( "Max=%.3f ", dfMax ); if( bComputeMinMax ) { CPLErrorReset(); GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax ); if (CPLGetLastErrorType() == CE_None) { printf( " Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } } printf( "\n" ); } eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats, &dfMin, &dfMax, &dfMean, &dfStdDev ); if( eErr == CE_None ) { printf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n", dfMin, dfMax, dfMean, dfStdDev ); } if( bReportHistograms ) { int nBucketCount, *panHistogram = NULL; eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, &nBucketCount, &panHistogram, TRUE, GDALTermProgress, NULL ); if( eErr == CE_None ) { int iBucket; printf( " %d buckets from %g to %g:\n ", nBucketCount, dfMin, dfMax ); for( iBucket = 0; iBucket < nBucketCount; iBucket++ ) printf( "%d ", panHistogram[iBucket] ); printf( "\n" ); CPLFree( panHistogram ); } } if ( bComputeChecksum) { printf( " Checksum=%d\n", GDALChecksumImage(hBand, 0, 0, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset))); } dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%.18g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; const char *pszResampling = NULL; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); pszResampling = GDALGetMetadataItem( hOverview, "RESAMPLING", "" ); if( pszResampling != NULL && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) printf( "*" ); } printf( "\n" ); if ( bComputeChecksum) { printf( " Overviews checksum: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%d", GDALChecksumImage(hOverview, 0, 0, GDALGetRasterBandXSize(hOverview), GDALGetRasterBandYSize(hOverview))); } printf( "\n" ); } } if( GDALHasArbitraryOverviews( hBand ) ) { printf( " Overviews: arbitrary\n" ); } nMaskFlags = GDALGetMaskFlags( hBand ); if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) { GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ; printf( " Mask Flags: " ); if( nMaskFlags & GMF_PER_DATASET ) printf( "PER_DATASET " ); if( nMaskFlags & GMF_ALPHA ) printf( "ALPHA " ); if( nMaskFlags & GMF_NODATA ) printf( "NODATA " ); if( nMaskFlags & GMF_ALL_VALID ) printf( "ALL_VALID " ); printf( "\n" ); if( hMaskBand != NULL && GDALGetOverviewCount(hMaskBand) > 0 ) { int iOverview; printf( " Overviews of mask band: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hMaskBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hMaskBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } } if( strlen(GDALGetRasterUnitType(hBand)) > 0 ) { printf( " Unit Type: %s\n", GDALGetRasterUnitType(hBand) ); } if( GDALGetRasterCategoryNames(hBand) != NULL ) { char **papszCategories = GDALGetRasterCategoryNames(hBand); int i; printf( " Categories:\n" ); for( i = 0; papszCategories[i] != NULL; i++ ) printf( " %3d: %s\n", i, papszCategories[i] ); } if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0 || GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 ) printf( " Offset: %.15g, Scale:%.15g\n", GDALGetRasterOffset( hBand, &bSuccess ), GDALGetRasterScale( hBand, &bSuccess ) ); papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex && (hTable = GDALGetRasterColorTable( hBand )) != NULL ) { int i; printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); if (bShowColorTable) { for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL ) { GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand ); GDALRATDumpReadable( hRAT, NULL ); } } GDALClose( hDataset ); CSLDestroy( papszExtraMDDomains ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); CPLCleanupTLS(); exit( 0 ); }
// get current tile void FdoRfpStreamReaderGdalByTile::_getTile() { CPLErr eErr; // Preinit the output buffer to 255. This is mostly important // when we have tiles falling over the right or bottom edge. // But this setting also ensures that "added" alpha values are // 255. // TODO: Eventually we will probably want to fill missing alpha // values with 255 and other missing data with 0. memset( m_tileData, 255, m_numTileBytes ); // Compute the ratio of a view pixel to a file pixel. double ratioX, ratioY; ratioX = m_winXSize / (double) m_viewXSize; ratioY = m_winYSize / (double) m_viewYSize; // Compute the window on the file we need to read to satisfy the request. double fileWinULX, fileWinULY, fileWinLRX, fileWinLRY; int fileWinXOff, fileWinYOff, fileWinXSize, fileWinYSize; fileWinULX = m_winXOff + (m_col * m_blockXSize) * ratioX; fileWinLRX = fileWinULX + m_blockXSize * ratioX; fileWinULY = m_winYOff + (m_row * m_blockYSize) * ratioY; fileWinLRY = fileWinULY + m_blockYSize * ratioY; fileWinXOff = (int) floor( fileWinULX + 0.5 ); fileWinYOff = (int) floor( fileWinULY + 0.5 ); fileWinXSize = (int) floor( fileWinLRX + 0.5 ) - fileWinXOff; fileWinYSize = (int) floor( fileWinLRY + 0.5 ) - fileWinYOff; // If this would go off the right or bottom of the image, we may // need to trip the read window. int fileXSize = m_image->m_xSize; int fileYSize = m_image->m_ySize; m_wrkBlockXSize = m_blockXSize; m_wrkBlockYSize = m_blockYSize; if( fileWinXOff + fileWinXSize > fileXSize ) { double xRatio = (fileXSize - fileWinXOff) / (double) fileWinXSize; fileWinXSize = fileXSize - fileWinXOff; m_wrkBlockXSize = (int) (m_wrkBlockXSize * xRatio + 0.5); } if( fileWinYOff + fileWinYSize > fileYSize ) { double yRatio = (fileYSize - fileWinYOff) / (double) fileWinYSize; fileWinYSize = fileYSize - fileWinYOff; m_wrkBlockYSize = (int) (m_wrkBlockYSize * yRatio + 0.5); } // Figure out the interleaving values to use based on the data // model and the selected interleaving. int pixelStep, lineStep, bandStep; switch( m_dataModel->GetOrganization() ) { case FdoRasterDataOrganization_Pixel: pixelStep = m_bytesPerSample * m_components; lineStep = pixelStep * m_blockXSize; bandStep = m_bytesPerSample; break; case FdoRasterDataOrganization_Row: pixelStep = m_bytesPerSample; lineStep = m_bytesPerSample * m_blockXSize * m_components; bandStep = m_bytesPerSample * m_blockXSize; break; case FdoRasterDataOrganization_Image: pixelStep = m_bytesPerSample; lineStep = m_bytesPerSample * m_blockXSize; bandStep = lineStep * m_blockYSize; break; } // If we have a dummy band # for Alpha, then that means we should // effectively not read it. int wrkComponents = m_components; if( m_components == 4 && m_bandList[3] == 0 ) wrkComponents = 3; // Read into interleaved buffer. FdoGdalMutexHolder oHolder; eErr = GDALDatasetRasterIO( m_image->GetDS(), GF_Read, fileWinXOff, fileWinYOff, fileWinXSize, fileWinYSize, m_tileData, m_wrkBlockXSize, m_wrkBlockYSize, m_gdalDataType, wrkComponents, m_bandList, pixelStep, lineStep, bandStep ); if( eErr != CE_None ) { wchar_t *msg = NULL; multibyte_to_wide( msg, CPLGetLastErrorMsg() ); throw FdoException::Create( msg ); } m_image->ReleaseDS(); // If we have a color table for the source imagery, apply it to the final image // The greyscale image returned from GDALDatasetRasterIO should contain color table entries FdoRasterDataModelType modelType = m_dataModel->GetDataModelType(); if ((modelType == FdoRasterDataModelType_RGB || modelType == FdoRasterDataModelType_RGBA) && m_image->m_components == 1) { GDALColorTableH colorTable = NULL; int colorEntries = 0; GDALDatasetH inDataset = m_image->GetDS(); GDALRasterBandH inBand = GDALGetRasterBand( inDataset, 1 ); colorTable = GDALGetRasterColorTable(inBand); if (colorTable != NULL) { colorEntries = GDALGetColorEntryCount(colorTable); } if (colorTable != NULL && colorEntries > 0) { GByte* outData = m_tileData; short bitMask = ((m_bytesPerSample<<8) - 1); for (int i=0; i<m_wrkBlockYSize; i++) { for (int j=0; j<m_wrkBlockXSize; j++) { GByte color = *outData; if (color < colorEntries) { GDALColorEntry colorEntry; if (GDALGetColorEntryAsRGB(colorTable, color, &colorEntry) == TRUE) { *outData = colorEntry.c1 & bitMask; outData += m_bytesPerSample; *outData = colorEntry.c2 & bitMask; outData += m_bytesPerSample; *outData = colorEntry.c3 & bitMask; outData += m_bytesPerSample; if (m_components == 4) { *outData = colorEntry.c4 & bitMask; outData += m_bytesPerSample; } } } } } } m_image->ReleaseDS(); } }
int main(void) { GDALAllRegister(); /*Open a file*/ GDALDatasetH hDataset; hDataset = GDALOpen( "./dem.tif", GA_ReadOnly ); if( hDataset == NULL ) printf("The dataset is NULL!\n"); /*Getting Dasetset Information*/ GDALDriverH hDriver; double adfGeoTransform[6]; hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver )); printf("Size is %dx%dx%d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), GDALGetRasterCount( hDataset )); if( GDALGetProjectionRef( hDataset ) != NULL ) printf("Projection is '%s'\n", GDALGetProjectionRef( hDataset ) ); if (GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf("Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3]); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[5]); } /*Fetching a Raster Band*/ GDALRasterBandH hBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; hBand = GDALGetRasterBand( hDataset, 1); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); if( !(bGotMin && bGotMax) ) { GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); } printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1]); if(GDALGetOverviewCount(hBand) > 0) printf( "Band has %d overviews.\n", GDALGetOverviewCount(hBand)); if( GDALGetRasterColorTable( hBand ) != NULL) printf( "Band has a color table with %d entries.\n", GDALGetColorEntryCount( GDALGetRasterColorTable( hBand))); /*Reading Raster Data*/ float *pafScanline; int nXSize = GDALGetRasterBandXSize( hBand ); pafScanline = (float *)CPLMalloc(sizeof(float)*nXSize); GDALRasterIO(hBand, GF_Read, 0, 0, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0); CPLFree(pafScanline); return 0; }
void toprsGadlReader::populateLut() { theLut.reset(); // toprsRefPtr not a leak. if(isIndexed(1)&&theDataset) { GDALColorTableH aTable = GDALGetRasterColorTable(GDALGetRasterBand( theDataset, 1 )); GDALPaletteInterp interp = GDALGetPaletteInterpretation(aTable); if(aTable && ( (interp == GPI_Gray) || (interp == GPI_RGB))) { GDALColorEntry colorEntry; int numberOfElements = GDALGetColorEntryCount(aTable); int idx = 0; if(numberOfElements) { // GPI_Gray Grayscale (in GDALColorEntry.c1) // GPI_RGB Red, Green, Blue and Alpha in (in c1, c2, c3 and c4) theLut.reset(new toprsNBandLutDataObject(numberOfElements,4,TOPRS_UINT8,-1)); bool nullSet = false; for(idx = 0; idx < numberOfElements; ++idx) { switch(interp) { case GPI_RGB: { if(GDALGetColorEntryAsRGB(aTable, idx, &colorEntry)) { (*theLut)[idx][0] = colorEntry.c1; (*theLut)[idx][1] = colorEntry.c2; (*theLut)[idx][2] = colorEntry.c3; (*theLut)[idx][3] = colorEntry.c4; if ( !nullSet ) { if ( m_preservePaletteIndexesFlag ) { // If preserving palette set the null to the fix alpha of 0. if ( (*theLut)[idx][3] == 0 ) { theLut->setNullPixelIndex(idx); nullSet = true; } } else { //--- // Not using alpha. // Since the alpha is currently not used, look for the null // pixel index and set if we find. If at some point the alpha // is taken out this can be removed. //--- if ( ( (*theLut)[idx][0] == 0 ) && ( (*theLut)[idx][1] == 0 ) && ( (*theLut)[idx][2] == 0 ) ) { theLut->setNullPixelIndex(idx); nullSet = true; } } } } else { (*theLut)[idx][0] = 0; (*theLut)[idx][1] = 0; (*theLut)[idx][2] = 0; (*theLut)[idx][3] = 0; // Look for the null pixel index and set if we find. if ( !nullSet ) { if ( (*theLut)[idx][0] == 0 ) { theLut->setNullPixelIndex(idx); } } } break; } case GPI_Gray: { const GDALColorEntry* constEntry = GDALGetColorEntry(aTable, idx); if(constEntry) { (*theLut)[idx][0] = constEntry->c1; } else { (*theLut)[idx][0] = 0; } break; } default: { break; } } } } } toprs_uint32 rasterCount = GDALGetRasterCount(theDataset); for(toprs_uint32 aGdalBandIndex=1; aGdalBandIndex <= rasterCount; ++aGdalBandIndex) { GDALRasterBandH aBand = GDALGetRasterBand( theDataset, aGdalBandIndex ); if (aBand) { GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT(aBand); int colCount = GDALRATGetColumnCount(hRAT); for (toprs_int32 col = 0; col < colCount; col++) { const char* colName = GDALRATGetNameOfCol(hRAT, col); if (colName) { if (strcmp(colName, "Class_Names") == 0) { std::vector<std::string> entryLabels; toprs_int32 rowCount = GDALRATGetRowCount(hRAT); for (toprs_int32 row = 0; row < rowCount; row++) { const char* className = GDALRATGetValueAsString(hRAT, row, col); std::string entryLabel(className); entryLabels.push_back(entryLabel); } theLut->setEntryLables(aGdalBandIndex-1, entryLabels); } } } } } } }
int GDALDitherRGB2PCTInternal( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GDALRasterBandH hTarget, GDALColorTableH hColorTable, int nBits, GInt16* pasDynamicColorMap, /* NULL or at least 256 * 256 * 256 * sizeof(GInt16) bytes */ int bDither, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hTarget, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hColorTable, "GDALDitherRGB2PCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( GDALGetRasterBandXSize( hTarget ) != nXSize || GDALGetRasterBandYSize( hTarget ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Target band doesn't match size of source bands.\n" ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Setup more direct colormap. */ /* -------------------------------------------------------------------- */ int nColors, iColor; #ifdef USE_SSE2 int anPCTUnaligned[256+4]; /* 4 for alignment on 16-byte boundary */ int* anPCT = ALIGN_INT_ARRAY_ON_16_BYTE(anPCTUnaligned); #else int anPCT[256*4]; #endif nColors = GDALGetColorEntryCount( hColorTable ); if (nColors == 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table must not be empty.\n" ); return CE_Failure; } else if (nColors > 256) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table cannot have more than 256 entries.\n" ); return CE_Failure; } for( iColor = 0; iColor < nColors; iColor++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hColorTable, iColor, &sEntry ); CAST_PCT(anPCT)[4*iColor+0] = sEntry.c1; CAST_PCT(anPCT)[4*iColor+1] = sEntry.c2; CAST_PCT(anPCT)[4*iColor+2] = sEntry.c3; CAST_PCT(anPCT)[4*iColor+3] = 0; } #ifdef USE_SSE2 /* Pad to multiple of 8 colors */ int nColorsMod8 = nColors % 8; if( nColorsMod8 ) { for( iColor = 0; iColor < 8 - nColorsMod8; iColor ++) { anPCT[nColors+iColor] = anPCT[nColors-1]; } } #endif /* -------------------------------------------------------------------- */ /* Setup various variables. */ /* -------------------------------------------------------------------- */ GByte *pabyRed, *pabyGreen, *pabyBlue, *pabyIndex; GByte *pabyColorMap = NULL; int *panError; int nCLevels = 1 << nBits; ColorIndex* psColorIndexMap = NULL; pabyRed = (GByte *) VSIMalloc(nXSize); pabyGreen = (GByte *) VSIMalloc(nXSize); pabyBlue = (GByte *) VSIMalloc(nXSize); pabyIndex = (GByte *) VSIMalloc(nXSize); panError = (int *) VSICalloc(sizeof(int),(nXSize+2) * 3); if (pabyRed == NULL || pabyGreen == NULL || pabyBlue == NULL || pabyIndex == NULL || panError == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } if( pasDynamicColorMap == NULL ) { /* -------------------------------------------------------------------- */ /* Build a 24bit to 8 bit color mapping. */ /* -------------------------------------------------------------------- */ pabyColorMap = (GByte *) VSIMalloc(nCLevels * nCLevels * nCLevels * sizeof(GByte)); if( pabyColorMap == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } FindNearestColor( nColors, anPCT, pabyColorMap, nCLevels); } else { pabyColorMap = NULL; if( nBits == 8 && (GIntBig)nXSize * nYSize <= 65536 ) { /* If the image is small enough, then the number of colors */ /* will be limited and using a hashmap, rather than a full table */ /* will be more efficient */ psColorIndexMap = (ColorIndex*)pasDynamicColorMap; memset(psColorIndexMap, 0xFF, sizeof(ColorIndex) * PRIME_FOR_65536); } else { memset(pasDynamicColorMap, 0xFF, 256 * 256 * 256 * sizeof(GInt16)); } } /* ==================================================================== */ /* Loop over all scanlines of data to process. */ /* ==================================================================== */ int iScanline; for( iScanline = 0; iScanline < nYSize; iScanline++ ) { int nLastRedError, nLastGreenError, nLastBlueError, i; /* -------------------------------------------------------------------- */ /* Report progress */ /* -------------------------------------------------------------------- */ if( !pfnProgress( iScanline / (double) nYSize, NULL, pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } /* -------------------------------------------------------------------- */ /* Read source data. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hRed, GF_Read, 0, iScanline, nXSize, 1, pabyRed, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iScanline, nXSize, 1, pabyGreen, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iScanline, nXSize, 1, pabyBlue, nXSize, 1, GDT_Byte, 0, 0 ); /* -------------------------------------------------------------------- */ /* Apply the error from the previous line to this one. */ /* -------------------------------------------------------------------- */ if( bDither ) { for( i = 0; i < nXSize; i++ ) { pabyRed[i] = (GByte) MAX(0,MIN(255,(pabyRed[i] + panError[i*3+0+3]))); pabyGreen[i] = (GByte) MAX(0,MIN(255,(pabyGreen[i] + panError[i*3+1+3]))); pabyBlue[i] = (GByte) MAX(0,MIN(255,(pabyBlue[i] + panError[i*3+2+3]))); } memset( panError, 0, sizeof(int) * (nXSize+2) * 3 ); } /* -------------------------------------------------------------------- */ /* Figure out the nearest color to the RGB value. */ /* -------------------------------------------------------------------- */ nLastRedError = 0; nLastGreenError = 0; nLastBlueError = 0; for( i = 0; i < nXSize; i++ ) { int iIndex, nError, nSixth; int nRedValue, nGreenValue, nBlueValue; nRedValue = MAX(0,MIN(255, pabyRed[i] + nLastRedError)); nGreenValue = MAX(0,MIN(255, pabyGreen[i] + nLastGreenError)); nBlueValue = MAX(0,MIN(255, pabyBlue[i] + nLastBlueError)); if( psColorIndexMap ) { GUInt32 nColorCode = MAKE_COLOR_CODE(nRedValue, nGreenValue, nBlueValue); GUInt32 nIdx = nColorCode % PRIME_FOR_65536; //int nCollisions = 0; //static int nMaxCollisions = 0; while( TRUE ) { if( psColorIndexMap[nIdx].nColorCode == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex; break; } if( (int)psColorIndexMap[nIdx].nColorCode < 0 ) { psColorIndexMap[nIdx].nColorCode = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex = (GByte) iIndex; break; } if( psColorIndexMap[nIdx].nColorCode2 == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex2; break; } if( (int)psColorIndexMap[nIdx].nColorCode2 < 0 ) { psColorIndexMap[nIdx].nColorCode2 = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex2 = (GByte) iIndex; break; } if( psColorIndexMap[nIdx].nColorCode3 == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex3; break; } if( (int)psColorIndexMap[nIdx].nColorCode3 < 0 ) { psColorIndexMap[nIdx].nColorCode3 = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex3 = (GByte) iIndex; break; } do { //nCollisions ++; nIdx+=257; if( nIdx >= PRIME_FOR_65536 ) nIdx -= PRIME_FOR_65536; } while( (int)psColorIndexMap[nIdx].nColorCode >= 0 && psColorIndexMap[nIdx].nColorCode != nColorCode && (int)psColorIndexMap[nIdx].nColorCode2 >= 0 && psColorIndexMap[nIdx].nColorCode2 != nColorCode&& (int)psColorIndexMap[nIdx].nColorCode3 >= 0 && psColorIndexMap[nIdx].nColorCode3 != nColorCode ); /*if( nCollisions > nMaxCollisions ) { nMaxCollisions = nCollisions; printf("nCollisions = %d for R=%d,G=%d,B=%d\n", nCollisions, nRedValue, nGreenValue, nBlueValue); }*/ } } else if( pasDynamicColorMap == NULL ) { int iRed = nRedValue * nCLevels / 256; int iGreen = nGreenValue * nCLevels / 256; int iBlue = nBlueValue * nCLevels / 256; iIndex = pabyColorMap[iRed + iGreen * nCLevels + iBlue * nCLevels * nCLevels]; } else { GUInt32 nColorCode = MAKE_COLOR_CODE(nRedValue, nGreenValue, nBlueValue); GInt16* psIndex = &pasDynamicColorMap[nColorCode]; if( *psIndex < 0 ) iIndex = *psIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); else iIndex = *psIndex; } pabyIndex[i] = (GByte) iIndex; if( !bDither ) continue; /* -------------------------------------------------------------------- */ /* Compute Red error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nRedValue - CAST_PCT(anPCT)[4*iIndex+0]; nSixth = nError / 6; panError[i*3 ] += nSixth; panError[i*3+6 ] = nSixth; panError[i*3+3 ] += nError - 5 * nSixth; nLastRedError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Green error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nGreenValue - CAST_PCT(anPCT)[4*iIndex+1]; nSixth = nError / 6; panError[i*3 +1] += nSixth; panError[i*3+6+1] = nSixth; panError[i*3+3+1] += nError - 5 * nSixth; nLastGreenError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Blue error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nBlueValue - CAST_PCT(anPCT)[4*iIndex+2]; nSixth = nError / 6; panError[i*3 +2] += nSixth; panError[i*3+6+2] = nSixth; panError[i*3+3+2] += nError - 5 * nSixth; nLastBlueError = 2 * nSixth; } /* -------------------------------------------------------------------- */ /* Write results. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hTarget, GF_Write, 0, iScanline, nXSize, 1, pabyIndex, nXSize, 1, GDT_Byte, 0, 0 ); } pfnProgress( 1.0, NULL, pProgressArg ); /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end_and_cleanup: CPLFree( pabyRed ); CPLFree( pabyGreen ); CPLFree( pabyBlue ); CPLFree( pabyIndex ); CPLFree( panError ); CPLFree( pabyColorMap ); return err; }
int CPL_STDCALL GDALDitherRGB2PCT( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GDALRasterBandH hTarget, GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hTarget, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hColorTable, "GDALDitherRGB2PCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( GDALGetRasterBandXSize( hTarget ) != nXSize || GDALGetRasterBandYSize( hTarget ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Target band doesn't match size of source bands.\n" ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Setup more direct colormap. */ /* -------------------------------------------------------------------- */ int nColors, anPCT[768], iColor; nColors = GDALGetColorEntryCount( hColorTable ); if (nColors == 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table must not be empty.\n" ); return CE_Failure; } else if (nColors > 256) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table cannot have more than 256 entries.\n" ); return CE_Failure; } for( iColor = 0; iColor < nColors; iColor++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hColorTable, iColor, &sEntry ); anPCT[iColor ] = sEntry.c1; anPCT[iColor+256] = sEntry.c2; anPCT[iColor+512] = sEntry.c3; } /* -------------------------------------------------------------------- */ /* Build a 24bit to 8 bit color mapping. */ /* -------------------------------------------------------------------- */ GByte *pabyColorMap; pabyColorMap = (GByte *) CPLMalloc(C_LEVELS * C_LEVELS * C_LEVELS * sizeof(int)); FindNearestColor( nColors, anPCT, pabyColorMap ); /* -------------------------------------------------------------------- */ /* Setup various variables. */ /* -------------------------------------------------------------------- */ GByte *pabyRed, *pabyGreen, *pabyBlue, *pabyIndex; int *panError; pabyRed = (GByte *) VSIMalloc(nXSize); pabyGreen = (GByte *) VSIMalloc(nXSize); pabyBlue = (GByte *) VSIMalloc(nXSize); pabyIndex = (GByte *) VSIMalloc(nXSize); panError = (int *) VSICalloc(sizeof(int),(nXSize+2) * 3); if (pabyRed == NULL || pabyGreen == NULL || pabyBlue == NULL || pabyIndex == NULL || panError == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } /* ==================================================================== */ /* Loop over all scanlines of data to process. */ /* ==================================================================== */ int iScanline; for( iScanline = 0; iScanline < nYSize; iScanline++ ) { int nLastRedError, nLastGreenError, nLastBlueError, i; /* -------------------------------------------------------------------- */ /* Report progress */ /* -------------------------------------------------------------------- */ if( !pfnProgress( iScanline / (double) nYSize, NULL, pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } /* -------------------------------------------------------------------- */ /* Read source data. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hRed, GF_Read, 0, iScanline, nXSize, 1, pabyRed, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iScanline, nXSize, 1, pabyGreen, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iScanline, nXSize, 1, pabyBlue, nXSize, 1, GDT_Byte, 0, 0 ); /* -------------------------------------------------------------------- */ /* Apply the error from the previous line to this one. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nXSize; i++ ) { pabyRed[i] = (GByte) MAX(0,MIN(255,(pabyRed[i] + panError[i*3+0+3]))); pabyGreen[i] = (GByte) MAX(0,MIN(255,(pabyGreen[i] + panError[i*3+1+3]))); pabyBlue[i] = (GByte) MAX(0,MIN(255,(pabyBlue[i] + panError[i*3+2+3]))); } memset( panError, 0, sizeof(int) * (nXSize+2) * 3 ); /* -------------------------------------------------------------------- */ /* Figure out the nearest color to the RGB value. */ /* -------------------------------------------------------------------- */ nLastRedError = 0; nLastGreenError = 0; nLastBlueError = 0; for( i = 0; i < nXSize; i++ ) { int iIndex, nError, nSixth, iRed, iGreen, iBlue; int nRedValue, nGreenValue, nBlueValue; nRedValue = MAX(0,MIN(255, pabyRed[i] + nLastRedError)); nGreenValue = MAX(0,MIN(255, pabyGreen[i] + nLastGreenError)); nBlueValue = MAX(0,MIN(255, pabyBlue[i] + nLastBlueError)); iRed = nRedValue * C_LEVELS / 256; iGreen = nGreenValue * C_LEVELS / 256; iBlue = nBlueValue * C_LEVELS / 256; iIndex = pabyColorMap[iRed + iGreen * C_LEVELS + iBlue * C_LEVELS * C_LEVELS]; pabyIndex[i] = (GByte) iIndex; /* -------------------------------------------------------------------- */ /* Compute Red error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nRedValue - anPCT[iIndex ]; nSixth = nError / 6; panError[i*3 ] += nSixth; panError[i*3+6 ] = nSixth; panError[i*3+3 ] += nError - 5 * nSixth; nLastRedError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Green error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nGreenValue - anPCT[iIndex+256]; nSixth = nError / 6; panError[i*3 +1] += nSixth; panError[i*3+6+1] = nSixth; panError[i*3+3+1] += nError - 5 * nSixth; nLastGreenError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Blue error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nBlueValue - anPCT[iIndex+512]; nSixth = nError / 6; panError[i*3 +2] += nSixth; panError[i*3+6+2] = nSixth; panError[i*3+3+2] += nError - 5 * nSixth; nLastBlueError = 2 * nSixth; } /* -------------------------------------------------------------------- */ /* Write results. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hTarget, GF_Write, 0, iScanline, nXSize, 1, pabyIndex, nXSize, 1, GDT_Byte, 0, 0 ); } pfnProgress( 1.0, NULL, pProgressArg ); /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end_and_cleanup: CPLFree( pabyRed ); CPLFree( pabyGreen ); CPLFree( pabyBlue ); CPLFree( pabyIndex ); CPLFree( panError ); CPLFree( pabyColorMap ); return err; }