示例#1
0
GDALDataset *PNMDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is a _raw_ ppm or pgm file.  Note, we don't    */
/*      support ascii files, or pbm (1bit) files.                       */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Parse out the tokens from the header.                           */
/* -------------------------------------------------------------------- */
    const char  *pszSrc = (const char *) poOpenInfo->pabyHeader;
    char        szToken[512];
    int         iIn, iToken = 0, nWidth =-1, nHeight=-1, nMaxValue=-1;
    unsigned int iOut;

    iIn = 2;
    while( iIn < poOpenInfo->nHeaderBytes && iToken < 3 )
    {
        iOut = 0;
        szToken[0] = '\0';
        while( iOut < sizeof(szToken) && iIn < poOpenInfo->nHeaderBytes )
        {
            if( pszSrc[iIn] == '#' )
            {
                while( pszSrc[iIn] != 10 && pszSrc[iIn] != 13
                       && iIn < poOpenInfo->nHeaderBytes - 1 )
                    iIn++;
            }

            if( iOut != 0 && isspace((unsigned char)pszSrc[iIn]) )
            {
                szToken[iOut] = '\0';

                if( iToken == 0 )
                    nWidth = atoi(szToken);
                else if( iToken == 1 )
                    nHeight = atoi(szToken);
                else if( iToken == 2 )
                    nMaxValue = atoi(szToken);

                iToken++;
                iIn++;
                break;
            }

            else if( !isspace((unsigned char)pszSrc[iIn]) )
            {
                szToken[iOut++] = pszSrc[iIn];
            }

            iIn++;
        }
    }

    CPLDebug( "PNM", "PNM header contains: width=%d, height=%d, maxval=%d",
              nWidth, nHeight, nMaxValue );

    if( iToken != 3 || nWidth < 1 || nHeight < 1 || nMaxValue < 1 )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    PNMDataset  *poDS;

    poDS = new PNMDataset();

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nHeight;

/* -------------------------------------------------------------------- */
/*      Open file                                                       */
/* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_Update )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within PNM driver.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int         bMSBFirst = TRUE, iPixelSize;
    GDALDataType eDataType;

#ifdef CPL_LSB
    bMSBFirst = FALSE;
#endif

    if ( nMaxValue < 256 )
        eDataType = GDT_Byte;
    else
        eDataType = GDT_UInt16;

    iPixelSize = GDALGetDataTypeSize( eDataType ) / 8;

    if( poOpenInfo->pabyHeader[1] == '5' )
    {
        if (nWidth > INT_MAX / iPixelSize)
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                  "Int overflow occured.");
            delete poDS;
            return NULL;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, iPixelSize,
                                  nWidth*iPixelSize, eDataType, bMSBFirst, TRUE ));
        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_GrayIndex );
    }
    else
    {
        if (nWidth > INT_MAX / (3 * iPixelSize))
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                  "Int overflow occured.");
            delete poDS;
            return NULL;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, 3*iPixelSize,
                                  nWidth*3*iPixelSize, eDataType, bMSBFirst, TRUE ));
        poDS->SetBand(
            2, new RawRasterBand( poDS, 2, poDS->fpImage, iIn+iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst, TRUE ));
        poDS->SetBand(
            3, new RawRasterBand( poDS, 3, poDS->fpImage, iIn+2*iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst, TRUE ));

        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_RedBand );
        poDS->GetRasterBand(2)->SetColorInterpretation( GCI_GreenBand );
        poDS->GetRasterBand(3)->SetColorInterpretation( GCI_BlueBand );
    }

/* -------------------------------------------------------------------- */
/*      Check for world file.                                           */
/* -------------------------------------------------------------------- */
    poDS->bGeoTransformValid = 
        GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
                           poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

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

    return( poDS );
}
示例#2
0
文件: pnmdataset.cpp 项目: OSGeo/gdal
GDALDataset *PNMDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is a _raw_ ppm or pgm file.  Note, we don't    */
/*      support ascii files, or pbm (1bit) files.                       */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Parse out the tokens from the header.                           */
/* -------------------------------------------------------------------- */
    const char *pszSrc = reinterpret_cast<char *>( poOpenInfo->pabyHeader );
    char szToken[512] = { '\0' };
    int iToken = 0;
    int nWidth = -1;
    int nHeight = -1;
    int nMaxValue = -1;

    int iIn = 2;
    while( iIn < poOpenInfo->nHeaderBytes && iToken < 3 )
    {
        unsigned int iOut = 0;
        szToken[0] = '\0';
        while( iOut < sizeof(szToken) && iIn < poOpenInfo->nHeaderBytes )
        {
            if( pszSrc[iIn] == '#' )
            {
                while( iIn < poOpenInfo->nHeaderBytes - 1 &&
                       pszSrc[iIn] != 10 && pszSrc[iIn] != 13 )
                    iIn++;
            }

            if( iOut != 0 && isspace(static_cast<unsigned char>(pszSrc[iIn])) )
            {
                szToken[iOut] = '\0';

                if( iToken == 0 )
                    nWidth = atoi(szToken);
                else if( iToken == 1 )
                    nHeight = atoi(szToken);
                else if( iToken == 2 )
                    nMaxValue = atoi(szToken);

                iToken++;
                iIn++;
                break;
            }

            else if( !isspace(static_cast<unsigned char>(pszSrc[iIn])) )
            {
                szToken[iOut++] = pszSrc[iIn];
            }

            iIn++;
        }
    }

    CPLDebug( "PNM", "PNM header contains: width=%d, height=%d, maxval=%d",
              nWidth, nHeight, nMaxValue );

    if( iToken != 3 || nWidth < 1 || nHeight < 1 || nMaxValue < 1 )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    PNMDataset *poDS = new PNMDataset();

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nHeight;

    // Borrow file pointer
    poDS->fpImage = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
#ifdef CPL_LSB
    const bool bMSBFirst = false;
#else
    const bool bMSBFirst = true;
#endif

    GDALDataType eDataType = GDT_Unknown;
    if ( nMaxValue < 256 )
        eDataType = GDT_Byte;
    else
        eDataType = GDT_UInt16;

    const int iPixelSize = GDALGetDataTypeSizeBytes( eDataType );

    if( poOpenInfo->pabyHeader[1] == '5' )
    {
        if (nWidth > INT_MAX / iPixelSize)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Int overflow occurred.");
            delete poDS;
            return nullptr;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, iPixelSize,
                                  nWidth*iPixelSize, eDataType, bMSBFirst,
                                  RawRasterBand::OwnFP::NO ) );
        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_GrayIndex );
    }
    else
    {
        if (nWidth > INT_MAX / (3 * iPixelSize))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Int overflow occurred.");
            delete poDS;
            return nullptr;
        }
        poDS->SetBand(
            1, new RawRasterBand( poDS, 1, poDS->fpImage, iIn, 3*iPixelSize,
                                  nWidth*3*iPixelSize, eDataType, bMSBFirst,
                                  RawRasterBand::OwnFP::NO ));
        poDS->SetBand(
            2, new RawRasterBand( poDS, 2, poDS->fpImage, iIn+iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst,
                                  RawRasterBand::OwnFP::NO ));
        poDS->SetBand(
            3, new RawRasterBand( poDS, 3, poDS->fpImage, iIn+2*iPixelSize,
                                  3*iPixelSize, nWidth*3*iPixelSize,
                                  eDataType, bMSBFirst,
                                  RawRasterBand::OwnFP::NO ));

        poDS->GetRasterBand(1)->SetColorInterpretation( GCI_RedBand );
        poDS->GetRasterBand(2)->SetColorInterpretation( GCI_GreenBand );
        poDS->GetRasterBand(3)->SetColorInterpretation( GCI_BlueBand );
    }

/* -------------------------------------------------------------------- */
/*      Check for world file.                                           */
/* -------------------------------------------------------------------- */
    poDS->bGeoTransformValid =
        CPL_TO_BOOL(
            GDALReadWorldFile( poOpenInfo->pszFilename, ".wld",
                               poDS->adfGeoTransform ) );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

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

    return poDS;
}