Skip to content

Commit

Permalink
move libpng engine shits over to a libpng extension
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertBColton committed Feb 15, 2019
1 parent 30f5257 commit be18ebb
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 95 deletions.
5 changes: 1 addition & 4 deletions ENIGMAsystem/SHELL/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,7 @@ endif

# CPPFLAGS needs these include dirs unconditionally
override CPPFLAGS += $(SYSTEMS:%=-I%/Info)
override CPPFLAGS += -I. -I$(CODEGEN) -I$(SHARED_SRC_DIR)/libpng-util -I$(SHARED_SRC_DIR)

# Unconditional LDLIBS
override LDLIBS += -L$(SHARED_SRC_DIR)/libpng-util -lpng-util -lpng
override CPPFLAGS += -I. -I$(CODEGEN)

.PHONY: all clean

Expand Down
12 changes: 12 additions & 0 deletions ENIGMAsystem/SHELL/Universal_System/Extensions/libpng/About.ey
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
%e-yaml
---

Name: libpng
Identifier: libpng
Author: Robert
Description: Support for loading png images using libpng reference library.
Icon: libpng.png

Depends: None
Dependencies: None
Init: extension_libpng_init
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SHARED_SRC_DIR := ../../shared
override CXXFLAGS += -I$(SHARED_SRC_DIR)/libpng-util -I$(SHARED_SRC_DIR)
override LDLIBS += -L$(SHARED_SRC_DIR)/libpng-util -lpng-util -lpng -lz

SOURCES += Universal_System/Extensions/libpng/libpng-ext.cpp
18 changes: 18 additions & 0 deletions ENIGMAsystem/SHELL/Universal_System/Extensions/libpng/include.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** Copyright (C) 2019 Robert B. Colton
***
*** This file is a part of the ENIGMA Development Environment.
***
*** ENIGMA is free software: you can redistribute it and/or modify it under the
*** terms of the GNU General Public License as published by the Free Software
*** Foundation, version 3 of the license or any later version.
***
*** This application and its source code is distributed AS-IS, WITHOUT ANY
*** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
*** details.
***
*** You should have received a copy of the GNU General Public License along
*** with this code. If not, see <http://www.gnu.org/licenses/>
**/

#include "libpng-ext.h"
111 changes: 111 additions & 0 deletions ENIGMAsystem/SHELL/Universal_System/Extensions/libpng/libpng-ext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/** Copyright (C) 2008-2011 Josh Ventura
*** Copyright (C) 2013 Ssss
*** Copyright (C) 2013-2014, 2019 Robert B. Colton
***
*** This file is a part of the ENIGMA Development Environment.
***
*** ENIGMA is free software: you can redistribute it and/or modify it under the
*** terms of the GNU General Public License as published by the Free Software
*** Foundation, version 3 of the license or any later version.
***
*** This application and its source code is distributed AS-IS, WITHOUT ANY
*** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
*** details.
***
*** You should have received a copy of the GNU General Public License along
*** with this code. If not, see <http://www.gnu.org/licenses/>
**/

#include "libpng-ext.h"
#include "Universal_System/image_formats.h"
#include "Universal_System/nlpo2.h"

#include "libpng-util.h"

using std::string;

namespace enigma {

unsigned char* image_load_png(string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, bool flipped) {
unsigned error;
unsigned char* image = nullptr;
unsigned pngwidth, pngheight;

error = libpng_decode32_file(&image, &pngwidth, &pngheight, filename.c_str());
if (error)
{
printf("error %u: %s\n", error, libpng_error_text(error).c_str());
return NULL;
}

unsigned
widfull = nlpo2dc(pngwidth) + 1,
hgtfull = nlpo2dc(pngheight) + 1,
ih,iw;
const int bitmap_size = widfull*hgtfull*4;
unsigned char* bitmap = new unsigned char[bitmap_size](); // Initialize to zero.

for (ih = 0; ih < pngheight; ih++) {
unsigned tmp = 0;
if (!flipped) {
tmp = ih*widfull*4;
} else {
tmp = (pngheight - 1 - ih)*widfull*4;
}
for (iw = 0; iw < pngwidth; iw++) {
bitmap[tmp+0] = image[4*pngwidth*ih+iw*4+2];
bitmap[tmp+1] = image[4*pngwidth*ih+iw*4+1];
bitmap[tmp+2] = image[4*pngwidth*ih+iw*4+0];
bitmap[tmp+3] = image[4*pngwidth*ih+iw*4+3];
tmp+=4;
}
}

free(image);
*width = pngwidth;
*height = pngheight;
*fullwidth = widfull;
*fullheight = hgtfull;
return bitmap;
}

int image_save_png(string filename, const unsigned char* data, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped)
{
//TODO: Use width/height instead of full size, lodepng didn't support this apparently
//TODO: lodepng didn't let us specify if our image data is flipped
//TODO: lodepng didn't support BGRA
unsigned bytes = 4;

unsigned char* bitmap = new unsigned char[width*height*bytes]();

for (unsigned i = 0; i < height; i++) {
unsigned tmp = i;
unsigned bmp = i;
if (!flipped) {
tmp = height - 1 - tmp;
bmp = height - 1 - bmp;
}
tmp *= bytes * fullwidth;
bmp *= bytes * width;
for (unsigned ii = 0; ii < width*bytes; ii += bytes) {
bitmap[bmp + ii + 2] = data[tmp + ii + 0];
bitmap[bmp + ii + 1] = data[tmp + ii + 1];
bitmap[bmp + ii + 0] = data[tmp + ii + 2];
bitmap[bmp + ii + 3] = data[tmp + ii + 3];
}
}

unsigned error = libpng_encode32_file(bitmap, width, height, filename.c_str());

delete[] bitmap;

if (error) return -1; else return 1;
}

void extension_libpng_init() {
image_load_handlers[".png"] = image_load_png;
image_save_handlers[".png"] = image_save_png;
}

} // namespace enigma
27 changes: 27 additions & 0 deletions ENIGMAsystem/SHELL/Universal_System/Extensions/libpng/libpng-ext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** Copyright (C) 2019 Robert B. Colton
***
*** This file is a part of the ENIGMA Development Environment.
***
*** ENIGMA is free software: you can redistribute it and/or modify it under the
*** terms of the GNU General Public License as published by the Free Software
*** Foundation, version 3 of the license or any later version.
***
*** This application and its source code is distributed AS-IS, WITHOUT ANY
*** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
*** details.
***
*** You should have received a copy of the GNU General Public License along
*** with this code. If not, see <http://www.gnu.org/licenses/>
**/

#ifndef ENIGMA_LIBPNG_H
#define ENIGMA_LIBPNG_H

namespace enigma {

void extension_libpng_init();

} // namespace enigma

#endif // ENIGMA_LIBPNG_H
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 16 additions & 88 deletions ENIGMAsystem/SHELL/Universal_System/image_formats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "image_formats.h"
#include "Universal_System/estring.h"

#include "libpng-util.h"
#include "gif_format.h"

#include <fstream> // std::ofstream
Expand All @@ -44,6 +43,9 @@ inline unsigned int lgpp2(unsigned int x){//Trailing zero count. lg for perfect
namespace enigma
{

std::map<std::string, ImageLoadFunction> image_load_handlers;
std::map<std::string, ImageSaveFunction> image_save_handlers;

unsigned char* image_flip(const unsigned char* data, unsigned width, unsigned height, unsigned bytes) {
//flipped upside down
unsigned sz = width * height;
Expand All @@ -69,15 +71,16 @@ string image_get_format(string filename) {

/// Generic all-purpose image loading call.
unsigned char* image_load(string filename, string format, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, int* imgnumb, bool flipped) {
if (format.compare(".png") == 0) {
return image_load_png(filename, width, height, fullwidth, fullheight, flipped);
} else if (format.compare(".bmp") == 0) {
if (format.compare(".bmp") == 0) {
return image_load_bmp(filename, width, height, fullwidth, fullheight, flipped);
} else if (format.compare(".gif") == 0) {
return image_load_gif(filename, width, height, fullwidth, fullheight, imgnumb, flipped);
} else {
return image_load_bmp(filename, width, height, fullwidth, fullheight, flipped);
}
auto handler = image_load_handlers.find(format);
if (handler != image_load_handlers.end()) {
return (*handler).second(filename, width, height, fullwidth, fullheight, flipped);
}
return image_load_bmp(filename, width, height, fullwidth, fullheight, flipped);
}


Expand All @@ -92,13 +95,14 @@ unsigned char* image_load(string filename, unsigned int* width, unsigned int* he

/// Generic all-purpose image saving call.
int image_save(string filename, const unsigned char* data, string format, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped) {
if (format.compare(".png") == 0) {
return image_save_png(filename, data, width, height, fullwidth, fullheight, flipped);
} else if (format.compare(".bmp") == 0) {
return image_save_bmp(filename, data, width, height, fullwidth, fullheight, flipped);
} else {
if (format.compare(".bmp") == 0) {
return image_save_bmp(filename, data, width, height, fullwidth, fullheight, flipped);
}
auto handler = image_save_handlers.find(format);
if (handler != image_save_handlers.end()) {
return (*handler).second(filename, data, width, height, fullwidth, fullheight, flipped);
}
return image_save_bmp(filename, data, width, height, fullwidth, fullheight, flipped);
}

/// Generic all-purpose image saving call that will regexp the filename for the format and call the appropriate function.
Expand All @@ -119,7 +123,7 @@ unsigned char* image_load_bmp(string filename, unsigned int* width, unsigned int
if (fgetc(imgfile)!=0x42 && fgetc(imgfile)!=0x4D) // Not a BMP
{
fclose(imgfile);
return image_load_png(filename,width,height,fullwidth,fullheight,flipped);
return NULL;
}
fseek(imgfile,10,SEEK_SET);
if (fread(&bmpstart,1,4,imgfile) != 4)
Expand Down Expand Up @@ -194,49 +198,6 @@ unsigned char* image_load_bmp(string filename, unsigned int* width, unsigned int
return bitmap;
}

unsigned char* image_load_png(string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, bool flipped) {
unsigned error;
unsigned char* image = nullptr;
unsigned pngwidth, pngheight;

error = libpng_decode32_file(&image, &pngwidth, &pngheight, filename.c_str());
if (error)
{
printf("error %u: %s\n", error, libpng_error_text(error).c_str());
return NULL;
}

unsigned
widfull = nlpo2dc(pngwidth) + 1,
hgtfull = nlpo2dc(pngheight) + 1,
ih,iw;
const int bitmap_size = widfull*hgtfull*4;
unsigned char* bitmap = new unsigned char[bitmap_size](); // Initialize to zero.

for (ih = 0; ih < pngheight; ih++) {
unsigned tmp = 0;
if (!flipped) {
tmp = ih*widfull*4;
} else {
tmp = (pngheight - 1 - ih)*widfull*4;
}
for (iw = 0; iw < pngwidth; iw++) {
bitmap[tmp+0] = image[4*pngwidth*ih+iw*4+2];
bitmap[tmp+1] = image[4*pngwidth*ih+iw*4+1];
bitmap[tmp+2] = image[4*pngwidth*ih+iw*4+0];
bitmap[tmp+3] = image[4*pngwidth*ih+iw*4+3];
tmp+=4;
}
}

free(image);
*width = pngwidth;
*height = pngheight;
*fullwidth = widfull;
*fullheight = hgtfull;
return bitmap;
}

unsigned char* image_load_gif(string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, int* imgnumb, bool flipped) {
unsigned int error = 0;
unsigned char* image = 0;
Expand Down Expand Up @@ -287,37 +248,4 @@ int image_save_bmp(string filename, const unsigned char* data, unsigned width, u
return 0;
}

int image_save_png(string filename, const unsigned char* data, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped)
{
//TODO: Use width/height instead of full size, lodepng didn't support this apparently
//TODO: lodepng didn't let us specify if our image data is flipped
//TODO: lodepng didn't support BGRA
unsigned bytes = 4;

unsigned char* bitmap = new unsigned char[width*height*bytes]();

for (unsigned i = 0; i < height; i++) {
unsigned tmp = i;
unsigned bmp = i;
if (!flipped) {
tmp = height - 1 - tmp;
bmp = height - 1 - bmp;
}
tmp *= bytes * fullwidth;
bmp *= bytes * width;
for (unsigned ii = 0; ii < width*bytes; ii += bytes) {
bitmap[bmp + ii + 2] = data[tmp + ii + 0];
bitmap[bmp + ii + 1] = data[tmp + ii + 1];
bitmap[bmp + ii + 0] = data[tmp + ii + 2];
bitmap[bmp + ii + 3] = data[tmp + ii + 3];
}
}

unsigned error = libpng_encode32_file(bitmap, width, height, filename.c_str());

delete[] bitmap;

if (error) return -1; else return 1;
}

}
14 changes: 11 additions & 3 deletions ENIGMAsystem/SHELL/Universal_System/image_formats.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,21 @@
#ifndef ENIGMA_IMAGEFORMATS_H
#define ENIGMA_IMAGEFORMATS_H

#include <map>
#include <functional>
#include <string>

using ImageLoadFunction = std::function<unsigned char*(std::string, unsigned int*, unsigned int*, unsigned int*, unsigned int*, bool)>;
using ImageSaveFunction = std::function<int(std::string, const unsigned char*, unsigned, unsigned, unsigned, unsigned, bool)>;

/// NOTE: These image formats expect the data to be un-aligned and always reads and writes with BGRA full color

namespace enigma
namespace enigma
{

extern std::map<std::string, ImageLoadFunction> image_load_handlers;
extern std::map<std::string, ImageSaveFunction> image_save_handlers;

/// Color formats
enum {
color_fmt_rgba,
Expand All @@ -48,10 +57,9 @@ int image_save(std::string filename, const unsigned char* data, std::string form
int image_save(std::string filename, const unsigned char* data, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped);

unsigned char* image_load_bmp(std::string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, bool flipped);
unsigned char* image_load_png(std::string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, bool flipped);
unsigned char* image_load_gif(std::string filename, unsigned int* width, unsigned int* height, unsigned int* fullwidth, unsigned int* fullheight, int* imgnumb, bool flipped);
int image_save_bmp(std::string filename, const unsigned char* data, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped);
int image_save_png(std::string filename, const unsigned char* data, unsigned width, unsigned height, unsigned fullwidth, unsigned fullheight, bool flipped);

} //namespace enigma

#endif //ENIGMA_IMAGEFORMATS_H

0 comments on commit be18ebb

Please sign in to comment.