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
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
00081 if (bit_depth == 16) png_set_strip_16(png_ptr);
00082 break;
00083 case PNG_COLOR_TYPE_RGB_ALPHA:
00084 if (bit_depth == 16) png_set_strip_16(png_ptr);
00085 png_set_invert_alpha(png_ptr);
00086
00087
00088
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 fprintf(stderr, "%d %d %d %p\n", width, height, channels, image_ptr);
00131 FILE *fp = fopen(file_name, "wb");
00132 if (!fp) {
00133 error(E_OPENFILE);
00134 return(NIL);
00135 }
00136
00137 png_structp png_ptr;
00138 png_infop info_ptr;
00139 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
00140 info_ptr = png_create_info_struct(png_ptr);
00141
00142 if (setjmp(png_jmpbuf(png_ptr))) {
00143 png_destroy_write_struct(&png_ptr, &info_ptr);
00144 fclose(fp);
00145 error(E_EOF);
00146 return(NIL);
00147 }
00148
00149 png_init_io(png_ptr, fp);
00150 png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
00151 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00152 png_bytep * row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
00153 int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr);
00154 fprintf(stderr, "%d\n", byte_per_scanline);
00155 for(y=0;y<height;y++){
00156 row_pointers[y] = &(image_ptr[y*byte_per_scanline]);
00157 }
00158 png_set_rows(png_ptr, info_ptr, row_pointers);
00159
00160 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, (png_voidp)NULL);
00161 png_write_end(png_ptr, info_ptr);
00162
00163 free(row_pointers);
00164 png_destroy_write_struct(&png_ptr, &info_ptr);
00165
00166 fclose(fp);
00167
00168 return (T);
00169 }
00170
00171 pointer ___euspng(register context *ctx, int n, register pointer *argv)
00172 {
00173 pointer mod=argv[0];
00174
00175 defun(ctx, "PNG-READ-IMAGE", mod, PNG_READ_IMAGE);
00176 defun(ctx, "PNG-WRITE-IMAGE", mod, PNG_WRITE_IMAGE);
00177 }
00178