/* 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); } } }
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; }