cleanup bitmap class
This commit is contained in:
@@ -49,139 +49,138 @@ void PngReadCallback(png_structp png_ptr, png_bytep outBytes,
|
||||
} // namespace
|
||||
|
||||
bool ConvertSurfaceToPNG(SDL_Surface *surface, std::vector<uint8_t> &buffer) {
|
||||
png_structp png_ptr = png_create_write_struct("1.6.40", NULL, NULL,
|
||||
NULL); if (!png_ptr) {
|
||||
SDL_Log("Failed to create PNG write struct");
|
||||
return false;
|
||||
}
|
||||
png_structp png_ptr = png_create_write_struct("1.6.40", NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
SDL_Log("Failed to create PNG write struct");
|
||||
return false;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
SDL_Log("Failed to create PNG info struct");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
SDL_Log("Error during PNG write");
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_write_fn(png_ptr, &buffer, PngWriteCallback, NULL);
|
||||
|
||||
png_colorp pal_ptr;
|
||||
|
||||
/* Prepare chunks */
|
||||
int colortype = PNG_COLOR_MASK_COLOR;
|
||||
int i = 0;
|
||||
SDL_Palette *pal;
|
||||
if (surface->format->BytesPerPixel > 0 &&
|
||||
surface->format->BytesPerPixel <= 8 && (pal =
|
||||
surface->format->palette)) {
|
||||
SDL_Log("Writing PNG image with palette");
|
||||
colortype |= PNG_COLOR_MASK_PALETTE;
|
||||
pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color));
|
||||
for (i = 0; i < pal->ncolors; i++) {
|
||||
pal_ptr[i].red = pal->colors[i].r;
|
||||
pal_ptr[i].green = pal->colors[i].g;
|
||||
pal_ptr[i].blue = pal->colors[i].b;
|
||||
}
|
||||
png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors);
|
||||
free(pal_ptr);
|
||||
}
|
||||
|
||||
if (surface->format->Amask) { // Check for alpha channel
|
||||
colortype |= PNG_COLOR_MASK_ALPHA;
|
||||
}
|
||||
|
||||
auto depth = surface->format->BitsPerPixel;
|
||||
|
||||
// Set image attributes.
|
||||
png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, depth, colortype,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
// Write the image data.
|
||||
std::vector<png_bytep> row_pointers(surface->h);
|
||||
for (int y = 0; y < surface->h; ++y) {
|
||||
row_pointers[y] = (png_bytep)(surface->pixels) + y * surface->pitch;
|
||||
}
|
||||
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers.data());
|
||||
|
||||
SDL_Log("Writing PNG image...");
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
SDL_Log("PNG image write complete");
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
SDL_Log("Failed to create PNG info struct");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
SDL_Log("Error during PNG write");
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_write_fn(png_ptr, &buffer, PngWriteCallback, NULL);
|
||||
|
||||
png_colorp pal_ptr;
|
||||
|
||||
/* Prepare chunks */
|
||||
int colortype = PNG_COLOR_MASK_COLOR;
|
||||
int i = 0;
|
||||
SDL_Palette *pal;
|
||||
if (surface->format->BytesPerPixel > 0 &&
|
||||
surface->format->BytesPerPixel <= 8 && (pal = surface->format->palette)) {
|
||||
SDL_Log("Writing PNG image with palette");
|
||||
colortype |= PNG_COLOR_MASK_PALETTE;
|
||||
pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color));
|
||||
for (i = 0; i < pal->ncolors; i++) {
|
||||
pal_ptr[i].red = pal->colors[i].r;
|
||||
pal_ptr[i].green = pal->colors[i].g;
|
||||
pal_ptr[i].blue = pal->colors[i].b;
|
||||
}
|
||||
png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors);
|
||||
free(pal_ptr);
|
||||
}
|
||||
|
||||
if (surface->format->Amask) { // Check for alpha channel
|
||||
colortype |= PNG_COLOR_MASK_ALPHA;
|
||||
}
|
||||
|
||||
auto depth = surface->format->BitsPerPixel;
|
||||
|
||||
// Set image attributes.
|
||||
png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, depth, colortype,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
// Write the image data.
|
||||
std::vector<png_bytep> row_pointers(surface->h);
|
||||
for (int y = 0; y < surface->h; ++y) {
|
||||
row_pointers[y] = (png_bytep)(surface->pixels) + y * surface->pitch;
|
||||
}
|
||||
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers.data());
|
||||
|
||||
SDL_Log("Writing PNG image...");
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
SDL_Log("PNG image write complete");
|
||||
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConvertPngToSurface(const std::vector<uint8_t> &png_data,
|
||||
SDL_Surface **outSurface) {
|
||||
std::vector<uint8_t> data(png_data);
|
||||
png_structp png_ptr = png_create_read_struct("1.6.40", NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
throw std::runtime_error("Failed to create PNG read struct");
|
||||
}
|
||||
std::vector<uint8_t> data(png_data);
|
||||
png_structp png_ptr = png_create_read_struct("1.6.40", NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
throw std::runtime_error("Failed to create PNG read struct");
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
throw std::runtime_error("Failed to create PNG info struct");
|
||||
}
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
throw std::runtime_error("Failed to create PNG info struct");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
throw std::runtime_error("Error during PNG read");
|
||||
}
|
||||
|
||||
// Set our custom read function
|
||||
png_set_read_fn(png_ptr, &data, PngReadCallback);
|
||||
|
||||
// Read the PNG info
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
uint32_t width = png_get_image_width(png_ptr, info_ptr);
|
||||
uint32_t height = png_get_image_height(png_ptr, info_ptr);
|
||||
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
|
||||
// Apply necessary transformations...
|
||||
// (Same as in your existing code)
|
||||
|
||||
// Update info structure with transformations
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Read the file
|
||||
std::vector<uint8_t> raw_data(width * height *
|
||||
4); // Assuming 4 bytes per pixel (RGBA)
|
||||
std::vector<png_bytep> row_pointers(height);
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
row_pointers[y] = raw_data.data() + y * width * 4;
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers.data());
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
throw std::runtime_error("Error during PNG read");
|
||||
}
|
||||
|
||||
// Create an SDL_Surface
|
||||
*outSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32,
|
||||
SDL_PIXELFORMAT_RGBA32);
|
||||
if (*outSurface == nullptr) {
|
||||
SDL_Log("SDL_CreateRGBSurfaceWithFormat failed: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
// Set our custom read function
|
||||
png_set_read_fn(png_ptr, &data, PngReadCallback);
|
||||
|
||||
// Copy the raw data into the SDL_Surface
|
||||
SDL_LockSurface(*outSurface);
|
||||
memcpy((*outSurface)->pixels, raw_data.data(), raw_data.size());
|
||||
SDL_UnlockSurface(*outSurface);
|
||||
// Read the PNG info
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
SDL_Log("Successfully created SDL_Surface from PNG data");
|
||||
uint32_t width = png_get_image_width(png_ptr, info_ptr);
|
||||
uint32_t height = png_get_image_height(png_ptr, info_ptr);
|
||||
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
|
||||
// Apply necessary transformations...
|
||||
// (Same as in your existing code)
|
||||
|
||||
// Update info structure with transformations
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Read the file
|
||||
std::vector<uint8_t> raw_data(width * height *
|
||||
4); // Assuming 4 bytes per pixel (RGBA)
|
||||
std::vector<png_bytep> row_pointers(height);
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
row_pointers[y] = raw_data.data() + y * width * 4;
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers.data());
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
||||
// Create an SDL_Surface
|
||||
*outSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32,
|
||||
SDL_PIXELFORMAT_RGBA32);
|
||||
if (*outSurface == nullptr) {
|
||||
SDL_Log("SDL_CreateRGBSurfaceWithFormat failed: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the raw data into the SDL_Surface
|
||||
SDL_LockSurface(*outSurface);
|
||||
memcpy((*outSurface)->pixels, raw_data.data(), raw_data.size());
|
||||
SDL_UnlockSurface(*outSurface);
|
||||
|
||||
SDL_Log("Successfully created SDL_Surface from PNG data");
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(int width, int height, int depth, int data_size) {
|
||||
@@ -230,10 +229,8 @@ void Bitmap::CreateTexture(SDL_Renderer *renderer) {
|
||||
|
||||
SDL_LockTexture(texture_.get(), nullptr, (void **)&texture_pixels,
|
||||
&converted_surface_->pitch);
|
||||
|
||||
memcpy(texture_pixels, converted_surface_->pixels,
|
||||
converted_surface_->h * converted_surface_->pitch);
|
||||
|
||||
SDL_UnlockTexture(texture_.get());
|
||||
}
|
||||
|
||||
@@ -249,19 +246,13 @@ void Bitmap::UpdateTexture(SDL_Renderer *renderer, bool use_sdl_update) {
|
||||
|
||||
SDL_LockTexture(texture_.get(), nullptr, (void **)&texture_pixels,
|
||||
&converted_surface_->pitch);
|
||||
|
||||
try {
|
||||
if (use_sdl_update) {
|
||||
SDL_UpdateTexture(texture_.get(), nullptr, converted_surface_->pixels,
|
||||
converted_surface_->pitch);
|
||||
} else {
|
||||
memcpy(texture_pixels, converted_surface_->pixels,
|
||||
converted_surface_->h * converted_surface_->pitch);
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
SDL_Log("Exception: %s\n", e.what());
|
||||
if (use_sdl_update) {
|
||||
SDL_UpdateTexture(texture_.get(), nullptr, converted_surface_->pixels,
|
||||
converted_surface_->pitch);
|
||||
} else {
|
||||
memcpy(texture_pixels, converted_surface_->pixels,
|
||||
converted_surface_->h * converted_surface_->pitch);
|
||||
}
|
||||
|
||||
SDL_UnlockTexture(texture_.get());
|
||||
}
|
||||
|
||||
@@ -272,8 +263,6 @@ void Bitmap::CreateTexture(std::shared_ptr<SDL_Renderer> renderer) {
|
||||
}
|
||||
|
||||
void Bitmap::UpdateTexture(std::shared_ptr<SDL_Renderer> renderer) {
|
||||
// SDL_DestroyTexture(texture_.get());
|
||||
// texture_ = nullptr;
|
||||
texture_ = std::shared_ptr<SDL_Texture>{
|
||||
SDL_CreateTextureFromSurface(renderer.get(), surface_.get()),
|
||||
SDL_Texture_Deleter{}};
|
||||
|
||||
Reference in New Issue
Block a user