Skip to content

Commit

Permalink
-PNG support implemented and tested
Browse files Browse the repository at this point in the history
  • Loading branch information
lucas-zimerman committed May 31, 2017
1 parent 04f7f5b commit 25ec607
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 29 deletions.
64 changes: 63 additions & 1 deletion Image.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
#include <stdlib.h>
#include <string.h>
#include "Image.h"
#include "png.h"
#include "_png.h"
#include "PPM.h"
#include "Hexen.h"
#include <MT2D/MessageBox/MT2D_MessageBox.h>
#include <MT2D/MT2D_Display.h>
#include <MT2D/MT2D.h>

extern char str_buffer[200];

ImageFormat PATH_GetType(char *PATH) {
ImageFormat _return= TYPE_UNSUPPORTED;
Expand Down Expand Up @@ -43,6 +48,7 @@ Image *Image_Load(char*PATH) {
ImageFormat Type;

PPMImage *ppmimg;
png_info *png;

if (PATH) {
Type = PATH_GetType(PATH);
Expand All @@ -58,7 +64,11 @@ Image *Image_Load(char*PATH) {
Img->Type = Type;
break;
}
break;
case TYPE_PNG:
Img = PNG_read_file(PATH);
Img->Loaded = true;
Img->Type = Type;
break;
}
}
Expand Down Expand Up @@ -92,6 +102,8 @@ Pixel *Image_GetPixel(Image *img, unsigned int X, unsigned int Y) {
case TYPE_PPM:
p = Image_GetPixel(img, X + Y * img->Width);
break;
case TYPE_PNG:
p = PNG_Get_Pixel(img, X, Y);
}
return p;
}
Expand All @@ -103,6 +115,11 @@ Pixel *Image_GetPixel(Image *img,int offset) {
case TYPE_PPM:
p = PPM_GetPixel((PPMImage*)img->ImagePointer, offset);
break;
case TYPE_PNG:
Y = offset / img->Width;
X = offset - Y * img->Width;
p = Image_GetPixel(img, X, Y);
break;
default:

Y = offset / img->Width;
Expand All @@ -115,6 +132,51 @@ Pixel *Image_GetPixel(Image *img,int offset) {


Pixel *Image_GetPalette(Image *image, int paletteLength) {
int i = 0, j = 0;
int ImgLength = image->Width * image->Height;
Pixel *palette = (Pixel*)malloc(paletteLength * sizeof(Pixel));//hard coded
Pixel *tmp;
bool *palette_started = (bool*)malloc(paletteLength * sizeof(bool));
for (int i = 0; i < paletteLength; i++) {
palette[i].blue = 0;
palette[i].green = 0;
palette[i].red = 0;
palette_started[i] = false;
}
int disp_pos = 8;
insert_string_on_display("INDEX R ,G ,B", 7, 10, DISPLAY_WINDOW1);
for (i = 0; i < ImgLength; i++) {
for (j = 0; j < paletteLength; j++) {
tmp = Image_GetPixel(image, i);
if (palette[j].red == tmp->red && palette[j].green == tmp->green && palette[j].blue == tmp->blue) {
//we found the same color on index, jump.
break;
}
if (palette_started[j] == false) {
//color not found in the index, jump.
palette[j].red = tmp->red;
palette[j].green = tmp->green;
palette[j].blue = tmp->blue;
palette_started[j] = true;
/*MT2D STUFF*/
sprintf(str_buffer, "%2d %3d ,%3d ,%3d", j, palette[j].red, palette[j].green, palette[j].blue);
insert_string_on_display(str_buffer, disp_pos, 10, DISPLAY_WINDOW1);
disp_pos++;
MT2D_Draw_Window(DISPLAY_WINDOW1);
/*=========*/
break;
}
}
if (j == 16) {
sprintf(str_buffer, "ERROR:this image has more than 16 colors, you can fix that with the gimp software... More info here:https://docs.gimp.org/en/gimp-image-convert-indexed.html");
MT2D_MessageBox(str_buffer);
return 0;
}
}
return palette;



Pixel *Palette = 0;
switch(image->Type){
case TYPE_PPM:
Expand Down
2 changes: 1 addition & 1 deletion Source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void screen_reset() {
insert_string_on_display("+ powered by +", 21, 60, DISPLAY_WINDOW1);
insert_string_on_display("+ MT2D ENGINE +", 22, 60, DISPLAY_WINDOW1);
insert_string_on_display("+++++++++++++++", 23, 60, DISPLAY_WINDOW1);
insert_string_on_display("HexStartup++ v1.01, created by IBM5155", 24, 40, DISPLAY_WINDOW1);
insert_string_on_display("HexStartup++ v2.0, created by IBM5155", 24, 40, DISPLAY_WINDOW1);
MT2D_Draw_Window(DISPLAY_WINDOW1);
}

Expand Down
100 changes: 74 additions & 26 deletions _PNG.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#include <stdlib.h>
#include "Image.h"
#include <png.h>
#include "_PNG.h"
#include <MT2D/MessageBox/MT2D_MessageBox.h>
#include <MT2D/MT2D_Display.h>
#include <MT2D/MT2D.h>

/*
* A simple libpng example program
Expand All @@ -17,63 +23,105 @@
* of the X11 license.
*
*/
/*
void read_png_file(char *filename) {

extern char str_buffer[200];


Image *PNG_read_file(char *filename) {
Image *img = Image_CreateBlank();
PNG_Info *img_struct = (PNG_Info*)malloc(sizeof(PNG_Info));
FILE *fp = fopen(filename, "rb");

png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
img_struct->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!img_struct->png) {
sprintf(str_buffer, "PNG ERROR:Unable to read image:", filename);
MT2D_MessageBox(str_buffer);
fclose(fp);
return 0;
}

png_infop info = png_create_info_struct(png);
if (!info) abort();
img_struct->info = png_create_info_struct(img_struct->png);
if (!img_struct->info) {
sprintf(str_buffer, "PNG ERROR:Unable to create the info of from this image: ", filename);
MT2D_MessageBox(str_buffer);
fclose(fp);
return 0;
}

if (setjmp(png_jmpbuf(png))) abort();
if (setjmp(png_jmpbuf(img_struct->png))) {
sprintf(str_buffer, "PNG ERROR:I really dont know whats this error is but if the original author said it's an error, so is it. : ", filename);
MT2D_MessageBox(str_buffer);
fclose(fp);
return 0;
}

png_init_io(png, fp);
png_init_io(img_struct->png, fp);

png_read_info(png, info);
png_read_info(img_struct->png, img_struct->info);

width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
color_type = png_get_color_type(png, info);
bit_depth = png_get_bit_depth(png, info);
img->Width = png_get_image_width(img_struct->png, img_struct->info);
img->Height = png_get_image_height(img_struct->png, img_struct->info);
png_byte color_type = png_get_color_type(img_struct->png, img_struct->info);
png_byte bit_depth = png_get_bit_depth(img_struct->png, img_struct->info);

// Read any color_type into 8bit depth, RGBA format.
// See http://www.libpng.org/pub/png/libpng-manual.txt

if (bit_depth == 16)
png_set_strip_16(png);
png_set_strip_16(img_struct->png);

if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
png_set_palette_to_rgb(img_struct->png);

// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png);
png_set_expand_gray_1_2_4_to_8(img_struct->png);

if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
if (png_get_valid(img_struct->png, img_struct->info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(img_struct->png);

// These color_type don't have an alpha channel then fill it with 0xff.
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
png_set_filler(img_struct->png, 0xFF, PNG_FILLER_AFTER);

if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_set_gray_to_rgb(img_struct->png);

png_read_update_info(png, info);
png_read_update_info(img_struct->png, img_struct->info);

row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
png_bytep *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * img->Height);
for (int y = 0; y < img->Height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(img_struct->png, img_struct->info));
}

png_read_image(png, row_pointers);
png_read_image(img_struct->png, row_pointers);
img_struct->row_pointers = row_pointers;
img->ImagePointer = img_struct;

fclose(fp);
return img;
}

*/
Pixel *PNG_Get_Pixel(Image *img, int X, int Y) {
PNG_Info *Pi = (PNG_Info*)img->ImagePointer;
Pixel *P = (Pixel*)malloc(sizeof(Pixel));
if (png_get_color_type(Pi->png, Pi->info) == PNG_COLOR_TYPE_RGB);
// abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA "
// "(lacks the alpha channel)");

if (png_get_color_type(Pi->png, Pi->info) != PNG_COLOR_TYPE_RGBA);
// abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)",
// PNG_COLOR_TYPE_RGBA, png_get_color_type(img->png, img->info));

png_byte* row = Pi->row_pointers[Y];
png_byte* ptr = &(row[X * 4]);
// printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n",
// x, y, ptr[0], ptr[1], ptr[2], ptr[3]);
P->red = ptr[0];
P->green = ptr[1];
P->blue = ptr[2];
return P;
}
12 changes: 11 additions & 1 deletion _PNG.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,14 @@
PPMImage *readPPM(const char *filename);
Pixel *Get_Palette(PPMImage *image, int paletteLength);
*/
*/
#include <png.h>

struct PNG_Info {
png_structp png;
png_infop info;
png_bytep *row_pointers;
};

Image *PNG_read_file(char *filename);
Pixel *PNG_Get_Pixel(Image *img, int X, int Y);

0 comments on commit 25ec607

Please sign in to comment.