Exemple #1
0
//--------------------------------------------------------------------------------------------
SDL_md2_texcoord_t * load_SDL_md2_texcoord_RW( SDL_RWops * rw, SDL_md2_texcoord_t * pdata, size_t count )
{
    if ( NULL == pdata ) return pdata;

    memset( pdata, 0, count * sizeof( SDL_md2_texcoord_t ) );

    if ( NULL == rw ) return pdata;

    for (size_t i = 0; i < count; i++)
    {
        SDL_md2_texcoord_t * ptex = pdata + i;

        ptex->s = SDL_ReadLE16( rw );
        ptex->t = SDL_ReadLE16( rw );
    }

    return pdata;
}
Exemple #2
0
static bool replay_read_header(Replay *rpy, SDL_RWops *file, int64_t filesize, size_t *ofs, const char *source) {
	uint8_t header[sizeof(replay_magic_header)];
	(*ofs) += sizeof(header);

	SDL_RWread(file, header, sizeof(header), 1);

	if(memcmp(header, replay_magic_header, sizeof(header))) {
		log_warn("%s: Incorrect header", source);
		return false;
	}

	CHECKPROP(rpy->version = SDL_ReadLE16(file), u);
	(*ofs) += 2;

	uint16_t base_version = (rpy->version & ~REPLAY_VERSION_COMPRESSION_BIT);
	bool compression = (rpy->version & REPLAY_VERSION_COMPRESSION_BIT);
	bool gamev_assumed = false;

	switch(base_version) {
		case REPLAY_STRUCT_VERSION_TS101000: {
			// legacy format with no versioning, assume v1.1
			TAISEI_VERSION_SET(&rpy->game_version, 1, 1, 0, 0);
			gamev_assumed = true;
			break;
		}

		case REPLAY_STRUCT_VERSION_TS102000_REV0:
		case REPLAY_STRUCT_VERSION_TS102000_REV1:
		{
			if(taisei_version_read(file, &rpy->game_version) != TAISEI_VERSION_SIZE) {
				log_warn("%s: Failed to read game version", source);
				return false;
			}

			(*ofs) += TAISEI_VERSION_SIZE;
			break;
		}

		default: {
			log_warn("%s: Unknown struct version %u", source, base_version);
			return false;
		}
	}

	char *gamev = taisei_version_tostring(&rpy->game_version);
	log_info("Struct version %u (%scompressed), game version %s%s",
		base_version, compression ? "" : "un", gamev, gamev_assumed ? " (assumed)" : "");
	free(gamev);

	if(compression) {
		CHECKPROP(rpy->fileoffset = SDL_ReadLE32(file), u);
		(*ofs) += 4;
	}

	return true;
}
Exemple #3
0
//--------------------------------------------------------------------------------------------
Uint16 * read_SDL_vecus_RW( SDL_RWops * rw, Uint16 vec[],  size_t count )
{
    if ( NULL == vec ) return vec;

    for ( size_t i = 0; i < count; i++ )
    {
        vec[i] = SDL_ReadLE16( rw );
    }

    return vec;
}
Exemple #4
0
static void replay_read_string(SDL_RWops *file, char **ptr, uint16_t version) {
	size_t len;

	if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
		len = SDL_ReadU8(file);
	} else {
		len = SDL_ReadLE16(file);
	}

	*ptr = malloc(len + 1);
	memset(*ptr, 0, len + 1);

	SDL_RWread(file, *ptr, 1, len);
}
Exemple #5
0
static bool replay_read_meta(Replay *rpy, SDL_RWops *file, int64_t filesize, const char *source) {
	uint16_t version = rpy->version & ~REPLAY_VERSION_COMPRESSION_BIT;

	replay_read_string(file, &rpy->playername, version);
	PRINTPROP(rpy->playername, s);

	if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
		CHECKPROP(rpy->flags = SDL_ReadLE32(file), u);
	}

	CHECKPROP(rpy->numstages = SDL_ReadLE16(file), u);

	if(!rpy->numstages) {
		log_warn("%s: No stages in replay", source);
		return false;
	}

	rpy->stages = malloc(sizeof(ReplayStage) * rpy->numstages);
	memset(rpy->stages, 0, sizeof(ReplayStage) * rpy->numstages);

	for(int i = 0; i < rpy->numstages; ++i) {
		ReplayStage *stg = rpy->stages + i;

		if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
			CHECKPROP(stg->flags = SDL_ReadLE32(file), u);
		}

		CHECKPROP(stg->stage = SDL_ReadLE16(file), u);
		CHECKPROP(stg->seed = SDL_ReadLE32(file), u);
		CHECKPROP(stg->diff = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_points = SDL_ReadLE32(file), u);

		if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
			CHECKPROP(stg->plr_continues_used = SDL_ReadU8(file), u);
		}

		CHECKPROP(stg->plr_char = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_shot = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_pos_x = SDL_ReadLE16(file), u);
		CHECKPROP(stg->plr_pos_y = SDL_ReadLE16(file), u);
		CHECKPROP(stg->plr_focus = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_power = SDL_ReadLE16(file), u);
		CHECKPROP(stg->plr_lives = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_life_fragments = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_bombs = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_bomb_fragments = SDL_ReadU8(file), u);
		CHECKPROP(stg->plr_inputflags = SDL_ReadU8(file), u);
		CHECKPROP(stg->numevents = SDL_ReadLE16(file), u);

		if(replay_calc_stageinfo_checksum(stg, version) + SDL_ReadLE32(file)) {
			log_warn("%s: Stageinfo is corrupt", source);
			return false;
		}
	}

	return true;
}
Exemple #6
0
static bool replay_read_events(Replay *rpy, SDL_RWops *file, int64_t filesize, const char *source) {
	for(int i = 0; i < rpy->numstages; ++i) {
		ReplayStage *stg = rpy->stages + i;

		if(!stg->numevents) {
			log_warn("%s: No events in stage", source);
			return false;
		}

		stg->events = malloc(sizeof(ReplayEvent) * stg->numevents);
		memset(stg->events, 0, sizeof(ReplayEvent) * stg->numevents);

		for(int j = 0; j < stg->numevents; ++j) {
			ReplayEvent *evt = stg->events + j;

			CHECKPROP(evt->frame = SDL_ReadLE32(file), u);
			CHECKPROP(evt->type = SDL_ReadU8(file), u);
			CHECKPROP(evt->value = SDL_ReadLE16(file), u);
		}
	}

	return true;
}
SDL_Surface *
SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
{
    SDL_bool was_error;
    long fp_offset;
    int bmpPitch;
    int i, pad;
    SDL_Surface *surface;
    Uint32 Rmask;
    Uint32 Gmask;
    Uint32 Bmask;
    Uint32 Amask;
    SDL_Palette *palette;
    Uint8 *bits;
    Uint8 *top, *end;
    SDL_bool topDown;
    int ExpandBMP;

    /* The Win32 BMP file header (14 bytes) */
    char magic[2];
    Uint32 bfSize;
    Uint16 bfReserved1;
    Uint16 bfReserved2;
    Uint32 bfOffBits;

    /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
    Uint32 biSize;
    Sint32 biWidth;
    Sint32 biHeight;
    Uint16 biPlanes;
    Uint16 biBitCount;
    Uint32 biCompression;
    Uint32 biSizeImage;
    Sint32 biXPelsPerMeter;
    Sint32 biYPelsPerMeter;
    Uint32 biClrUsed;
    Uint32 biClrImportant;

    /* Make sure we are passed a valid data source */
    surface = NULL;
    was_error = SDL_FALSE;
    if (src == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Read in the BMP file header */
    fp_offset = SDL_RWtell(src);
    SDL_ClearError();
    if (SDL_RWread(src, magic, 1, 2) != 2) {
        SDL_Error(SDL_EFREAD);
        was_error = SDL_TRUE;
        goto done;
    }
    if (SDL_strncmp(magic, "BM", 2) != 0) {
        SDL_SetError("File is not a Windows BMP file");
        was_error = SDL_TRUE;
        goto done;
    }
    bfSize = SDL_ReadLE32(src);
    bfReserved1 = SDL_ReadLE16(src);
    bfReserved2 = SDL_ReadLE16(src);
    bfOffBits = SDL_ReadLE32(src);

    /* Read the Win32 BITMAPINFOHEADER */
    biSize = SDL_ReadLE32(src);
    if (biSize == 12) {
        biWidth = (Uint32) SDL_ReadLE16(src);
        biHeight = (Uint32) SDL_ReadLE16(src);
        biPlanes = SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = BI_RGB;
        biSizeImage = 0;
        biXPelsPerMeter = 0;
        biYPelsPerMeter = 0;
        biClrUsed = 0;
        biClrImportant = 0;
    } else {
        biWidth = SDL_ReadLE32(src);
        biHeight = SDL_ReadLE32(src);
        biPlanes = SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = SDL_ReadLE32(src);
        biSizeImage = SDL_ReadLE32(src);
        biXPelsPerMeter = SDL_ReadLE32(src);
        biYPelsPerMeter = SDL_ReadLE32(src);
        biClrUsed = SDL_ReadLE32(src);
        biClrImportant = SDL_ReadLE32(src);
    }
    if (biHeight < 0) {
        topDown = SDL_TRUE;
        biHeight = -biHeight;
    } else {
        topDown = SDL_FALSE;
    }

    /* Check for read error */
    if (SDL_strcmp(SDL_GetError(), "") != 0) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
    switch (biBitCount) {
    case 1:
    case 4:
        ExpandBMP = biBitCount;
        biBitCount = 8;
        break;
    default:
        ExpandBMP = 0;
        break;
    }

    /* We don't support any BMP compression right now */
    Rmask = Gmask = Bmask = Amask = 0;
    switch (biCompression) {
    case BI_RGB:
        /* If there are no masks, use the defaults */
        if (bfOffBits == (14 + biSize)) {
            /* Default values for the BMP format */
            switch (biBitCount) {
            case 15:
            case 16:
                Rmask = 0x7C00;
                Gmask = 0x03E0;
                Bmask = 0x001F;
                break;
            case 24:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
                Rmask = 0x000000FF;
                Gmask = 0x0000FF00;
                Bmask = 0x00FF0000;
#else
                Rmask = 0x00FF0000;
                Gmask = 0x0000FF00;
                Bmask = 0x000000FF;
#endif
                break;
            case 32:
                Amask = 0xFF000000;
                Rmask = 0x00FF0000;
                Gmask = 0x0000FF00;
                Bmask = 0x000000FF;
                break;
            default:
                break;
            }
            break;
        }
        /* Fall through -- read the RGB masks */

    case BI_BITFIELDS:
        switch (biBitCount) {
        case 15:
        case 16:
            Rmask = SDL_ReadLE32(src);
            Gmask = SDL_ReadLE32(src);
            Bmask = SDL_ReadLE32(src);
            break;
        case 32:
            Rmask = SDL_ReadLE32(src);
            Gmask = SDL_ReadLE32(src);
            Bmask = SDL_ReadLE32(src);
            Amask = SDL_ReadLE32(src);
            break;
        default:
            break;
        }
        break;
    default:
        SDL_SetError("Compressed BMP files not supported");
        was_error = SDL_TRUE;
        goto done;
    }

    /* Create a compatible surface, note that the colors are RGB ordered */
    surface =
        SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
                             Bmask, Amask);
    if (surface == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Load the palette, if any */
    palette = (surface->format)->palette;
    if (palette) {
        if (biClrUsed == 0) {
            biClrUsed = 1 << biBitCount;
        }
        if ((int) biClrUsed > palette->ncolors) {
            palette->ncolors = biClrUsed;
            palette->colors =
                (SDL_Color *) SDL_realloc(palette->colors,
                                          palette->ncolors *
                                          sizeof(*palette->colors));
            if (!palette->colors) {
                SDL_OutOfMemory();
                was_error = SDL_TRUE;
                goto done;
            }
        } else if ((int) biClrUsed < palette->ncolors) {
            palette->ncolors = biClrUsed;
        }
        if (biSize == 12) {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                palette->colors[i].unused = SDL_ALPHA_OPAQUE;
            }
        } else {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                SDL_RWread(src, &palette->colors[i].unused, 1, 1);
            }
        }
    }

    /* Read the surface pixels.  Note that the bmp image is upside down */
    if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
        SDL_Error(SDL_EFSEEK);
        was_error = SDL_TRUE;
        goto done;
    }
    top = (Uint8 *)surface->pixels;
    end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    switch (ExpandBMP) {
    case 1:
        bmpPitch = (biWidth + 7) >> 3;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    case 4:
        bmpPitch = (biWidth + 1) >> 1;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    default:
        pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0);
        break;
    }
    if (topDown) {
        bits = top;
    } else {
        bits = end - surface->pitch;
    }
    while (bits >= top && bits < end) {
        switch (ExpandBMP) {
        case 1:
        case 4:{
                Uint8 pixel = 0;
                int shift = (8 - ExpandBMP);
                for (i = 0; i < surface->w; ++i) {
                    if (i % (8 / ExpandBMP) == 0) {
                        if (!SDL_RWread(src, &pixel, 1, 1)) {
                            SDL_SetError("Error reading from BMP");
                            was_error = SDL_TRUE;
                            goto done;
                        }
                    }
                    *(bits + i) = (pixel >> shift);
                    pixel <<= ExpandBMP;
                }
            }
            break;

        default:
            if (SDL_RWread(src, bits, 1, surface->pitch)
                != surface->pitch) {
                SDL_Error(SDL_EFREAD);
                was_error = SDL_TRUE;
                goto done;
            }
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            /* Byte-swap the pixels if needed. Note that the 24bpp
               case has already been taken care of above. */
            switch (biBitCount) {
            case 15:
            case 16:{
                    Uint16 *pix = (Uint16 *) bits;
                    for (i = 0; i < surface->w; i++)
                        pix[i] = SDL_Swap16(pix[i]);
                    break;
                }

            case 32:{
                    Uint32 *pix = (Uint32 *) bits;
                    for (i = 0; i < surface->w; i++)
                        pix[i] = SDL_Swap32(pix[i]);
                    break;
                }
            }
#endif
            break;
        }
        /* Skip padding bytes, ugh */
        if (pad) {
            Uint8 padbyte;
            for (i = 0; i < pad; ++i) {
                SDL_RWread(src, &padbyte, 1, 1);
            }
        }
        if (topDown) {
            bits += surface->pitch;
        } else {
            bits -= surface->pitch;
        }
    }
  done:
    if (was_error) {
        if (src) {
            SDL_RWseek(src, fp_offset, RW_SEEK_SET);
        }
        if (surface) {
            SDL_FreeSurface(surface);
        }
        surface = NULL;
    }
    if (freesrc && src) {
        SDL_RWclose(src);
    }
    return (surface);
}
/**
 * @brief Tests writing and reading from file using endian aware functions.
 *
 * \sa
 * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile
 * http://wiki.libsdl.org/moin.cgi/SDL_RWClose
 * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16
 * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16
 */
int
rwops_testFileWriteReadEndian(void)
{
   SDL_RWops *rw;
   Sint64 result;
   int mode;
   size_t objectsWritten;
   Uint16 BE16value;
   Uint32 BE32value;
   Uint64 BE64value;
   Uint16 LE16value;
   Uint32 LE32value;
   Uint64 LE64value;
   Uint16 BE16test;
   Uint32 BE32test;
   Uint64 BE64test;
   Uint16 LE16test;
   Uint32 LE32test;
   Uint64 LE64test;
   int cresult;

   for (mode = 0; mode < 3; mode++) {

     /* Create test data */
     switch (mode) {
       case 0:
        SDLTest_Log("All 0 values");
        BE16value = 0;
        BE32value = 0;
        BE64value = 0;
        LE16value = 0;
        LE32value = 0;
        LE64value = 0;
        break;
       case 1:
        SDLTest_Log("All 1 values");
        BE16value = 1;
        BE32value = 1;
        BE64value = 1;
        LE16value = 1;
        LE32value = 1;
        LE64value = 1;
        break;
       case 2:
        SDLTest_Log("Random values");
        BE16value = SDLTest_RandomUint16();
        BE32value = SDLTest_RandomUint32();
        BE64value = SDLTest_RandomUint64();
        LE16value = SDLTest_RandomUint16();
        LE32value = SDLTest_RandomUint32();
        LE64value = SDLTest_RandomUint64();
        break;
     }

     /* Write test. */
     rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+");
     SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")");
     SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL");

     /* Bail out if NULL */
     if (rw == NULL) return TEST_ABORTED;

     /* Write test data */
     objectsWritten = SDL_WriteBE16(rw, BE16value);
     SDLTest_AssertPass("Call to SDL_WriteBE16");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);
     objectsWritten = SDL_WriteBE32(rw, BE32value);
     SDLTest_AssertPass("Call to SDL_WriteBE32");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);
     objectsWritten = SDL_WriteBE64(rw, BE64value);
     SDLTest_AssertPass("Call to SDL_WriteBE64");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);
     objectsWritten = SDL_WriteLE16(rw, LE16value);
     SDLTest_AssertPass("Call to SDL_WriteLE16");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);
     objectsWritten = SDL_WriteLE32(rw, LE32value);
     SDLTest_AssertPass("Call to SDL_WriteLE32");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);
     objectsWritten = SDL_WriteLE64(rw, LE64value);
     SDLTest_AssertPass("Call to SDL_WriteLE64");
     SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten);

     /* Test seek to start */
     result = SDL_RWseek( rw, 0, RW_SEEK_SET );
     SDLTest_AssertPass("Call to SDL_RWseek succeeded");
     SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", result);

     /* Read test data */
     BE16test = SDL_ReadBE16(rw);
     SDLTest_AssertPass("Call to SDL_ReadBE16");
     SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test);
     BE32test = SDL_ReadBE32(rw);
     SDLTest_AssertPass("Call to SDL_ReadBE32");
     SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test);
     BE64test = SDL_ReadBE64(rw);
     SDLTest_AssertPass("Call to SDL_ReadBE64");
     SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %llu, got: %llu", BE64value, BE64test);
     LE16test = SDL_ReadLE16(rw);
     SDLTest_AssertPass("Call to SDL_ReadLE16");
     SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test);
     LE32test = SDL_ReadLE32(rw);
     SDLTest_AssertPass("Call to SDL_ReadLE32");
     SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test);
     LE64test = SDL_ReadLE64(rw);
     SDLTest_AssertPass("Call to SDL_ReadLE64");
     SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %llu, got: %llu", LE64value, LE64test);

     /* Close handle */
     cresult = SDL_RWclose(rw);
     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
     SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult);
   }

   return TEST_COMPLETED;
}
/* static */ bt_array*	bt_array::create(const char* filename)
// Makes a bt_array accessor for the specified .bt data file.  Returns
// NULL if the file is not a valid .bt file, or if there are other
// errors.
{
	assert(filename);

	SDL_RWops*	in = SDL_RWFromFile(filename, "rb");
	if (in == 0) {
		// Can't open the file.
		// warning ...
		printf("can't open file %s\n", filename);
		return NULL;
	}
	
	//
	// Read .BT header.
	//

	// Create a bt_array instance, and load its members.
	bt_array*	bt = new bt_array();
	
	// File-type marker.
	char	buf[11];
	SDL_RWread(in, buf, 1, 10);
	buf[10] = 0;
	if (strcmp(buf, "binterr1.1") == 0 || strcmp(buf, "binterr1.2") == 0) {
		bt->m_file_ver = BT11;
	}
	else if (strcmp(buf, "binterr1.3") == 0) {
		bt->m_file_ver = BT13;
	}
	else {
		// Bad input file format.
		printf("input file %s is not .BT version 1.1, 1.2 or 1.3 format\n", filename);
		SDL_RWclose(in);
		delete bt;
		return NULL;
	}

	bt->m_width = SDL_ReadLE32(in);
	bt->m_height = SDL_ReadLE32(in);
	if (bt->m_width <= 0 || bt->m_height <= 0) {
		// invalid data size.
		printf("invalid data size: width = %d, height = %d\n", bt->m_width, bt->m_height);

		delete bt;
		SDL_RWclose(in);
		return NULL;
	}

	int	sample_size = SDL_ReadLE16(in);
	bt->m_float_data = SDL_ReadLE16(in) == 1 ? true : false;
	if (bt->m_float_data && sample_size != 4) {
		// can't deal with floats that aren't 4 bytes.
		printf("invalid data format: float, but size = %d\n", sample_size);
		delete bt;
		SDL_RWclose(in);
		return NULL;
	}
	if (bt->m_float_data == false && sample_size != 2) {
		// can't deal with ints that aren't 2 bytes.
		printf("invalid data format: int, but size = %d\n", sample_size);
		delete bt;
		SDL_RWclose(in);
		return NULL;
	}
	
	bt->m_sizeof_element = bt->m_float_data ? 4 : 2;
	if (bt->m_file_ver == BT11) {
		bt->m_utm_flag = SDL_ReadLE16(in) ? true : false;
	}
	else {
		bt->m_horz_units = SDL_ReadLE16(in);
	}
	bt->m_utm_zone = SDL_ReadLE16(in);
	bt->m_datum = SDL_ReadLE16(in);
	bt->m_left = ReadDouble64(in);
	bt->m_right = ReadDouble64(in);
	bt->m_bottom = ReadDouble64(in);
	bt->m_top = ReadDouble64(in);

	if (bt->m_file_ver == BT13) {
		SDL_ReadLE16(in); // Skip 2-byte External projection flag
		union {
			float	f;
			Uint32	l;
		} u;
		u.l = SDL_ReadLE32(in);
		bt->m_vertical_scale = (u.f > 0.f) ? u.f : 1.f;
	}
	else {
		bt->m_vertical_scale = 1.f;
	}

	// Close the file.
	SDL_RWclose(in);

	printf("width = %d, height = %d, sample_size = %d, left = %lf, right = %lf, bottom = %lf, top = %lf\n",
	       bt->m_width, bt->m_height, sample_size, bt->m_left, bt->m_right, bt->m_bottom, bt->m_top);

	printf("vertical scale = %lf\n", bt->m_vertical_scale);

	// Reopen the data using memory-mapping.
	bt->m_data_size = sample_size * bt->m_width * bt->m_height;
	bt->m_data_size += BT_HEADER_SIZE;
	bt->m_data = mmap_util::map(bt->m_data_size, false, filename);
	if (bt->m_data == 0) {
		// Failed to open a memory-mapped view to the data.
		printf("mmap_util::map() failed on %s, size = %d\n", filename, bt->m_data_size);
		delete bt;
		return NULL;
	}

	// Initialize the (empty) cache.
	if (bt->m_width * 4096 < TOTAL_CACHE_BYTES) {
		// No point in caching -- the dataset isn't big enough
		// to stress mmap.
		bt->m_cache_height = 0;
	} else {
		// Figure out how big our cache lines should be.
		bt->m_cache_height = TOTAL_CACHE_BYTES / bt->m_width / bt->m_sizeof_element;
	}
	if (bt->m_cache_height) {
		bt->m_cache.resize(bt->m_width);
	}

	// Niello: not sure how this will work with the cache enabled
	bt->m_min_elev = bt->m_max_elev = bt->get_sample(0, 0);
	for (int w = 0; w < bt->m_width; w++) {
		for (int h = 0; h < bt->m_height; h++) {
			float elev = bt->get_sample(w, h);
			if (elev < bt->m_min_elev) bt->m_min_elev = elev;
			else if (elev > bt->m_max_elev) bt->m_max_elev = elev;
		}
	}

	return bt;
}
Exemple #10
0
SDL_Surface *
SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
{
    SDL_bool was_error;
    Sint64 fp_offset = 0;
    int bmpPitch;
    int i, pad;
    SDL_Surface *surface;
    Uint32 Rmask = 0;
    Uint32 Gmask = 0;
    Uint32 Bmask = 0;
    Uint32 Amask = 0;
    SDL_Palette *palette;
    Uint8 *bits;
    Uint8 *top, *end;
    SDL_bool topDown;
    int ExpandBMP;
    SDL_bool haveRGBMasks = SDL_FALSE;
    SDL_bool haveAlphaMask = SDL_FALSE;
    SDL_bool correctAlpha = SDL_FALSE;

    /* The Win32 BMP file header (14 bytes) */
    char magic[2];
    /* Uint32 bfSize = 0; */
    /* Uint16 bfReserved1 = 0; */
    /* Uint16 bfReserved2 = 0; */
    Uint32 bfOffBits = 0;

    /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
    Uint32 biSize = 0;
    Sint32 biWidth = 0;
    Sint32 biHeight = 0;
    /* Uint16 biPlanes = 0; */
    Uint16 biBitCount = 0;
    Uint32 biCompression = 0;
    /* Uint32 biSizeImage = 0; */
    /* Sint32 biXPelsPerMeter = 0; */
    /* Sint32 biYPelsPerMeter = 0; */
    Uint32 biClrUsed = 0;
    /* Uint32 biClrImportant = 0; */

    (void) haveRGBMasks;
    (void) haveAlphaMask;

    /* Make sure we are passed a valid data source */
    surface = NULL;
    was_error = SDL_FALSE;
    if (src == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Read in the BMP file header */
    fp_offset = SDL_RWtell(src);
    SDL_ClearError();
    if (SDL_RWread(src, magic, 1, 2) != 2) {
        SDL_Error(SDL_EFREAD);
        was_error = SDL_TRUE;
        goto done;
    }
    if (SDL_strncmp(magic, "BM", 2) != 0) {
        SDL_SetError("File is not a Windows BMP file");
        was_error = SDL_TRUE;
        goto done;
    }
    /* bfSize = */ SDL_ReadLE32(src);
    /* bfReserved1 = */ SDL_ReadLE16(src);
    /* bfReserved2 = */ SDL_ReadLE16(src);
    bfOffBits = SDL_ReadLE32(src);

    /* Read the Win32 BITMAPINFOHEADER */
    biSize = SDL_ReadLE32(src);
    if (biSize == 12) {   /* really old BITMAPCOREHEADER */
        biWidth = (Uint32) SDL_ReadLE16(src);
        biHeight = (Uint32) SDL_ReadLE16(src);
        /* biPlanes = */ SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = BI_RGB;
    } else if (biSize >= 40) {  /* some version of BITMAPINFOHEADER */
        Uint32 headerSize;
        biWidth = SDL_ReadLE32(src);
        biHeight = SDL_ReadLE32(src);
        /* biPlanes = */ SDL_ReadLE16(src);
        biBitCount = SDL_ReadLE16(src);
        biCompression = SDL_ReadLE32(src);
        /* biSizeImage = */ SDL_ReadLE32(src);
        /* biXPelsPerMeter = */ SDL_ReadLE32(src);
        /* biYPelsPerMeter = */ SDL_ReadLE32(src);
        biClrUsed = SDL_ReadLE32(src);
        /* biClrImportant = */ SDL_ReadLE32(src);

        /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
        if (biSize == 64) {
            /* ignore these extra fields. */
            if (biCompression == BI_BITFIELDS) {
                /* this value is actually huffman compression in this variant. */
                SDL_SetError("Compressed BMP files not supported");
                was_error = SDL_TRUE;
                goto done;
            }
        } else {
            /* This is complicated. If compression is BI_BITFIELDS, then
               we have 3 DWORDS that specify the RGB masks. This is either
               stored here in an BITMAPV2INFOHEADER (which only differs in
               that it adds these RGB masks) and biSize >= 52, or we've got
               these masks stored in the exact same place, but strictly
               speaking, this is the bmiColors field in BITMAPINFO immediately
               following the legacy v1 info header, just past biSize. */
            if (biCompression == BI_BITFIELDS) {
                haveRGBMasks = SDL_TRUE;
                Rmask = SDL_ReadLE32(src);
                Gmask = SDL_ReadLE32(src);
                Bmask = SDL_ReadLE32(src);

                /* ...v3 adds an alpha mask. */
                if (biSize >= 56) {  /* BITMAPV3INFOHEADER; adds alpha mask */
                    haveAlphaMask = SDL_TRUE;
                    Amask = SDL_ReadLE32(src);
                }
            } else {
                /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
                if (biSize >= 52) {  /* BITMAPV2INFOHEADER; adds RGB masks */
                    /*Rmask = */ SDL_ReadLE32(src);
                    /*Gmask = */ SDL_ReadLE32(src);
                    /*Bmask = */ SDL_ReadLE32(src);
                }
                if (biSize >= 56) {  /* BITMAPV3INFOHEADER; adds alpha mask */
                    /*Amask = */ SDL_ReadLE32(src);
                }
            }

            /* Insert other fields here; Wikipedia and MSDN say we're up to
               v5 of this header, but we ignore those for now (they add gamma,
               color spaces, etc). Ignoring the weird OS/2 2.x format, we
               currently parse up to v3 correctly (hopefully!). */
        }

        /* skip any header bytes we didn't handle... */
        headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14));
        if (biSize > headerSize) {
            SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR);
        }
    }
    if (biHeight < 0) {
        topDown = SDL_TRUE;
        biHeight = -biHeight;
    } else {
        topDown = SDL_FALSE;
    }

    /* Check for read error */
    if (SDL_strcmp(SDL_GetError(), "") != 0) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
    switch (biBitCount) {
    case 1:
    case 4:
        ExpandBMP = biBitCount;
        biBitCount = 8;
        break;
    default:
        ExpandBMP = 0;
        break;
    }

    /* We don't support any BMP compression right now */
    switch (biCompression) {
    case BI_RGB:
        /* If there are no masks, use the defaults */
        SDL_assert(!haveRGBMasks);
        SDL_assert(!haveAlphaMask);
        /* Default values for the BMP format */
        switch (biBitCount) {
        case 15:
        case 16:
            Rmask = 0x7C00;
            Gmask = 0x03E0;
            Bmask = 0x001F;
            break;
        case 24:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            Rmask = 0x000000FF;
            Gmask = 0x0000FF00;
            Bmask = 0x00FF0000;
#else
            Rmask = 0x00FF0000;
            Gmask = 0x0000FF00;
            Bmask = 0x000000FF;
#endif
            break;
        case 32:
            /* We don't know if this has alpha channel or not */
            correctAlpha = SDL_TRUE;
            Amask = 0xFF000000;
            Rmask = 0x00FF0000;
            Gmask = 0x0000FF00;
            Bmask = 0x000000FF;
            break;
        default:
            break;
        }
        break;

    case BI_BITFIELDS:
        break;  /* we handled this in the info header. */

    default:
        SDL_SetError("Compressed BMP files not supported");
        was_error = SDL_TRUE;
        goto done;
    }

    /* Create a compatible surface, note that the colors are RGB ordered */
    surface =
        SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
                             Bmask, Amask);
    if (surface == NULL) {
        was_error = SDL_TRUE;
        goto done;
    }

    /* Load the palette, if any */
    palette = (surface->format)->palette;
    if (palette) {
        SDL_assert(biBitCount <= 8);
        if (biClrUsed == 0) {
            biClrUsed = 1 << biBitCount;
        }
        if ((int) biClrUsed > palette->ncolors) {
            SDL_Color *colors;
            int ncolors = biClrUsed;
            colors =
                (SDL_Color *) SDL_realloc(palette->colors,
                                          ncolors *
                                          sizeof(*palette->colors));
            if (!colors) {
                SDL_OutOfMemory();
                was_error = SDL_TRUE;
                goto done;
            }
            palette->ncolors = ncolors;
            palette->colors = colors;
        } else if ((int) biClrUsed < palette->ncolors) {
            palette->ncolors = biClrUsed;
        }
        if (biSize == 12) {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                palette->colors[i].a = SDL_ALPHA_OPAQUE;
            }
        } else {
            for (i = 0; i < (int) biClrUsed; ++i) {
                SDL_RWread(src, &palette->colors[i].b, 1, 1);
                SDL_RWread(src, &palette->colors[i].g, 1, 1);
                SDL_RWread(src, &palette->colors[i].r, 1, 1);
                SDL_RWread(src, &palette->colors[i].a, 1, 1);

                /* According to Microsoft documentation, the fourth element
                   is reserved and must be zero, so we shouldn't treat it as
                   alpha.
                */
                palette->colors[i].a = SDL_ALPHA_OPAQUE;
            }
        }
    }

    /* Read the surface pixels.  Note that the bmp image is upside down */
    if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
        SDL_Error(SDL_EFSEEK);
        was_error = SDL_TRUE;
        goto done;
    }
    top = (Uint8 *)surface->pixels;
    end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    switch (ExpandBMP) {
    case 1:
        bmpPitch = (biWidth + 7) >> 3;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    case 4:
        bmpPitch = (biWidth + 1) >> 1;
        pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
        break;
    default:
        pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0);
        break;
    }
    if (topDown) {
        bits = top;
    } else {
        bits = end - surface->pitch;
    }
    while (bits >= top && bits < end) {
        switch (ExpandBMP) {
        case 1:
        case 4:{
                Uint8 pixel = 0;
                int shift = (8 - ExpandBMP);
                for (i = 0; i < surface->w; ++i) {
                    if (i % (8 / ExpandBMP) == 0) {
                        if (!SDL_RWread(src, &pixel, 1, 1)) {
                            SDL_SetError("Error reading from BMP");
                            was_error = SDL_TRUE;
                            goto done;
                        }
                    }
                    *(bits + i) = (pixel >> shift);
                    pixel <<= ExpandBMP;
                }
            }
            break;

        default:
            if (SDL_RWread(src, bits, 1, surface->pitch)
                != surface->pitch) {
                SDL_Error(SDL_EFREAD);
                was_error = SDL_TRUE;
                goto done;
            }
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            /* Byte-swap the pixels if needed. Note that the 24bpp
               case has already been taken care of above. */
            switch (biBitCount) {
            case 15:
            case 16:{
                    Uint16 *pix = (Uint16 *) bits;
                    for (i = 0; i < surface->w; i++)
                        pix[i] = SDL_Swap16(pix[i]);
                    break;
                }

            case 32:{
                    Uint32 *pix = (Uint32 *) bits;
                    for (i = 0; i < surface->w; i++)
                        pix[i] = SDL_Swap32(pix[i]);
                    break;
                }
            }
#endif
            break;
        }
        /* Skip padding bytes, ugh */
        if (pad) {
            Uint8 padbyte;
            for (i = 0; i < pad; ++i) {
                SDL_RWread(src, &padbyte, 1, 1);
            }
        }
        if (topDown) {
            bits += surface->pitch;
        } else {
            bits -= surface->pitch;
        }
    }
    if (correctAlpha) {
        CorrectAlphaChannel(surface);
    }
  done:
    if (was_error) {
        if (src) {
            SDL_RWseek(src, fp_offset, RW_SEEK_SET);
        }
        SDL_FreeSurface(surface);
        surface = NULL;
    }
    if (freesrc && src) {
        SDL_RWclose(src);
    }
    return (surface);
}