Files
bullet3/Demos/OpenCLClothDemo/bmpLoader.cpp
erwin.coumans 4f9b450200 added OpenCL cloth demo, contributed by AMD.
updated GpuSoftBodySolvers
updated DirectCompute cloth demo
2010-08-14 00:56:17 +00:00

326 lines
8.5 KiB
C++

/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2010 Advanced Micro Devices
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "bmpLoader.h"
#include <new>
#include <cstring>
#include <cstdio>
namespace amd
{
static const short bitMapID = 19778;
void
BitMap::releaseResources(void)
{
if (pixels_ != NULL) {
delete[] pixels_;
}
if (colors_ != NULL) {
delete[] colors_;
}
pixels_ = NULL;
colors_ = NULL;
isLoaded_ = false;
}
BitMap& BitMap::operator=(const BitMap& rhs)
{
if (this == &rhs) {
return *this;
}
// Copy header
id = rhs.id;
size = rhs.size;
reserved1 = rhs.reserved1;
reserved2 = rhs.reserved2;
offset = rhs.offset;
// Copy header info
sizeInfo = rhs.sizeInfo;
width = rhs.width;
height = rhs.height;
planes = rhs.planes;
bitsPerPixel = rhs.bitsPerPixel;
compression = rhs.compression;
imageSize = rhs.imageSize;
xPelsPerMeter = rhs.xPelsPerMeter;
yPelsPerMeter = rhs.yPelsPerMeter;
clrUsed = rhs.clrUsed;
clrImportant = rhs.clrImportant;
numColors_ = rhs.numColors_;
isLoaded_ = rhs.isLoaded_;
pixels_ = NULL;
colors_ = NULL;
if (isLoaded_) {
if (rhs.colors_ != NULL) {
colors_ = new ColorPalette[numColors_];
if (colors_ == NULL) {
isLoaded_ = false;
return *this;
}
memcpy(colors_, rhs.colors_, numColors_ * sizeof(ColorPalette));
}
pixels_ = new uchar4[width * height];
if (pixels_ == NULL) {
delete[] colors_;
colors_ = NULL;
isLoaded_ = false;
return *this;
}
memcpy(pixels_, rhs.pixels_, width * height * sizeof(uchar4));
}
return *this;
}
void
BitMap::load(const char * filename)
{
// Release any existing resources
releaseResources();
// Open BMP file
FILE * fd = fopen(filename, "rb");
// Opened OK
if (fd != NULL) {
// Read header
fread((BitMapHeader *)this, sizeof(BitMapHeader), 1, fd);
// Failed to read header
if (ferror(fd)) {
fclose(fd);
return;
}
// Confirm that we have a bitmap file
if (id != bitMapID) {
fclose(fd);
return;
}
// Read map info header
fread((BitMapInfoHeader *)this, sizeof(BitMapInfoHeader), 1, fd);
// Failed to read map info header
if (ferror(fd)) {
fclose(fd);
return;
}
// No support for compressed images
if (compression) {
fclose(fd);
return;
}
// Support only 8 or 24 bits images
if (bitsPerPixel < 8) {
fclose(fd);
return;
}
// Store number of colors
numColors_ = 1 << bitsPerPixel;
//load the palate for 8 bits per pixel
if(bitsPerPixel == 8) {
colors_ = new ColorPalette[numColors_];
if (colors_ == NULL) {
fclose(fd);
return;
}
fread(
(char *)colors_,
numColors_ * sizeof(ColorPalette),
1,
fd);
// Failed to read colors
if (ferror(fd)) {
fclose(fd);
return;
}
}
// Allocate buffer to hold all pixels
unsigned int sizeBuffer = size - offset;
unsigned char * tmpPixels = new unsigned char[sizeBuffer];
if (tmpPixels == NULL) {
delete colors_;
colors_ = NULL;
fclose(fd);
return;
}
// Read pixels from file, including any padding
fread(tmpPixels, sizeBuffer * sizeof(unsigned char), 1, fd);
// Failed to read pixel data
if (ferror(fd)) {
delete colors_;
colors_ = NULL;
delete tmpPixels;
fclose(fd);
return;
}
// Allocate image
pixels_ = new uchar4[width * height];
if (pixels_ == NULL) {
delete colors_;
colors_ = NULL;
delete tmpPixels;
fclose(fd);
return;
}
// Set image, including w component (white)
memset(pixels_, 0xff, width * height * sizeof(uchar4));
unsigned int index = 0;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// Read RGB values
if (bitsPerPixel == 8) {
pixels_[(y * width + x)] = colors_[tmpPixels[index++]];
}
else { // 24 bit
pixels_[(y * width + x)].z = tmpPixels[index++];
pixels_[(y * width + x)].y = tmpPixels[index++];
pixels_[(y * width + x)].x = tmpPixels[index++];
}
}
// Handle padding
for(int x = 0; x < (4 - (3 * width) % 4) % 4; x++) {
index++;
}
}
// Loaded file so we can close the file.
fclose(fd);
delete[] tmpPixels;
// Loaded file so record this fact
isLoaded_ = true;
}
}
int
BitMap::colorIndex(uchar4 color)
{
for (int i = 0; i < numColors_; i++) {
if (colors_[i].x == color.x &&
colors_[i].y == color.y &&
colors_[i].z == color.z &&
colors_[i].w == color.w) {
return i;
}
}
return 0;
}
bool
BitMap::write(const char * filename)
{
if (!isLoaded_) {
return false;
}
// Open BMP file
FILE * fd = fopen(filename, "wb");
// Opened OK
if (fd != NULL) {
// Write header
fwrite((BitMapHeader *)this, sizeof(BitMapHeader), 1, fd);
// Failed to write header
if (ferror(fd)) {
fclose(fd);
return false;
}
// Write map info header
fwrite((BitMapInfoHeader *)this, sizeof(BitMapInfoHeader), 1, fd);
// Failed to write map info header
if (ferror(fd)) {
fclose(fd);
return false;
}
// Write palate for 8 bits per pixel
if(bitsPerPixel == 8) {
fwrite(
(char *)colors_,
numColors_ * sizeof(ColorPalette),
1,
fd);
// Failed to write colors
if (ferror(fd)) {
fclose(fd);
return false;
}
}
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// Read RGB values
if (bitsPerPixel == 8) {
fputc(
colorIndex(
pixels_[(y * width + x)]),
fd);
}
else { // 24 bit
fputc(pixels_[(y * width + x)].z, fd);
fputc(pixels_[(y * width + x)].y, fd);
fputc(pixels_[(y * width + x)].x, fd);
if (ferror(fd)) {
fclose(fd);
return false;
}
}
}
// Add padding
for(int x = 0; x < (4 - (3 * width) % 4) % 4; x++) {
fputc(0, fd);
}
}
return true;
}
return false;
}
} // amd