I'm currently working on PNG formats. And, I'm trying to understand its characteristics:
width, height, bytewidth, bytes per width, RGB pixel (red, green, blue)
Refering to this and this, width is the resolution width of the image in pixels, height is the resolution height of the image in pixels, bytes per width takes only 8 or 16 as value, RGB pixel's three items takes 0 to 255 as integer value.
But, I cannot understand what's a bytewidth?
Because when I try to convert one bmp image to a png one in C++ I get the following error:
Unhandled exception at 0x01038F6C in Project.exe: 0xC0000005: Access violation writing location 0x00BB9000.
I get this when I initialize the output png characteristics to:
width = 1600, height = 900, bytewidth = 1, bytes per width = 1, RGB pixel (red = 255, green = 255, blue = 255)
using this code:
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE
#include <png.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
typedef struct _RGBPixel {
uint8_t blue;
uint8_t green;
uint8_t red;
} RGBPixel;
/* Structure for containing decompressed bitmaps. */
typedef struct _RGBBitmap {
RGBPixel *pixels;
size_t width;
size_t height;
size_t bytewidth;
uint8_t bytes_per_pixel;
} RGBBitmap;
/* Returns pixel of bitmap at given point. */
#define RGBPixelAtPoint(image, x, y) \
*(((image)->pixels) + (((image)->bytewidth * (y)) \
+ ((x) * (image)->bytes_per_pixel)))
/* Attempts to save PNG to file; returns 0 on success, non-zero on error. */
int save_png_to_file(RGBBitmap *bitmap, const char *path)
{
FILE *fp = fopen(path, "wb");
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
size_t x, y;
png_uint_32 bytes_per_row;
png_byte **row_pointers = NULL;
if (fp == NULL) return -1;
/* Initialize the write struct. */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(fp);
return -1;
}
/* Initialize the info struct. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
png_destroy_write_struct(&png_ptr, NULL);
fclose(fp);
return -1;
}
/* Set up error handling. */
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return -1;
}
/* Set image attributes. */
png_set_IHDR(png_ptr,
info_ptr,
bitmap->width,
bitmap->height,
8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
/* Initialize rows of PNG. */
bytes_per_row = bitmap->width * bitmap->bytes_per_pixel;
row_pointers = (png_byte **)png_malloc(png_ptr, bitmap->height * sizeof(png_byte *));
for (y = 0; y < bitmap->height; ++y) {
uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel);
row_pointers[y] = (png_byte *)row;
for (x = 0; x < bitmap->width; ++x) {
RGBPixel color = RGBPixelAtPoint(bitmap, x, y);
*row++ = color.red;
*row++ = color.green; /************* MARKED LINE ***************/
*row++ = color.blue;
}
}
/* Actually write the image data. */
png_init_io(png_ptr, fp);
png_set_rows(png_ptr, info_ptr, row_pointers);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
/* Cleanup. */
for (y = 0; y < bitmap->height; y++) {
png_free(png_ptr, row_pointers[y]);
}
png_free(png_ptr, row_pointers);
/* Finish writing. */
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return 0;
}
int main()
{
RGBBitmap rgbbitmap;
rgbbitmap.height = 1600;
rgbbitmap.width = 900;
rgbbitmap.bytes_per_pixel = 1;
rgbbitmap.bytewidth = 1;
RGBPixel rgbpixel;
rgbpixel.blue = 255;
rgbpixel.green = 255;
rgbpixel.red = 255;
rgbbitmap.pixels = &rgbpixel;
save_png_to_file(&rgbbitmap, "abc.bmp");
return 0;
}
I'm actually getting that error on the marked line.
Any brilliant suggestion, please?
row++
? – HALRGBPixel color = RGBPixelAtPoint(bitmap, x, y);
line. – user3472134