Example #1
0
/* Parses a JPEG file and extracts the resolution data from it, and
   returns a newly allocated JPG_Info structure.
*/
JPG_Info * Parse_JPG(const char * file) 
{

  FILE * f = fopen(file, "rb");
  if(! f)
    return NULL;

  int eof = 0;
  int tag = read_next_tag(f, &eof);
  if(tag != 0xD8 || eof) {
    fclose(f);
    return NULL;
  }

  while(1) {
    tag = read_next_tag(f, &eof);
    if(eof)  {
      fclose(f);
      return NULL;
    }
    switch(tag) {
    case 0xC0: /* image data */
      {
        int len = read_word(f, &eof);
        int bps = read_byte(f, &eof);
        int y = read_word(f, &eof);
        int x = read_word(f, &eof);
        int cmps = read_byte(f, &eof);
        fclose(f);
        if(eof)
          return NULL;
          
        JPG_Info * val = (JPG_Info *)calloc(1, sizeof(JPG_Info));
        val->filename = ALLOC_N_char(strlen(file)+1);
        strcpy(val->filename, file);
        val->width = x;
        val->height = y;
        return val;
      }
    default:
      skip_variable_length(f, &eof);
    }
  }
}
Example #2
0
int TerragenDataset::LoadFromFile()
{
    m_dSCAL = 30.0;
    m_nDataOffset = 0;

    if(0 != VSIFSeekL(m_fp, 16, SEEK_SET))
        return FALSE;

    char szTag[4];
    if( !read_next_tag(szTag) || !tag_is(szTag, "SIZE") )
        return FALSE;

    GUInt16 nSize;
    if( !get(nSize) || !skip(2) )
        return FALSE;

    // Set dimensions to SIZE chunk. If we don't
    // encounter XPTS/YPTS chunks, we can assume
    // the terrain to be square.
    GUInt16 xpts = nSize+1;
    GUInt16 ypts = nSize+1;

    while( read_next_tag(szTag) )
    {
        if( tag_is(szTag, "XPTS") )
        {
            get(xpts);
            if( xpts < nSize || !skip(2) )
                return FALSE;
            continue;
        }

        if( tag_is(szTag, "YPTS") )
        {
            get( ypts );
            if( ypts < nSize || !skip(2) )
                return FALSE;
            continue;
        }

        if( tag_is(szTag, "SCAL") )
        {
            float sc[3];
            get(sc[0]);
            get(sc[1]);
            get(sc[2]);
            m_dSCAL = sc[1];
            continue;
        }

        if( tag_is(szTag, "CRAD") )
        {
            if( !skip(sizeof(float)) )
                return FALSE;
            continue;
        }
        if( tag_is(szTag, "CRVM") )
        {
            if( !skip(sizeof(GUInt32)) )
                return FALSE;
            continue;
        }
        if( tag_is(szTag, "ALTW") )
        {
            get(m_nHeightScale);
            get(m_nBaseHeight);
            m_nDataOffset = VSIFTellL(m_fp);
            if( !skip(static_cast<size_t>(xpts) * static_cast<size_t>(ypts) * sizeof(GInt16)) )
                return FALSE;
            continue;
        }
        if( tag_is(szTag, "EOF ") )
        {
            break;
        }
    }


    if(xpts == 0 || ypts == 0 || m_nDataOffset == 0)
        return FALSE;

    nRasterXSize = xpts;
    nRasterYSize = ypts;

    // todo: sanity check: do we have enough pixels?

    // Cache realworld scaling and offset.
    m_dScale = m_dSCAL / 65536 * m_nHeightScale;
    m_dOffset = m_dSCAL * m_nBaseHeight;
    strcpy(m_szUnits, "m");

    // Make our projection to have origin at the
    // NW corner, and groundscale to match elev scale
    // (i.e., uniform voxels).
    m_adfTransform[0] = 0.0;
    m_adfTransform[1] = m_dSCAL;
    m_adfTransform[2] = 0.0;
    m_adfTransform[3] = 0.0;
    m_adfTransform[4] = 0.0;
    m_adfTransform[5] = m_dSCAL;

/* -------------------------------------------------------------------- */
/*      Set projection.							*/
/* -------------------------------------------------------------------- */
    // Terragen files as of Apr 2006 are partially georeferenced,
    // we can declare a local coordsys that uses meters.
    OGRSpatialReference sr;

    sr.SetLocalCS("Terragen world space");
    if(OGRERR_NONE != sr.SetLinearUnits("m", 1.0))
        return FALSE;

    if(OGRERR_NONE != sr.exportToWkt(&m_pszProjection))
        return FALSE;

    return TRUE;
}