Beispiel #1
0
bool Decrypt(const wxString &sText, wxString &sDecryptText)
{

	GByte *pabyKey = GetKey();
	GByte *pabyIV = GetIV();

	EVP_CIPHER_CTX* ctx = CreateCTX(pabyKey, pabyIV, true);
	if(!ctx)
	{
		wxLogError(_("Decrypt: Failed EVP_DecryptInit!"));
		CPLFree( pabyKey );
		CPLFree( pabyIV );
		return false;
	}

	int nTextBytes;
	GByte *pabyText = CPLHexToBinary( sText.mb_str(wxConvUTF8), &nTextBytes );

	int outlen;
	unsigned char outbuf[BUFSIZE];

	bool bResult = EVP_DecryptUpdate(ctx, outbuf, &outlen, pabyText, nTextBytes);
	if(!bResult)
	{
		wxLogError(_("Decrypt: Failed EVP_DecryptUpdate!"));
		CPLFree( pabyKey );
		CPLFree( pabyIV );
		CPLFree( pabyText );
		return bResult;
	}

	int nLen = outlen;
	bResult = EVP_DecryptFinal(ctx, &outbuf[outlen], &outlen);
	nLen += outlen;
	outbuf[nLen] = 0;

	CPLString szCryptText((const char*)outbuf);
	sDecryptText = wxString(szCryptText, wxConvUTF8);

	CPLFree( pabyKey );
	CPLFree( pabyIV );
	CPLFree( pabyText );

	EVP_CIPHER_CTX_cleanup(ctx);
	//EVP_CIPHER_CTX_free(ctx);

	return bResult;
}
Beispiel #2
0
GByte *GetKey(void)
{
	wxGISAppConfig oConfig = GetConfig();
	if(!oConfig.IsOk())
		return NULL;
    //try get key data from config
	wxString sKey = oConfig.Read(enumGISHKCU, wxString(wxT("wxGISCommon/crypt/key")), wxString(ERR));
	if(sKey.CmpNoCase(wxString(ERR)) == 0)
	{
		if(!CreateRandomData())//create random key data
            return NULL;
		//second try get key data from config
		sKey = oConfig.Read(enumGISHKCU, wxString(wxT("wxGISCommon/crypt/key")), wxString(ERR));
		if(sKey.CmpNoCase(wxString(ERR)) == 0)
			return NULL;
	}

	int nKeyBytes;
	GByte *pabyKey = CPLHexToBinary( sKey.mb_str(wxConvUTF8), &nKeyBytes );
    return pabyKey;
}
/*****************************************************
 * \brief Read a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterRasterBand::IReadBlock(int nBlockXOff,
        int nBlockYOff, void * pImage)
{
    PGresult * poResult = NULL;
    CPLString osCommand;
    int nXOff = 0;
    int nYOff = 0;
    int nNaturalBlockXSize = 0;
    int nNaturalBlockYSize = 0;
    double adfProjWin[8];
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;

    int nPixelSize = GDALGetDataTypeSize(eDataType) / 8;

    // Construct a polygon to intersect with
    GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize);

    nXOff = nBlockXOff * nNaturalBlockXSize;
    nYOff = nBlockYOff * nNaturalBlockYSize;

    poRDS->PolygonFromCoords(nXOff, nYOff, nXOff + nNaturalBlockXSize, nYOff + nNaturalBlockYSize, adfProjWin);

    // Raise the query
    if (poRDS->pszWhere == NULL) {
        osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s "
            "WHERE st_intersects(%s, ST_PolygonFromText"
            "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f "
            "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema,
            pszTable, pszColumn, adfProjWin[0], adfProjWin[1],
            adfProjWin[2], adfProjWin[3],  adfProjWin[4], adfProjWin[5],
            adfProjWin[6], adfProjWin[7], adfProjWin[0], adfProjWin[1],
            poRDS->nSrid);
    }

    else {
        osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s WHERE (%s) "
            "AND st_intersects(%s, ST_PolygonFromText"
            "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f "
            "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema,
            pszTable, poRDS->pszWhere, pszColumn, adfProjWin[0],
            adfProjWin[1], adfProjWin[2], adfProjWin[3], adfProjWin[4],
            adfProjWin[5], adfProjWin[6], adfProjWin[7], adfProjWin[0],
            adfProjWin[1], poRDS->nSrid);
    }

#ifdef DEBUG_QUERY
    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::IReadBlock(): Query = %s",
            osCommand.c_str());
#endif

    poResult = PQexec(poRDS->poConn, osCommand.c_str());
    if (poResult == NULL ||
        PQresultStatus(poResult) != PGRES_TUPLES_OK ||
        PQntuples(poResult) < 0) {

        if (poResult)
            PQclear(poResult);

        ReportError(CE_Failure, CPLE_AppDefined,
            "Error retrieving raster data FROM database");

        CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO(): %s",
                PQerrorMessage(poRDS->poConn));

        return CE_Failure;
    }

    /**
     * No data. Return the buffer filled with nodata values
     **/
    else if (PQntuples(poResult) == 0) {
        PQclear(poResult);

        CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IRasterIO(): Null block");

        NullBlock(pImage);

        return CE_None;
    }


    /**
     * Ok, we get the data. Only data size, without payload
     *
     * TODO: Check byte order
     **/
    int nExpectedDataSize = nNaturalBlockXSize * nNaturalBlockYSize *
        nPixelSize;

    int nWKBLength = 0;

    GByte * pbyData = CPLHexToBinary(PQgetvalue(poResult, 0, 0),
        &nWKBLength);

    char * pbyDataToRead = (char*)GET_BAND_DATA(pbyData,nBand,
            nPixelSize, nExpectedDataSize);

    memcpy(pImage, pbyDataToRead, nExpectedDataSize * sizeof(char));

    CPLDebug("PostGIS_Raster", "IReadBlock: Copied %d bytes FROM block "
            "(%d, %d) to %p", nExpectedDataSize, nBlockXOff,
            nBlockYOff, pImage);

    CPLFree(pbyData);
    PQclear(poResult);

    return CE_None;
}
Beispiel #4
0
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree, const char *pszUnused )

{
    PamInitialize();

/* -------------------------------------------------------------------- */
/*      Apply any dataset level metadata.                               */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    GDALMajorObject::SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
    
    if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
    {
        const char *pszLEHex = 
            CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", NULL );
        if( pszLEHex != NULL )
        {
            int nBytes;
            GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes );
            if( nBytes == 8 )
            {
                CPL_LSBPTR64( pabyBin );
                
                GDALPamRasterBand::SetNoDataValue( *((double *) pabyBin) );
            }
            else
            {
                GDALPamRasterBand::SetNoDataValue( 
                    atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
            }
            CPLFree( pabyBin );
        }
        else
        {
            GDALPamRasterBand::SetNoDataValue( 
                atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
        }
    }

    GDALPamRasterBand::SetOffset( 
        atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    GDALPamRasterBand::SetScale( 
        atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL));

    if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
        GDALPamRasterBand::SetColorInterpretation(
                                GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
    {
        CPLXMLNode *psEntry;
        char **papszCategoryNames = NULL;

        for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            /* Don't skeep <Category> tag with empty content */
            if( psEntry->eType != CXT_Element 
                || !EQUAL(psEntry->pszValue,"Category") 
                || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
                continue;
            
            papszCategoryNames = CSLAddString( papszCategoryNames, 
                                 (psEntry->psChild) ? psEntry->psChild->pszValue : "" );
        }
        
        GDALPamRasterBand::SetCategoryNames( papszCategoryNames );
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
    {
        CPLXMLNode *psEntry;
        GDALColorTable oTable;
        int        iEntry = 0;

        for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            GDALColorEntry sCEntry;

            sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
            sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
            sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
            sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }
        
        GDALPamRasterBand::SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a complete set of stats?                             */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "Minimum" ) != NULL 
        && CPLGetXMLNode( psTree, "Maximum" ) != NULL )
    {
        psPam->bHaveMinMax = TRUE;
        psPam->dfMin = atof(CPLGetXMLValue(psTree, "Minimum","0"));
        psPam->dfMax = atof(CPLGetXMLValue(psTree, "Maximum","0"));
    }

    if( CPLGetXMLNode( psTree, "Mean" ) != NULL 
        && CPLGetXMLNode( psTree, "StandardDeviation" ) != NULL )
    {
        psPam->bHaveStats = TRUE;
        psPam->dfMean = atof(CPLGetXMLValue(psTree, "Mean","0"));
        psPam->dfStdDev = atof(CPLGetXMLValue(psTree,"StandardDeviation","0"));
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != NULL )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = NULL;

        psPam->psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* -------------------------------------------------------------------- */
/*      Raster Attribute Table                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" );
    if( psRAT != NULL )
    {
        psPam->poDefaultRAT = new GDALRasterAttributeTable();
        psPam->poDefaultRAT->XMLInit( psRAT, "" );
    }

    return CE_None;
}
/**
 * Fill all the raster properties with the string
 * hexwkb representation given as input.
 * This method swaps words if the raster endianess is distinct from
 * the machine endianess
 * Properties:
 *  const char *: the string hexwkb representation of the raster
 */
int WKTRasterWrapper::Initialize(const char* pszHex) { 
    int nBufferDataWithoutHeaderLen = 0;
    int nRasterHeaderLen = 0; 
    int nRasterBandHeaderLen = 0; 
    int nRasterDataLen = 0;
    GByte * pbyAuxPtr;
    GByte byMachineEndianess = NDR; // by default

    // Check machine endianess
#ifdef CPL_LSB
    byMachineEndianess = NDR;
#else
    byMachineEndianess = XDR;
#endif

    /*************************************************************************
     *  Check parameters
     *************************************************************************/
    if (pszHex == NULL || strlen(pszHex) % 2) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Couldn't create raster wrapper, invalid raster hexwkb string");
        return FALSE;
    }

    /*************************************************************************
     * Check if raster has enough data
     *************************************************************************/
    nRasterHeaderLen =
        sizeof (GByte) +
        4 * sizeof (GUInt16) +
 	sizeof (GInt32) +
 	6 * sizeof (double);

    nBufferDataWithoutHeaderLen =
        strlen(pszHex +2*nRasterHeaderLen) / 2;

    pbyHexWkb = CPLHexToBinary(pszHex, &nLengthByWkbString);    
    
    if (nRasterHeaderLen > nLengthByWkbString || 
        nLengthByWkbString != nRasterHeaderLen + nBufferDataWithoutHeaderLen)
    {        
        CPLError(CE_Failure, CPLE_ObjectNull,
                "Raster object is corrupted, not enough data");
        return FALSE;
    }


    /*************************************************************************
     * Copy raster as class attribute, and transform it to binary
     *************************************************************************/
    nLengthHexWkbString = strlen(pszHex);   

    pszHexWkb = (char *) VSIMalloc(nLengthHexWkbString);
    if (pszHexWkb == NULL) {        
        CPLError(CE_Failure, CPLE_ObjectNull,
                "Couldn't allocate memory for raster wrapper, aborting");
        return FALSE;
    }

    memcpy(pszHexWkb, pszHex, nLengthHexWkbString * sizeof (GByte));

   
    /***********************************************************************
     * Get endianess. This is important, because we could need to swap
     * words if the data endianess is distinct from machine endianess
     ***********************************************************************/
    memcpy(&byEndianess, pbyHexWkb, sizeof(GByte));

    // We are going to use this pointer to move over the string
    pbyAuxPtr = pbyHexWkb + sizeof (GByte);

    /*************************************************************************
     * Parse HexWkb string in binary format and fill the rest of class fields
     *************************************************************************/
    memcpy(&nVersion, pbyAuxPtr, sizeof (GUInt16));
    if (byEndianess != byMachineEndianess)
        GDALSwapWords(&nVersion, sizeof (GUInt16), 1, sizeof (GUInt16));
    pbyAuxPtr += sizeof (GUInt16);


    /**
     * Check WKT Raster version
     */
    if (nVersion != WKT_RASTER_VERSION) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "WKT Raster version not supported (%d). Supported raster\
                version is %d\n", nVersion, WKT_RASTER_VERSION);

        return FALSE;
    }
/*****************************************************
 * \brief Read a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterTileRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff,
                                               CPL_UNUSED int nBlockYOff,
                                               void * pImage)
{
    CPLString osCommand;
    PGresult * poResult = NULL;
    int nWKBLength = 0;

    int nPixelSize = GDALGetDataTypeSize(eDataType)/8;

    PostGISRasterTileDataset * poRTDS =
        (PostGISRasterTileDataset *)poDS;
        
    // Get by PKID
    if (poRTDS->poRDS->pszPrimaryKeyName) {
        osCommand.Printf("select st_band(%s, %d) from %s.%s where "
            "%s = '%s'", poRTDS->poRDS->pszColumn, nBand, poRTDS->poRDS->pszSchema, poRTDS->poRDS->pszTable,
            poRTDS->poRDS->pszPrimaryKeyName, poRTDS->pszPKID);

    }
    
    // Get by upperleft
    else {
        osCommand.Printf("select st_band(%s, %d) from %s.%s where "
            "abs(ST_UpperLeftX(%s) - %.8f) < 1e-8 and abs(ST_UpperLeftY(%s) - %.8f) < 1e-8", 
            poRTDS->poRDS->pszColumn, nBand, poRTDS->poRDS->pszSchema, poRTDS->poRDS->pszTable, poRTDS->poRDS->pszColumn, 
            poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X], poRTDS->poRDS->pszColumn, 
            poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]);
        
    }
    
    poResult = PQexec(poRTDS->poRDS->poConn, osCommand.c_str());
    
#ifdef DEBUG_QUERY
    CPLDebug("PostGIS_Raster", "PostGISRasterTileRasterBand::IReadBlock(): "
             "Query = \"%s\" --> number of rows = %d",
             osCommand.c_str(), poResult ? PQntuples(poResult) : 0 );
#endif

    if (poResult == NULL || 
        PQresultStatus(poResult) != PGRES_TUPLES_OK ||
        PQntuples(poResult) <= 0) {
            
        if (poResult)
            PQclear(poResult);
            
        ReportError(CE_Failure, CPLE_AppDefined,
            "Error getting block of data (upperpixel = %f, %f)",
                poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X], 
                poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]);
            
        return CE_Failure;
    }


    // TODO: Check this
    if (bIsOffline) {
        CPLError(CE_Failure, CPLE_AppDefined, "This raster has outdb "
            "storage. This feature isn't still available");
        
        PQclear(poResult);    
        return CE_Failure;
    }
    
    /* Copy only data size, without payload */
    int nExpectedDataSize = 
        nBlockXSize * nBlockYSize * nPixelSize;
        
    GByte * pbyData = CPLHexToBinary(PQgetvalue(poResult, 0, 0), 
        &nWKBLength);
    int nExpectedWKBLength = RASTER_HEADER_SIZE + BAND_SIZE(nPixelSize, nExpectedDataSize);
    CPLErr eRet = CE_None;
    if( nWKBLength != nExpectedWKBLength )
    {
        CPLDebug("PostGIS_Raster", "nWKBLength=%d, nExpectedWKBLength=%d", nWKBLength, nExpectedWKBLength );
        eRet = CE_Failure;
    }
    else
    {
        GByte * pbyDataToRead = 
        (GByte*)GET_BAND_DATA(pbyData,1, nPixelSize, 
            nExpectedDataSize);

        // Do byte-swapping if necessary */
        int bIsLittleEndian = (pbyData[0] == 1);
#ifdef CPL_LSB
        int bSwap = !bIsLittleEndian;
#else
        int bSwap = bIsLittleEndian;
#endif
        if( bSwap && nPixelSize > 1 )
        {
            GDALSwapWords( pbyDataToRead, nPixelSize,
                           nBlockXSize * nBlockYSize,
                           nPixelSize );
        }

        memcpy(pImage, pbyDataToRead, nExpectedDataSize);
    }

    CPLFree(pbyData);
    PQclear(poResult);

    return eRet;
}
/*****************************************************
 * \brief Read a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterTileRasterBand::IReadBlock(int /*nBlockXOff*/,
                                               int /*nBlockYOff*/,
                                               void * pImage)
{
    CPLString osCommand;
    PGresult * poResult = nullptr;
    int nWKBLength = 0;

    const int nPixelSize = GDALGetDataTypeSizeBytes(eDataType);

    PostGISRasterTileDataset * poRTDS =
        cpl::down_cast<PostGISRasterTileDataset *>(poDS);

    const double dfTileUpperLeftX = poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X];
    const double dfTileUpperLeftY = poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y];
    const double dfTileResX = poRTDS->adfGeoTransform[1];
    const double dfTileResY = poRTDS->adfGeoTransform[5];
    const int nTileXSize = nBlockXSize;
    const int nTileYSize = nBlockYSize;

    CPLString osRasterToFetch;
    osRasterToFetch.Printf("ST_Band(%s, %d)",
                           poRTDS->poRDS->pszColumn, nBand);
    // We don't honour CLIENT_SIDE_IF_POSSIBLE since it would be likely too
    // costly in that context.
    if( poRTDS->poRDS->eOutDBResolution != OutDBResolution::CLIENT_SIDE )
    {
        osRasterToFetch = "encode(ST_AsBinary(" + osRasterToFetch + ",TRUE),'hex')";
    }

    osCommand.Printf("SELECT %s FROM %s.%s WHERE ",
        osRasterToFetch.c_str(), poRTDS->poRDS->pszSchema, poRTDS->poRDS->pszTable);

    // Get by PKID
    if (poRTDS->poRDS->pszPrimaryKeyName)
    {
        osCommand += CPLSPrintf("%s = '%s'",
                        poRTDS->poRDS->pszPrimaryKeyName, poRTDS->pszPKID);
    }

    // Get by upperleft
    else {
        osCommand += CPLSPrintf(
            "abs(ST_UpperLeftX(%s) - %.8f) < 1e-8 and abs(ST_UpperLeftY(%s) - %.8f) < 1e-8",
            poRTDS->poRDS->pszColumn,
            dfTileUpperLeftX,
            poRTDS->poRDS->pszColumn,
            dfTileUpperLeftY);
    }

    poResult = PQexec(poRTDS->poRDS->poConn, osCommand.c_str());

#ifdef DEBUG_QUERY
    CPLDebug("PostGIS_Raster", "PostGISRasterTileRasterBand::IReadBlock(): "
             "Query = \"%s\" --> number of rows = %d",
             osCommand.c_str(), poResult ? PQntuples(poResult) : 0 );
#endif

    if (poResult == nullptr ||
        PQresultStatus(poResult) != PGRES_TUPLES_OK ||
        PQntuples(poResult) <= 0) {

        CPLString osError;
        if( PQresultStatus(poResult) == PGRES_FATAL_ERROR )
        {
            const char *pszError = PQerrorMessage( poRTDS->poRDS->poConn );
            if( pszError )
                osError = pszError;
        }
        if (poResult)
            PQclear(poResult);

        ReportError(CE_Failure, CPLE_AppDefined,
            "Error getting block of data (upperpixel = %f, %f): %s",
                dfTileUpperLeftX,
                dfTileUpperLeftY,
                osError.c_str());

        return CE_Failure;
    }

    /* Copy only data size, without payload */
    int nExpectedDataSize =
        nBlockXSize * nBlockYSize * nPixelSize;

    struct CPLFreer { void operator() (GByte* x) const { CPLFree(x); } };
    std::unique_ptr<GByte, CPLFreer> pbyDataAutoFreed(
        CPLHexToBinary(PQgetvalue(poResult, 0, 0), &nWKBLength));
    GByte* pbyData = pbyDataAutoFreed.get();
    PQclear(poResult);

    const int nMinimumWKBLength = RASTER_HEADER_SIZE + BAND_SIZE(1, nPixelSize);
    if( nWKBLength < nMinimumWKBLength )
    {
        CPLDebug("PostGIS_Raster", "nWKBLength=%d. too short. Expected at least %d",
                 nWKBLength, nMinimumWKBLength );
        return CE_Failure;
    }

    // Is it indb-raster ?
    if( (pbyData[RASTER_HEADER_SIZE] & 0x80) == 0 )
    {
        int nExpectedWKBLength = RASTER_HEADER_SIZE +
                                 BAND_SIZE(nPixelSize, nExpectedDataSize);
        if( nWKBLength != nExpectedWKBLength )
        {
            CPLDebug("PostGIS_Raster",
                     "nWKBLength=%d, nExpectedWKBLength=%d",
                     nWKBLength, nExpectedWKBLength );
            return CE_Failure;
        }

        GByte * pbyDataToRead = GET_BAND_DATA(pbyData,1,
                                              nPixelSize,nExpectedDataSize);

        // Do byte-swapping if necessary */
        const bool bIsLittleEndian = (pbyData[0] == 1);
#ifdef CPL_LSB
        const bool bSwap = !bIsLittleEndian;
#else
        const bool bSwap = bIsLittleEndian;
#endif

        if( bSwap && nPixelSize > 1 )
        {
            GDALSwapWords( pbyDataToRead, nPixelSize,
                           nBlockXSize * nBlockYSize,
                           nPixelSize );
        }

        memcpy(pImage, pbyDataToRead, nExpectedDataSize);
    }
    else
    {
        int nCurOffset = RASTER_HEADER_SIZE;
        if( !poRTDS->poRDS->LoadOutdbRaster(nCurOffset, eDataType, nBand,
                                             pbyData,
                                             nWKBLength,
                                             pImage,
                                             dfTileUpperLeftX,
                                             dfTileUpperLeftY,
                                             dfTileResX,
                                             dfTileResY,
                                             nTileXSize,
                                             nTileYSize) )
        {
            return CE_Failure;
        }
    }


    return CE_None;
}