int SDTSRasterReader::GetBlock( int nXOffset, int nYOffset, void * pData ) { DDFRecord *poRecord = NULL; int nBytesPerValue; int iTry; CPLAssert( nXOffset == 0 ); /* -------------------------------------------------------------------- */ /* Analyse the datatype. */ /* -------------------------------------------------------------------- */ CPLAssert( EQUAL(szFMT,"BI16") || EQUAL(szFMT,"BFP32") ); if( EQUAL(szFMT,"BI16") ) nBytesPerValue = 2; else nBytesPerValue = 4; for(iTry=0;iTry<2;iTry++) { /* -------------------------------------------------------------------- */ /* Read through till we find the desired record. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); while( (poRecord = oDDFModule.ReadRecord()) != NULL ) { if( poRecord->GetIntSubfield( "CELL", 0, "ROWI", 0 ) == nYOffset + nYStart ) { break; } } if( CPLGetLastErrorType() == CE_Failure ) return FALSE; /* -------------------------------------------------------------------- */ /* If we didn't get what we needed just start over. */ /* -------------------------------------------------------------------- */ if( poRecord == NULL ) { if (iTry == 0) oDDFModule.Rewind(); else { CPLError( CE_Failure, CPLE_AppDefined, "Cannot read scanline %d. Raster access failed.\n", nYOffset ); return FALSE; } } else { break; } } /* -------------------------------------------------------------------- */ /* Validate the records size. Does it represent exactly one */ /* scanline? */ /* -------------------------------------------------------------------- */ DDFField *poCVLS; poCVLS = poRecord->FindField( "CVLS" ); if( poCVLS == NULL ) return FALSE; if( poCVLS->GetRepeatCount() != nXSize ) { CPLError( CE_Failure, CPLE_AppDefined, "Cell record is %d long, but we expected %d, the number\n" "of pixels in a scanline. Raster access failed.\n", poCVLS->GetRepeatCount(), nXSize ); return FALSE; } /* -------------------------------------------------------------------- */ /* Does the CVLS field consist of exactly 1 B(16) field? */ /* -------------------------------------------------------------------- */ if( poCVLS->GetDataSize() < nBytesPerValue * nXSize || poCVLS->GetDataSize() > nBytesPerValue * nXSize + 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Cell record is not of expected format. Raster access " "failed.\n" ); return FALSE; } /* -------------------------------------------------------------------- */ /* Copy the data to the application buffer, and byte swap if */ /* required. */ /* -------------------------------------------------------------------- */ memcpy( pData, poCVLS->GetData(), nXSize * nBytesPerValue ); #ifdef CPL_LSB if( nBytesPerValue == 2 ) { for( int i = 0; i < nXSize; i++ ) { ((GInt16 *) pData)[i] = CPL_MSBWORD16(((GInt16 *) pData)[i]); } } else { for( int i = 0; i < nXSize; i++ ) { CPL_MSBPTR32( ((GByte *)pData) + i*4 ); } } #endif return TRUE; }
GDALDataset *SGIDataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, CPL_UNUSED char **papszOptions ) { if( eType != GDT_Byte ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create SGI dataset with an illegal\n" "data type (%s), only Byte supported by the format.\n", GDALGetDataTypeName(eType) ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the file for output. */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( pszFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create file '%s': %s", pszFilename, VSIStrerror( errno ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Prepare and write 512 byte header. */ /* -------------------------------------------------------------------- */ GByte abyHeader[512]; GInt16 nShortValue; GInt32 nIntValue; memset( abyHeader, 0, 512 ); abyHeader[0] = 1; abyHeader[1] = 218; abyHeader[2] = 1; // RLE abyHeader[3] = 1; // 8bit if( nBands == 1 ) nShortValue = CPL_MSBWORD16(2); else nShortValue = CPL_MSBWORD16(3); memcpy( abyHeader + 4, &nShortValue, 2 ); nShortValue = CPL_MSBWORD16(nXSize); memcpy( abyHeader + 6, &nShortValue, 2 ); nShortValue = CPL_MSBWORD16(nYSize); memcpy( abyHeader + 8, &nShortValue, 2 ); nShortValue = CPL_MSBWORD16(nBands); memcpy( abyHeader + 10, &nShortValue, 2 ); nIntValue = CPL_MSBWORD32(0); memcpy( abyHeader + 12, &nIntValue, 4 ); nIntValue = CPL_MSBWORD32(255); memcpy( abyHeader + 16, &nIntValue, 4 ); VSIFWriteL( abyHeader, 1, 512, fp ); /* -------------------------------------------------------------------- */ /* Create our RLE compressed zero-ed dummy line. */ /* -------------------------------------------------------------------- */ GByte *pabyRLELine; GInt32 nRLEBytes = 0; int nPixelsRemaining = nXSize; pabyRLELine = (GByte *) CPLMalloc((nXSize/127) * 2 + 4); while( nPixelsRemaining > 0 ) { pabyRLELine[nRLEBytes] = (GByte) MIN(127,nPixelsRemaining); pabyRLELine[nRLEBytes+1] = 0; nPixelsRemaining -= pabyRLELine[nRLEBytes]; nRLEBytes += 2; } /* -------------------------------------------------------------------- */ /* Prepare and write RLE offset/size tables with everything */ /* zeroed indicating dummy lines. */ /* -------------------------------------------------------------------- */ int i; int nTableLen = nYSize * nBands; GInt32 nDummyRLEOffset = 512 + 4 * nTableLen * 2; CPL_MSBPTR32( &nRLEBytes ); CPL_MSBPTR32( &nDummyRLEOffset ); for( i = 0; i < nTableLen; i++ ) VSIFWriteL( &nDummyRLEOffset, 1, 4, fp ); for( i = 0; i < nTableLen; i++ ) VSIFWriteL( &nRLEBytes, 1, 4, fp ); /* -------------------------------------------------------------------- */ /* write the dummy RLE blank line. */ /* -------------------------------------------------------------------- */ CPL_MSBPTR32( &nRLEBytes ); if( (GInt32) VSIFWriteL( pabyRLELine, 1, nRLEBytes, fp ) != nRLEBytes ) { CPLError( CE_Failure, CPLE_FileIO, "Failure writing SGI file '%s'.\n%s", pszFilename, VSIStrerror( errno ) ); return NULL; } VSIFCloseL( fp ); CPLFree( pabyRLELine ); return (GDALDataset*) GDALOpen( pszFilename, GA_Update ); }