euspng.c
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #pragma init (register_euspng)
00026 
00027 #include <png.h>
00028 #include "eus.h"
00029 
00030 extern pointer ___euspng();
00031 static register_euspng()
00032 { add_module_initializer("___euspng", ___euspng);}
00033 
00034 pointer PNG_READ_IMAGE(register context *ctx, int n, register pointer *argv)
00035 {
00036   char *file_name;
00037   pointer ret, image_ptr;
00038   ckarg(1);
00039   if (isstring(argv[0])) file_name = argv[0]->c.str.chars;
00040   else error(E_NOSTRING);
00041 
00042   FILE *fp = fopen(file_name, "rb");
00043   if (!fp) {
00044     error(E_OPENFILE);
00045     return(NIL);
00046   }
00047 
00048   png_structp png_ptr;
00049   png_infop info_ptr;
00050   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
00051   info_ptr = png_create_info_struct(png_ptr);
00052 
00053   if (setjmp(png_jmpbuf(png_ptr))) {
00054     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
00055     fclose(fp);
00056     error(E_EOF);
00057     return(NIL);
00058   }
00059 
00060   png_init_io(png_ptr, fp);
00061   png_read_info(png_ptr, info_ptr);
00062   int width = png_get_image_width(png_ptr, info_ptr);
00063   int height = png_get_image_height(png_ptr, info_ptr);
00064   int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00065   int channels = png_get_channels(png_ptr, info_ptr);
00066   int color_type = png_get_color_type(png_ptr, info_ptr);
00067   //fprintf(stderr, "bit_depth = %d, channels %d, color_type =%d (pal:%d,gray:%d,rgb:%d,rgba:%d)\n", bit_depth, channels, color_type, PNG_COLOR_TYPE_PALETTE,PNG_COLOR_TYPE_GRAY,PNG_COLOR_TYPE_RGB,PNG_COLOR_TYPE_RGB_ALPHA);
00068   switch (color_type) {
00069   case PNG_COLOR_TYPE_PALETTE:
00070     png_set_palette_to_rgb(png_ptr);
00071     break;
00072   case PNG_COLOR_TYPE_GRAY:
00073     #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
00074     if ( bit_depth < 8) png_set_gray_to_rgb(png_ptr);
00075     #else
00076     if ( bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
00077     #endif
00078     break;
00079   case PNG_COLOR_TYPE_RGB:
00080     //png_set_bgr(png_ptr);
00081     if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit
00082     break;
00083   case PNG_COLOR_TYPE_RGB_ALPHA:
00084     if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit
00085     png_set_invert_alpha(png_ptr);
00086     //png_set_bgr(png_ptr);
00087     //png_set_strip_alpha(png_ptr);
00088     // RGBA -> rgb , GA -> g
00089     png_color_16 my_background = {0xff, 0xff, 0xff, 0xff, 0xff};
00090     png_set_background(png_ptr, &my_background,
00091                        PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
00092 
00093     break;
00094   }
00095   png_read_update_info(png_ptr, info_ptr);
00096   width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr);;
00097   bit_depth = png_get_bit_depth(png_ptr, info_ptr); channels = png_get_channels(png_ptr, info_ptr);
00098   color_type = png_get_color_type(png_ptr, info_ptr);
00099 
00100   png_bytep * row_pointers = (png_bytep *)malloc(height*sizeof(png_bytep));
00101   int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr);
00102   image_ptr = makebuffer(height*byte_per_scanline);
00103   for(y=0;y<height;y++){
00104     row_pointers[y] = image_ptr->c.str.chars+y*byte_per_scanline;
00105   }
00106   png_read_image(png_ptr, row_pointers);
00107   free(row_pointers);
00108   png_read_end(png_ptr,info_ptr);
00109   png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
00110   fclose(fp);
00111 
00112   ret=cons(ctx,image_ptr,NIL);
00113   ret=cons(ctx,makeint(channels),ret);
00114   ret=cons(ctx,makeint(height),ret);
00115   ret=cons(ctx,makeint(width),ret);
00116   return (ret);
00117 }
00118 
00119 pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
00120 {
00121   char *file_name, *image_ptr;
00122   int width, height, channels;
00123   ckarg(5);
00124   if (isstring(argv[0])) file_name = argv[0]->c.str.chars;
00125   else error(E_NOSTRING);
00126   width  = ckintval(argv[1]);
00127   height = ckintval(argv[2]);
00128   channels  = ckintval(argv[3]);
00129   image_ptr = argv[4]->c.str.chars;
00130   FILE *fp = fopen(file_name, "wb");
00131   if (!fp) {
00132     error(E_OPENFILE);
00133     return(NIL);
00134   }
00135 
00136   png_structp png_ptr;
00137   png_infop info_ptr;
00138   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
00139   info_ptr = png_create_info_struct(png_ptr);
00140 
00141   if (setjmp(png_jmpbuf(png_ptr))) {
00142     png_destroy_write_struct(&png_ptr, &info_ptr);
00143     fclose(fp);
00144     error(E_EOF);
00145     return(NIL);
00146   }
00147 
00148   png_init_io(png_ptr, fp);
00149   png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, //GRAY
00150                PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00151   png_bytep * row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
00152   int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr);
00153   for(y=0;y<height;y++){
00154     row_pointers[y] = &(image_ptr[y*byte_per_scanline]);
00155   }
00156   png_set_rows(png_ptr, info_ptr, row_pointers);
00157 
00158   png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, (png_voidp)NULL);
00159   png_write_end(png_ptr, info_ptr);
00160 
00161   free(row_pointers);
00162   png_destroy_write_struct(&png_ptr, &info_ptr);
00163 
00164   fclose(fp);
00165 
00166   return (T);
00167 }
00168 
00169 pointer ___euspng(register context *ctx, int n, register pointer *argv)
00170 {
00171     pointer mod=argv[0];
00172 
00173     defun(ctx, "PNG-READ-IMAGE",  mod, PNG_READ_IMAGE);
00174     defun(ctx, "PNG-WRITE-IMAGE", mod, PNG_WRITE_IMAGE);
00175 }
00176 


jskeus
Author(s): JSK Alumnis
autogenerated on Tue Mar 7 2017 04:04:34