Exemple #1
0
/**
 * Constructor for the GuiImageData class.
 */
GuiImageData::GuiImageData(const u8 * i, int maxw, int maxh)
{
    data = NULL;
    width = 0;
    height = 0;

    if(i)
        data = DecodePNG(i, &width, &height, data, maxw, maxh);
}
RasterMapTile *RasterMapManager::GetTile(const unsigned int zoom, const unsigned int x, const unsigned int y) {
    if (m_Ready) {
        // Compute what file our tile is in (as implemented, this is dependent on MGM_CACHE_TILES_PER_FILE == 32)
        unsigned int absX = x >> 3, absY = y >> 2;
        unsigned char relX = x - absX * 8, relY = y - absY * 4;

        // Work out the file name
        static char filenameBuf[1024];
        if (snprintf(filenameBuf, sizeof(filenameBuf), "%s/%s_%d/%d_%d.mgm",
                    m_CachePrefix.c_str(), m_MapType.c_str(), zoom, absX, absY) == sizeof(filenameBuf)) {
            LogPrintf("RasterMapManager: Could not work out what file the requested tile is in.\n");
            return NULL;
        }

        // Get the file
        FILE *mgmFile = fopen(filenameBuf, "rb");
        if (!mgmFile) {
            LogPrintf("RasterMapManager: Provided cache does not contain requested tile, ignoring\n");
            return NULL;
        }

        // Read MGMaps header
        static unsigned char mgmapsHeader[2 + 6 * MGM_CACHE_TILES_PER_FILE];
        if (fread(mgmapsHeader, 1, sizeof(mgmapsHeader), mgmFile) != sizeof(mgmapsHeader)) {
            LogPrintf("RasterMapsManager: could not read MGMaps tile cache file header\n");
            return NULL;
        }

        // Parse MGMaps header, searching for desired tile
        unsigned int nextOffset = sizeof(mgmapsHeader), offset = 0;
        int numTiles = mgmapsHeader[0] << 8 | mgmapsHeader[1];
        Assert(numTiles >= 1 && numTiles <= MGM_CACHE_TILES_PER_FILE, "wrong number of tiles in cache file");
        for (int i = 0; i < numTiles; ++i) {
            MGMHeaderChunk *tmp = (MGMHeaderChunk*)(&mgmapsHeader[2 + i * sizeof(MGMHeaderChunk)]);
            offset = nextOffset;
            nextOffset = CHUNK_NEXT_OFFSET(tmp);
            if (tmp->relX == relX && tmp->relY == relY) {
                unsigned int length = nextOffset - offset;
                // Check that the computed length is sane
                fseek(mgmFile, 0, SEEK_END);
                if (ftell(mgmFile) < nextOffset) {
                    LogPrintf("RasterMapsManager: error parsing MGMaps header (bad size)\n");
                    return NULL;
                }

                // Check read buffer is big enough to hold tile
                if (length >= READ_BUFFER_SIZE) {
                    LogPrintf("RasterMapManager: can't read JPEG longer than read buffer; probable malformed cache.\n");
                    return NULL;
                }

                // Get the tile from the cachefile
                fseek(mgmFile, offset, SEEK_SET);
                if (length != fread(m_ReadBuffer, 1, length, mgmFile)) {
                    LogPrintf("RasterMapManager: end of file reached before JPEG was completely read, malformed cache.\n");
                    return NULL;
                }
                fclose(mgmFile);

                // Decode the tile
                unsigned int width = 0, height = 0;
                unsigned char *img = DecodePNG(m_ReadBuffer, length, width, height);
                return img ? new RasterMapTile(img, width, height) : NULL;
            }
        }
        fclose(mgmFile);
    }
    LogPrintf("RasterMapsManager: could not find requested file in tile cache\n");
    return NULL;
}