Image-PNG-Simple
view release on metacpan or search on metacpan
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "png.h"
#include <stdio.h>
#include "BmpIoLib.h"
/* Windows setjmp and longjmp don't work by Perl default */
#if defined(_WIN32) || defined(_WIN64)
# undef setjmp
# undef longjmp
# if defined(__MINGW32__)
// Copied from MinGW setjmp.h
# ifdef _WIN64
# if (__MINGW_GCC_VERSION < 40702)
# define setjmp(BUF) _setjmp((BUF), mingw_getsp())
# else
# define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
# endif
# else
# define setjmp(BUF) _setjmp3((BUF), NULL)
# endif
__declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value);
# else
# include <setjmp.h>
# endif
#endif
typedef struct {
IBMP* pBmp;
} ImagePNGSimple;
MODULE = Image::PNG::Simple PACKAGE = Image::PNG::Simple
SV
new(...)
PPCODE:
{
char* class_name = SvPV_nolen(ST(0));
ImagePNGSimple* ips = (ImagePNGSimple*)malloc(sizeof(ImagePNGSimple));
size_t ips_iv = PTR2IV(ips);
SV* ips_sv = sv_2mortal(newSViv(ips_iv));
SV* ips_svrv = sv_2mortal(newRV_inc(ips_sv));
SV* ips_obj = sv_bless(ips_svrv, gv_stashpv(class_name, 1));
XPUSHs(ips_obj);
XSRETURN(1);
}
SV
DESTORY(...)
PPCODE:
{
SV* ips_obj = ST(0);
SV* ips_sv = SvROK(ips_obj) ? SvRV(ips_obj) : ips_obj;
size_t ips_iv = SvIV(ips_sv);
ImagePNGSimple* ips = INT2PTR(ImagePNGSimple*, ips_iv);
if (ips->pBmp != NULL) {
free(ips->pBmp);
}
free(ips);
XSRETURN(0);
}
SV
read_bmp_file(...)
PPCODE :
{
SV* ips_obj = ST(0);
SV* ips_sv = SvROK(ips_obj) ? SvRV(ips_obj) : ips_obj;
size_t ips_iv = SvIV(ips_sv);
ImagePNGSimple* ips = INT2PTR(ImagePNGSimple*, ips_iv);
// Open bitmap file
SV* sv_file = ST(1);
char* file = SvPV_nolen(sv_file);
FILE* in_fh = fopen(file, "rb");
if (in_fh == NULL) {
croak("Can't open bitmap file %s", file);
}
// Create bitmap data
IBMP *pBmp = BmpIO_Load(in_fh);
fclose(in_fh);
if (pBmp == NULL) {
croak("Can't parse bitmap file %s", file);
}
ips->pBmp = pBmp;
XSRETURN(0);
}
SV
write_bmp_file(...)
PPCODE:
{
SV* ips_obj = ST(0);
SV* ips_sv = SvROK(ips_obj) ? SvRV(ips_obj) : ips_obj;
size_t ips_iv = SvIV(ips_sv);
ImagePNGSimple* ips = INT2PTR(ImagePNGSimple*, ips_iv);
// Not exists bitmap data
if (ips->pBmp == NULL) {
croak("Can't write bitmap because bitmap data is not loaded");
}
// Open file for write
SV* sv_file = ST(1);
char* file = SvPV_nolen(sv_file);
FILE* out_fh = fopen(file, "wb" );
if (out_fh == NULL) {
croak("Can't open file %s for writing", file);
}
BmpIO_Save(out_fh, ips->pBmp);
fclose(out_fh);
XSRETURN(0);
}
SV
write_png_file(...)
PPCODE:
{
SV* ips_obj = ST(0);
SV* ips_sv = SvROK(ips_obj) ? SvRV(ips_obj) : ips_obj;
size_t ips_iv = SvIV(ips_sv);
ImagePNGSimple* ips = INT2PTR(ImagePNGSimple*, ips_iv);
// Bitmap information
IBMP* pBmp = ips->pBmp;
// Not exists bitmap data
if (ips->pBmp == NULL) {
croak("Can't write bitmap because bitmap data is not loaded");
}
// Open file for write
SV* sv_file = ST(1);
char* file = SvPV_nolen(sv_file);
FILE* out_fh = fopen(file, "wb" );
if (out_fh == NULL) {
croak("Can't open file %s for writing", file);
}
// PNG information
IV x;
IV y;
// Create png write struct
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png == NULL)
{
fclose(out_fh);
croak("Fail png_create_write_struct");
}
// Create png information
png_infop info = png_create_info_struct(png);
if (info == NULL) {
png_destroy_write_struct(&png, (png_infopp)NULL);
fclose(out_fh);
croak("Fail png_create_info_struct");
}
// Set png error callback
png_bytep* lines = NULL;
if (setjmp(png_jmpbuf(png))) {
png_destroy_write_struct(&png, &info);
if (lines != NULL) {
free(lines);
}
fclose(out_fh);
croak("libpng internal error");
}
// Initialize png IO
png_init_io(png, out_fh);
// Image width
IV bmp_height = BmpIO_GetHeight(pBmp);
// Image height
( run in 2.493 seconds using v1.01-cache-2.11-cpan-71847e10f99 )