Пример #1
0
const char *MIDDATAFile::GetLine()
{
    const char *pszLine;
    
    if (m_eAccessMode == TABRead)
    {
        
        pszLine = CPLReadLine(m_fp);

        SetEof(VSIFEof(m_fp));

        if (pszLine == NULL)
        {
            m_szLastRead[0] = '\0';
        }
        else
        {
            // skip leading spaces
            while(pszLine && (*pszLine == ' ' || *pszLine == '\t') )
                pszLine++;

            strncpy(m_szLastRead,pszLine,MIDMAXCHAR);
        }
        //if (pszLine)
        //  printf("%s\n",pszLine);
        return pszLine;
    }
    else
    {
      CPLAssert(FALSE);
    }
    return NULL;
}
Пример #2
0
int MIDDATAFile::Rewind()
{
    if (m_fp == NULL || m_eAccessMode == TABWrite) 
        return -1;

    else
    {
        VSIRewind(m_fp);
        SetEof(VSIFEof(m_fp));
    }
    return 0;
}
Пример #3
0
/**********************************************************************
 *                          AVCRawBinEOF()
 *
 * Return TRUE if there is no more data to read from the file or
 * FALSE otherwise.
 **********************************************************************/
GBool AVCRawBinEOF(AVCRawBinFile *psFile)
{
    if (psFile == NULL || psFile->fp == NULL)
        return TRUE;

    /* In write access mode, always return TRUE, since we always write
     * at EOF for now.
     */
    if (psFile->eAccess != AVCRead && psFile->eAccess != AVCReadWrite)
        return TRUE;

    /* If file data size was specified, then check that we have not
     * passed that point yet...
     */
    if (psFile->nFileDataSize > 0 &&
        (psFile->nOffset+psFile->nCurPos) >= psFile->nFileDataSize)
        return TRUE;

    /* If the file pointer has been moved by AVCRawBinFSeek(), then
     * we may be at a position past EOF, but VSIFeof() would still
     * return FALSE. It also returns false if we have read just up to
     * the end of the file. EOF marker would not have been set unless
     * we try to read past that.
     *
     * To prevent this situation, if the memory buffer is empty,
     * we will try to read 1 byte from the file to force the next
     * chunk of data to be loaded (and we'll move the read pointer
     * back by 1 char after of course!).
     * If we are at the end of the file, this will trigger the EOF flag.
     */
    if ((psFile->nCurPos == 0 && psFile->nCurSize == 0) ||
        (psFile->nCurPos == AVCRAWBIN_READBUFSIZE &&
         psFile->nCurSize == AVCRAWBIN_READBUFSIZE))
    {
        GByte c;
        /* Set bDisableReadBytesEOFError=TRUE to temporarily disable
         * the EOF error message from AVCRawBinReadBytes().
         */
        bDisableReadBytesEOFError = TRUE;
        AVCRawBinReadBytes(psFile, 1, &c);
        bDisableReadBytesEOFError = FALSE;

        if (psFile->nCurPos > 0)
            AVCRawBinFSeek(psFile, -1, SEEK_CUR);
    }

    return (psFile->nCurPos == psFile->nCurSize &&
            VSIFEof(psFile->fp));
}
Пример #4
0
int MIDDATAFile::Open(const char *pszFname, const char *pszAccess)
{
   if (m_fp)
   {
       return -1;
   }

    /*-----------------------------------------------------------------
     * Validate access mode and make sure we use Text access.
     *----------------------------------------------------------------*/
    if (EQUALN(pszAccess, "r", 1))
    {
        m_eAccessMode = TABRead;
        pszAccess = "rt";
    }
    else if (EQUALN(pszAccess, "w", 1))
    {
        m_eAccessMode = TABWrite;
        pszAccess = "wt";
    }
    else
    {
        return -1;
    }

    /*-----------------------------------------------------------------
     * Open file for reading
     *----------------------------------------------------------------*/
    m_pszFname = CPLStrdup(pszFname);
    m_fp = VSIFOpen(m_pszFname, pszAccess);

    if (m_fp == NULL)
    {
        CPLFree(m_pszFname);
        m_pszFname = NULL;
        return -1;
    }

    SetEof(VSIFEof(m_fp));
    return 0;
}
Пример #5
0
GDALDataset *RIKDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    bool rik3header = false;

    if( EQUALN((const char *) poOpenInfo->pabyHeader, "RIK3", 4) )
    {
        rik3header = true;
    }

    if( rik3header )
        VSIFSeek( poOpenInfo->fp, 4, SEEK_SET );
    else
        VSIFSeek( poOpenInfo->fp, 0, SEEK_SET );

/* -------------------------------------------------------------------- */
/*      Read the map name.                                              */
/* -------------------------------------------------------------------- */

    char name[1024];

    GUInt16 nameLength = GetRikString( poOpenInfo->fp, name, sizeof(name) );

    if( nameLength > sizeof(name) - 1 )
    {
        return NULL;
    }

    if( !rik3header )
    {
        if( nameLength == 0 || nameLength != strlen(name) )
            return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */

    RIKHeader header;
    double metersPerPixel;

    const char *headerType = "RIK3";

    if( rik3header )
    {
/* -------------------------------------------------------------------- */
/*      RIK3 header.                                                    */
/* -------------------------------------------------------------------- */

        // Read projection name

        char projection[1024];

        GUInt16 projLength = GetRikString( poOpenInfo->fp,
                                           projection, sizeof(projection) );

        if( projLength > sizeof(projection) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        // Read unknown string

        projLength = GetRikString( poOpenInfo->fp, projection, sizeof(projection) );

        // Read map north edge

        char tmpStr[16];

        GUInt16 tmpLength = GetRikString( poOpenInfo->fp,
                                          tmpStr, sizeof(tmpStr) );

        if( tmpLength > sizeof(tmpStr) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        header.fNorth = atof( tmpStr );

        // Read map west edge

        tmpLength = GetRikString( poOpenInfo->fp,
                                  tmpStr, sizeof(tmpStr) );

        if( tmpLength > sizeof(tmpStr) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        header.fWest = atof( tmpStr );

        // Read binary values

        VSIFRead( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fp );
        VSIFRead( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fp );
        VSIFRead( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fp );
        VSIFRead( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fp );
        VSIFRead( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fp );
        VSIFRead( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fp );
#ifdef CPL_MSB
        CPL_SWAP32PTR( &header.iScale );
        CPL_SWAP32PTR( &header.iMPPNum );
        CPL_SWAP32PTR( &header.iBlockWidth );
        CPL_SWAP32PTR( &header.iBlockHeight );
        CPL_SWAP32PTR( &header.iHorBlocks );
        CPL_SWAP32PTR( &header.iVertBlocks );
#endif

        VSIFRead( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fp );
        VSIFRead( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fp );
        header.iUnknown = header.iOptions;
        VSIFRead( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fp );

        header.fSouth = header.fNorth -
            header.iVertBlocks * header.iBlockHeight * header.iMPPNum;
        header.fEast = header.fWest +
            header.iHorBlocks * header.iBlockWidth * header.iMPPNum;

        metersPerPixel = header.iMPPNum;
    }
    else
    {
/* -------------------------------------------------------------------- */
/*      Old RIK header.                                                 */
/* -------------------------------------------------------------------- */

        VSIFRead( &header.iUnknown, 1, sizeof(header.iUnknown), poOpenInfo->fp );
        VSIFRead( &header.fSouth, 1, sizeof(header.fSouth), poOpenInfo->fp );
        VSIFRead( &header.fWest, 1, sizeof(header.fWest), poOpenInfo->fp );
        VSIFRead( &header.fNorth, 1, sizeof(header.fNorth), poOpenInfo->fp );
        VSIFRead( &header.fEast, 1, sizeof(header.fEast), poOpenInfo->fp );
        VSIFRead( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fp );
        VSIFRead( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fp );
#ifdef CPL_MSB
        CPL_SWAP64PTR( &header.fSouth );
        CPL_SWAP64PTR( &header.fWest );
        CPL_SWAP64PTR( &header.fNorth );
        CPL_SWAP64PTR( &header.fEast );
        CPL_SWAP32PTR( &header.iScale );
        CPL_SWAP32PTR( &header.iMPPNum );
#endif

        if (!CPLIsFinite(header.fSouth) |
            !CPLIsFinite(header.fWest) |
            !CPLIsFinite(header.fNorth) |
            !CPLIsFinite(header.fEast))
            return NULL;

        bool offsetBounds;

        offsetBounds = header.fSouth < 4000000;

        header.iMPPDen = 1;

        if( offsetBounds )
        {
            header.fSouth += 4002995;
            header.fNorth += 5004000;
            header.fWest += 201000;
            header.fEast += 302005;

            VSIFRead( &header.iMPPDen, 1, sizeof(header.iMPPDen), poOpenInfo->fp );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &header.iMPPDen );
#endif

            headerType = "RIK1";
        }
        else
        {
            headerType = "RIK2";
        }

        metersPerPixel = header.iMPPNum / double(header.iMPPDen);

        VSIFRead( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fp );
        VSIFRead( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fp );
        VSIFRead( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fp );
#ifdef CPL_MSB
        CPL_SWAP32PTR( &header.iBlockWidth );
        CPL_SWAP32PTR( &header.iBlockHeight );
        CPL_SWAP32PTR( &header.iHorBlocks );
#endif

        if(( header.iBlockWidth > 2000 ) || ( header.iBlockWidth < 10 ) ||
           ( header.iBlockHeight > 2000 ) || ( header.iBlockHeight < 10 ))
           return NULL;

        if( !offsetBounds )
        {
            VSIFRead( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fp );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &header.iVertBlocks );
#endif
        }

        if( offsetBounds || !header.iVertBlocks )
        {
            header.iVertBlocks = (GUInt32)
                ceil( (header.fNorth - header.fSouth) /
                      (header.iBlockHeight * metersPerPixel) );
        }

#if RIK_HEADER_DEBUG
        CPLDebug( "RIK",
                  "Original vertical blocks %d\n",
                  header.iVertBlocks );
#endif

        VSIFRead( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fp );

        if( header.iBitsPerPixel != 8 )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "File %s has unsupported number of bits per pixel.\n",
                      poOpenInfo->pszFilename );
            return NULL;
        }

        VSIFRead( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fp );

        if( !header.iHorBlocks || !header.iVertBlocks )
           return NULL;

        if( header.iOptions != 0x00 && // Uncompressed
            header.iOptions != 0x40 && // Uncompressed
            header.iOptions != 0x01 && // RLE
            header.iOptions != 0x41 && // RLE
            header.iOptions != 0x0B && // LZW
            header.iOptions != 0x0D )  // ZLIB
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "File %s. Unknown map options.\n",
                      poOpenInfo->pszFilename );
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Read the palette.                                               */
/* -------------------------------------------------------------------- */

    GByte palette[768];

    GUInt16 i;
    for( i = 0; i < 256; i++ )
    {
        VSIFRead( &palette[i * 3 + 2], 1, 1, poOpenInfo->fp );
        VSIFRead( &palette[i * 3 + 1], 1, 1, poOpenInfo->fp );
        VSIFRead( &palette[i * 3 + 0], 1, 1, poOpenInfo->fp );
    }

/* -------------------------------------------------------------------- */
/*      Find block offsets.                                             */
/* -------------------------------------------------------------------- */

    GUInt32 blocks;
    GUInt32 *offsets;

    blocks = header.iHorBlocks * header.iVertBlocks;
    offsets = (GUInt32 *)CPLMalloc( blocks * sizeof(GUInt32) );

    if( !offsets )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s. Unable to allocate offset table.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    if( header.iOptions == 0x00 )
    {
        offsets[0] = VSIFTell( poOpenInfo->fp );

        for( GUInt32 i = 1; i < blocks; i++ )
        {
            offsets[i] = offsets[i - 1] +
                header.iBlockWidth * header.iBlockHeight;
        }
    }
    else
    {
        for( GUInt32 i = 0; i < blocks; i++ )
        {
            VSIFRead( &offsets[i], 1, sizeof(offsets[i]), poOpenInfo->fp );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &offsets[i] );
#endif
            if( rik3header )
            {
                GUInt32 blockSize;
                VSIFRead( &blockSize, 1, sizeof(blockSize), poOpenInfo->fp );
#ifdef CPL_MSB
                CPL_SWAP32PTR( &blockSize );
#endif
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Final checks.                                                   */
/* -------------------------------------------------------------------- */

    // File size

    if( VSIFEof( poOpenInfo->fp ) )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s. Read past end of file.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    VSIFSeek( poOpenInfo->fp, 0, SEEK_END );
    GUInt32 fileSize = VSIFTell( poOpenInfo->fp );

#if RIK_HEADER_DEBUG
    CPLDebug( "RIK",
              "File size %d\n",
              fileSize );
#endif

    // Make sure the offset table is valid

    GUInt32 lastoffset = 0;

    for( GUInt32 y = 0; y < header.iVertBlocks; y++)
    {
        for( GUInt32 x = 0; x < header.iHorBlocks; x++)
        {
            if( !offsets[x + y * header.iHorBlocks] )
            {
                continue;
            }

            if( offsets[x + y * header.iHorBlocks] >= fileSize )
            {
                if( !y )
                {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                              "File %s too short.\n",
                              poOpenInfo->pszFilename );
                    return NULL;
                }
                header.iVertBlocks = y;
                break;
            }

            if( offsets[x + y * header.iHorBlocks] < lastoffset )
            {
                if( !y )
                {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                              "File %s. Corrupt offset table.\n",
                              poOpenInfo->pszFilename );
                    return NULL;
                }
                header.iVertBlocks = y;
                break;
            }

            lastoffset = offsets[x + y * header.iHorBlocks];
        }
    }

#if RIK_HEADER_DEBUG
    CPLDebug( "RIK",
              "first offset %d\n"
              "last offset %d\n",
              offsets[0],
              lastoffset );
#endif

    const char *compression = "RLE";

    if( header.iOptions == 0x00 ||
        header.iOptions == 0x40 )
        compression = "Uncompressed";
    if( header.iOptions == 0x0b )
        compression = "LZW";
    if( header.iOptions == 0x0d )
        compression = "ZLIB";

    CPLDebug( "RIK",
              "RIK file parameters:\n"
              " name: %s\n"
              " header: %s\n"
              " unknown: 0x%X\n"
              " south: %f\n"
              " west: %f\n"
              " north: %f\n"
              " east: %f\n"
              " original scale: %d\n"
              " meters per pixel: %f\n"
              " block width: %d\n"
              " block height: %d\n"
              " horizontal blocks: %d\n"
              " vertical blocks: %d\n"
              " bits per pixel: %d\n"
              " options: 0x%X\n"
              " compression: %s\n",
              name, headerType, header.iUnknown,
              header.fSouth, header.fWest, header.fNorth, header.fEast,
              header.iScale, metersPerPixel,
              header.iBlockWidth, header.iBlockHeight,
              header.iHorBlocks, header.iVertBlocks,
              header.iBitsPerPixel, header.iOptions, compression);

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */

    RIKDataset 	*poDS;

    poDS = new RIKDataset();

    poDS->fp = poOpenInfo->fp;
    poOpenInfo->fp = NULL;

    poDS->fTransform[0] = header.fWest - metersPerPixel / 2.0;
    poDS->fTransform[1] = metersPerPixel;
    poDS->fTransform[2] = 0.0;
    poDS->fTransform[3] = header.fNorth + metersPerPixel / 2.0;
    poDS->fTransform[4] = 0.0;
    poDS->fTransform[5] = -metersPerPixel;

    poDS->nBlockXSize = header.iBlockWidth;
    poDS->nBlockYSize = header.iBlockHeight;
    poDS->nHorBlocks = header.iHorBlocks;
    poDS->nVertBlocks = header.iVertBlocks;
    poDS->pOffsets = offsets;
    poDS->options = header.iOptions;
    poDS->nFileSize = fileSize;

    poDS->nRasterXSize = header.iBlockWidth * header.iHorBlocks;
    poDS->nRasterYSize = header.iBlockHeight * header.iVertBlocks;

    poDS->nBands = 1;

    GDALColorEntry oEntry;
    poDS->poColorTable = new GDALColorTable();
    for( i = 0; i < 256; i++ )
    {
        oEntry.c1 = palette[i * 3 + 2]; // Red
        oEntry.c2 = palette[i * 3 + 1]; // Green
        oEntry.c3 = palette[i * 3];     // Blue
        oEntry.c4 = 255;

        poDS->poColorTable->SetColorEntry( i, &oEntry );
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */

    poDS->SetBand( 1, new RIKRasterBand( poDS, 1 ));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */

    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for external overviews.                                   */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles );

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The RIK driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
    return( poDS );
}
Пример #6
0
CPLErr RIKRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
    RIKDataset *poRDS = (RIKDataset *) poDS;
    GByte *blockData;
    GUInt32 blocks;
    GUInt32 nBlockIndex;
    GUInt32 nBlockOffset;
    GUInt32 nBlockSize;

    blocks = poRDS->nHorBlocks * poRDS->nVertBlocks;
    nBlockIndex = nBlockXOff + nBlockYOff * poRDS->nHorBlocks;
    nBlockOffset = poRDS->pOffsets[nBlockIndex];

    nBlockSize = poRDS->nFileSize;
    for( GUInt32 bi = nBlockIndex + 1; bi < blocks; bi++ )
    {
        if( poRDS->pOffsets[bi] )
        {
            nBlockSize = poRDS->pOffsets[bi];
            break;
        }
    }
    nBlockSize -= nBlockOffset;

    GUInt32 pixels;

    pixels = poRDS->nBlockXSize * poRDS->nBlockYSize;

    if( !nBlockOffset || !nBlockSize
#ifdef RIK_SINGLE_BLOCK
        || nBlockIndex != RIK_SINGLE_BLOCK
#endif
        )
    {
        for( GUInt32 i = 0; i < pixels; i++ )
        ((GByte *) pImage)[i] = 0;
        return CE_None;
    }

    VSIFSeek( poRDS->fp, nBlockOffset, SEEK_SET );

/* -------------------------------------------------------------------- */
/*      Read uncompressed block.                                        */
/* -------------------------------------------------------------------- */

    if( poRDS->options == 0x00 || poRDS->options == 0x40 )
    {
        VSIFRead( pImage, 1, nBlockSize, poRDS->fp );
        return CE_None;
    }

    // Read block to memory
    blockData = (GByte *) CPLMalloc(nBlockSize);
    VSIFRead( blockData, 1, nBlockSize, poRDS->fp );

    GUInt32 filePos = 0;
    GUInt32 imagePos = 0;

/* -------------------------------------------------------------------- */
/*      Read RLE block.                                                 */
/* -------------------------------------------------------------------- */

    if( poRDS->options == 0x01 ||
        poRDS->options == 0x41 ) do
    {
        GByte count = blockData[filePos++];
        GByte color = blockData[filePos++];

        for (GByte i = 0; i <= count; i++)
        {
            ((GByte *) pImage)[imagePos++] = color;
        }
    } while( filePos < nBlockSize && imagePos < pixels );

/* -------------------------------------------------------------------- */
/*      Read LZW block.                                                 */
/* -------------------------------------------------------------------- */

    else if( poRDS->options == 0x0b )
    {
        const bool LZW_HAS_CLEAR_CODE = !!(blockData[4] & 0x80);
        const int LZW_MAX_BITS = blockData[4] & 0x1f; // Max 13
        const int LZW_BITS_PER_PIXEL = 8;
        const int LZW_OFFSET = 5;

        const int LZW_CLEAR = 1 << LZW_BITS_PER_PIXEL;
        const int LZW_CODES = 1 << LZW_MAX_BITS;
        const int LZW_NO_SUCH_CODE = LZW_CODES + 1;

        int lastAdded = LZW_HAS_CLEAR_CODE ? LZW_CLEAR : LZW_CLEAR - 1;
        int codeBits = LZW_BITS_PER_PIXEL + 1;

        int code;
        int lastCode;
        GByte lastOutput;
        int bitsTaken = 0;

        int prefix[8192];      // only need LZW_CODES for size.
        GByte character[8192]; // only need LZW_CODES for size.

        int i;

        for( i = 0; i < LZW_CLEAR; i++ )
            character[i] = (GByte)i;
        for( i = 0; i < LZW_CODES; i++ )
            prefix[i] = LZW_NO_SUCH_CODE;

        filePos = LZW_OFFSET;
        GUInt32 fileAlign = LZW_OFFSET;
        int imageLine = poRDS->nBlockYSize - 1;

        GUInt32 lineBreak = poRDS->nBlockXSize;

        // 32 bit alignment
        lineBreak += 3;
        lineBreak &= 0xfffffffc;

        code = GetNextLZWCode( codeBits, blockData, filePos,
                               fileAlign, bitsTaken );

        OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize,
                     lineBreak, imageLine, imagePos );
        lastOutput = (GByte)code;

        while( imageLine >= 0 &&
               (imageLine || imagePos < poRDS->nBlockXSize) &&
               filePos < nBlockSize ) try
        {
            lastCode = code;
            code = GetNextLZWCode( codeBits, blockData,
                                   filePos, fileAlign, bitsTaken );
            if( VSIFEof( poRDS->fp ) )
            {
                CPLFree( blockData );
                CPLError( CE_Failure, CPLE_AppDefined,
                          "RIK decompression failed. "
                          "Read past end of file.\n" );
                return CE_Failure;
            }

            if( LZW_HAS_CLEAR_CODE && code == LZW_CLEAR )
            {
#if RIK_CLEAR_DEBUG
                CPLDebug( "RIK",
                          "Clearing block %d\n"
                          " x=%d y=%d\n"
                          " pos=%d size=%d\n",
                          nBlockIndex,
                          imagePos, imageLine,
                          filePos, nBlockSize );
#endif

                // Clear prefix table
                for( i = LZW_CLEAR; i < LZW_CODES; i++ )
                    prefix[i] = LZW_NO_SUCH_CODE;
                lastAdded = LZW_CLEAR;
                codeBits = LZW_BITS_PER_PIXEL + 1;

                filePos = fileAlign;
                bitsTaken = 0;

                code = GetNextLZWCode( codeBits, blockData,
                                       filePos, fileAlign, bitsTaken );

                if( code > lastAdded )
                {
                    throw "Clear Error";
                }

                OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize,
                             lineBreak, imageLine, imagePos );
                lastOutput = (GByte)code;
            }
            else
            {
                // Set-up decoding

                GByte stack[8192]; // only need LZW_CODES for size.

                int stackPtr = 0;
                int decodeCode = code;

                if( code == lastAdded + 1 )
                {
                    // Handle special case
                    *stack = lastOutput;
                    stackPtr = 1;
                    decodeCode = lastCode;
       	        }
                else if( code > lastAdded + 1 )
                {
                    throw "Too high code";
                }

                // Decode

                i = 0;
                while( ++i < LZW_CODES &&
       	               decodeCode >= LZW_CLEAR &&
       	               decodeCode < LZW_NO_SUCH_CODE )
                {
                    stack[stackPtr++] = character[decodeCode];
                    decodeCode = prefix[decodeCode];
                }
                stack[stackPtr++] = (GByte)decodeCode;

                if( i == LZW_CODES || decodeCode >= LZW_NO_SUCH_CODE )
                {
                    throw "Decode error";
                }

                // Output stack

                lastOutput = stack[stackPtr - 1];

                while( stackPtr != 0 && imagePos < pixels )
                {
                    OutputPixel( stack[--stackPtr], pImage, poRDS->nBlockXSize,
                                 lineBreak, imageLine, imagePos );
                }

                // Add code to string table

                if( lastCode != LZW_NO_SUCH_CODE &&
                    lastAdded != LZW_CODES - 1 )
                {
                    prefix[++lastAdded] = lastCode;
                    character[lastAdded] = lastOutput;
                }

                // Check if we need to use more bits

                if( lastAdded == (1 << codeBits) - 1 &&
                    codeBits != LZW_MAX_BITS )
                {
                     codeBits++;

                     filePos = fileAlign;
                     bitsTaken = 0;
                }
            }
        }
        catch (const char *errStr)
        {
#if RIK_ALLOW_BLOCK_ERRORS
                CPLDebug( "RIK",
                          "LZW Decompress Failed: %s\n"
                          " blocks: %d\n"
                          " blockindex: %d\n"
                          " blockoffset: %X\n"
                          " blocksize: %d\n",
                          errStr, blocks, nBlockIndex,
                          nBlockOffset, nBlockSize );
                break;
#else
                CPLFree( blockData );
                CPLError( CE_Failure, CPLE_AppDefined,
                          "RIK decompression failed. "
                          "Corrupt image block." );
                return CE_Failure;
#endif
        }
    }

/* -------------------------------------------------------------------- */
/*      Read ZLIB block.                                                */
/* -------------------------------------------------------------------- */

    else if( poRDS->options == 0x0d )
    {
        uLong destLen = pixels;
        Byte *upsideDown = (Byte *) CPLMalloc( pixels );

        uncompress( upsideDown, &destLen, blockData, nBlockSize );

        for (GUInt32 i = 0; i < poRDS->nBlockYSize; i++)
        {
            memcpy( ((Byte *)pImage) + poRDS->nBlockXSize * i,
                    upsideDown + poRDS->nBlockXSize *
                                 (poRDS->nBlockYSize - i - 1),
                    poRDS->nBlockXSize );
        }

        CPLFree( upsideDown );
    }

    CPLFree( blockData );

    return CE_None;
}
Пример #7
0
int NTFRecord::ReadPhysicalLine( FILE *fp, char *pszLine )

{
    int         nBytesRead = 0;
    int         nRecordStart, nRecordEnd, i, nLength = 0;

/* -------------------------------------------------------------------- */
/*      Read enough data that we are sure we have a whole record.       */
/* -------------------------------------------------------------------- */
    nRecordStart = VSIFTell( fp );
    nBytesRead = VSIFRead( pszLine, 1, MAX_RECORD_LEN+2, fp );

    if( nBytesRead == 0 )
    {
        if( VSIFEof( fp ) )
            return -1;
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Low level read error occured while reading NTF file." );
            return -2;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Search for CR or LF.                                            */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nBytesRead; i++ )
    {
        if( pszLine[i] == 10 || pszLine[i] == 13 )
            break;
    }

/* -------------------------------------------------------------------- */
/*      If we don't find EOL within 80 characters something has gone    */
/*      badly wrong!                                                    */
/* -------------------------------------------------------------------- */
    if( i == MAX_RECORD_LEN+2 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "%d byte record too long for NTF format.\n"
                  "No line may be longer than 80 characters though up to %d tolerated.\n",
                  nBytesRead, MAX_RECORD_LEN );
        return -2;
    }

/* -------------------------------------------------------------------- */
/*      Trim CR/LF.                                                     */
/* -------------------------------------------------------------------- */
    nLength = i;
    if( pszLine[i+1] == 10 || pszLine[i+1] == 13 )
        nRecordEnd = nRecordStart + i + 2;
    else
        nRecordEnd = nRecordStart + i + 1;

    pszLine[nLength] = '\0';

/* -------------------------------------------------------------------- */
/*      Restore read pointer to beginning of next record.               */
/* -------------------------------------------------------------------- */
    VSIFSeek( fp, nRecordEnd, SEEK_SET );
    
    return nLength;
}
Пример #8
0
int VSIFEofL( FILE * fp )

{
    return VSIFEof( fp );
}