Image-PNG-Simple

 view release on metacpan or  search on metacpan

Simple.xs  view on Meta::CPAN

#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 )