/** * Graphics::PNG is PNG library * * @author DATE Ken (as Itacchi) / ge6537@i.bekkoame.ne.jp * @code-name Aoi * @see http://www.isc.meiji.ac.jp/~ee77038/ruby/ * @ToDo progressive-read, any streaming input support, png_permit_empty_plte * $Id: reader.c,v 1.1 2000/09/27 17:11:43 date Exp date $ */ #include "libpng.h" #define PNG_AFTER_IDAT 0x08 #define READ_STATUS_FN "read_status_fn" #define READ_USER_TRANSFORM_FN "read_user_transform_fn" VALUE cReader; /* * ----------------------- * utility function for * Graphics::PNG::Reader * ----------------------- */ static void libpng_reader_free(png_obj) png_object *png_obj; { if (png_obj->fp) fclose(png_obj->fp); png_destroy_read_struct(&png_obj->obj, &png_obj->info, &png_obj->end_info); free(png_obj); } static void png_default_error(png_ptr, message) png_structp png_ptr; png_const_charp message; { rb_raise(ePngError, "Ruby/libpng error: %s\n", message); } static void png_default_warning(png_ptr, message) png_structp png_ptr; png_const_charp message; { rb_warning("Ruby/libpng warning: %s\n", message); } static void read_row_callback(png_ptr, row_number, pass) png_structp png_ptr; png_uint_32 row_number; int pass; { VALUE proc; if(png_ptr == NULL || row_number > PNG_MAX_UINT) return; proc = rb_iv_get(cReader, READ_STATUS_FN); if (NIL_P(proc)) return; rb_funcall(proc, rb_intern("call"), 2, INT2NUM(row_number), INT2FIX(pass)); } /* static void read_user_transform(png_ptr, row_info, data) png_structp png_ptr; png_row_infop row_info; png_bytep data; { VALUE proc; proc = rb_iv_get(cReader, READ_STATUS_FN); if (NIL_P(proc)) return; rb_funcall(proc, rb_intern("call"), 2, INT2NUM(row_number), rb_str_new2(data)); } */ /* * ----------------------- * class method of * Graphics::PNG::Reader * ----------------------- */ static VALUE libpng_reader_new(klass, file) VALUE klass, file; { FILE *fp; OpenFile *fptr; VALUE new_obj; png_object *png_obj; char buf[PNG_BYTES_TO_CHECK]; Check_Type(file, T_STRING); if ((fp = fopen(STR2CSTR(file), "rb")) == NULL){ rb_raise(ePngError, "can't open %s", STR2CSTR(file)); return Qnil; } if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){ rb_raise(rb_eException, "can't read %s", STR2CSTR(file)); return Qnil; } if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)){ rb_raise(ePngError, "not PNG file %s", STR2CSTR(file)); return Qnil; } /* create PNG object */ new_obj = Data_Make_Struct(klass, png_object, NULL, libpng_reader_free, png_obj); png_obj->fp = fp; png_obj->obj = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, png_default_error, png_default_warning); if (png_obj->obj == NULL){ fclose(fp); rb_raise(ePngError, "can't create PNG object (failer to create read struct)"); return Qnil; } png_set_sig_bytes(png_obj->obj, PNG_BYTES_TO_CHECK); png_obj->info = png_create_info_struct(png_obj->obj); png_obj->end_info = png_create_info_struct(png_obj->obj); if (png_obj->info == NULL || png_obj->end_info == NULL){ fclose(fp); png_destroy_read_struct(&png_obj->obj, &png_obj->info, &png_obj->end_info); rb_raise(ePngError, "can't create PNG object (failer to create info struct)"); return Qnil; } if (setjmp(png_jmpbuf(png_obj->obj))){ fclose(fp); png_destroy_read_struct(&png_obj->obj, &png_obj->info, &png_obj->end_info); rb_raise(ePngError, "PNG read error"); return Qnil; } png_init_io(png_obj->obj, png_obj->fp); png_read_info(png_obj->obj, png_obj->info); png_set_read_status_fn(png_obj->obj, read_row_callback); /* png_set_read_user_transform_fn(read_ptr, read_user_transform); */ rb_obj_call_init(new_obj, 1, &file); return new_obj; } /* * ----------------------- * instance method of * Graphics::PNG::Reader * ----------------------- */ static VALUE libpng_reader_initialize(obj) VALUE obj; { return Qnil; } #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_bit_depth(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_bit_depth(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) static VALUE libpng_reader_get_bKGD(obj) VALUE obj; { png_object *png_obj; png_color_16p background; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_bKGD(png_obj->obj, png_obj->info, &background)) return libpng_color_16_new2(cPngColor16, background); return Qnil; } #endif static VALUE libpng_reader_get_channels(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_channels(png_obj->obj, png_obj->info)); } #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_color_type(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_color_type(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #if defined(PNG_READ_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_get_cHRM(obj) VALUE obj; { png_object *png_obj; double white_x, red_x, green_x, blue_x; double white_y, red_y, green_y, blue_y; VALUE ary; GET_PNG_VAL(obj, png_obj); if(png_get_cHRM(png_obj->obj, png_obj->info, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)){ ary = rb_ary_new(); rb_ary_push(ary, rb_float_new(white_x)); rb_ary_push(ary, rb_float_new(white_y)); rb_ary_push(ary, rb_float_new(red_x)); rb_ary_push(ary, rb_float_new(red_y)); rb_ary_push(ary, rb_float_new(green_x)); rb_ary_push(ary, rb_float_new(green_y)); rb_ary_push(ary, rb_float_new(blue_y)); rb_ary_push(ary, rb_float_new(blue_x)); return ary; } return Qnil; } #endif /* PNG_FLOATING_POINT_SUPPORTED */ #ifdef PNG_FIXED_POINT_SUPPORTED static VALUE libpng_reader_get_cHRM_fixed(obj) VALUE obj; { png_object *png_obj; png_uint_32 white_x, red_x, green_x, blue_x; png_uint_32 white_y, red_y, green_y, blue_y; VALUE ary; GET_PNG_VAL(obj, png_obj); if(png_get_cHRM_fixed(png_obj->obj, png_obj->info, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)){ ary = rb_ary_new(); rb_ary_push(ary, INT2NUM(white_x)); rb_ary_push(ary, INT2NUM(white_y)); rb_ary_push(ary, INT2NUM(red_x)); rb_ary_push(ary, INT2NUM(red_y)); rb_ary_push(ary, INT2NUM(green_x)); rb_ary_push(ary, INT2NUM(green_y)); rb_ary_push(ary, INT2NUM(blue_x)); rb_ary_push(ary, INT2NUM(blue_y)); return ary; } return Qnil; } #endif /* PNG_FIXED_POINT_SUPPORTED */ #endif /* PNG_READ_cHRM_SUPPORTED */ #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_compression_type(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_compression_type(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_filter_type(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_filter_type(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #if defined(PNG_gAMA_SUPPORTED)|| defined(PNG_READ_GAMMA_SUPPORTED) static VALUE libpng_reader_get_gAMA(obj) VALUE obj; { png_object *png_obj; double image_gamma; GET_PNG_VAL(obj, png_obj); if(png_get_gAMA(png_obj->obj, png_obj->info, &image_gamma)) return rb_float_new(image_gamma); return Qnil; } #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_get_gAMA_fixed(obj) VALUE obj; { png_object *png_obj; png_uint_32 image_gamma; GET_PNG_VAL(obj, png_obj); if(png_get_gAMA_fixed(png_obj->obj, png_obj->info, &image_gamma)) return INT2NUM(image_gamma); return Qnil; } #endif /* PNG_FLOATING_POINT_SUPPORTED */ #endif /* PNG_gAMA_SUPPORTED || PNG_READ_GAMMA_SUPPORTED */ #if defined(PNG_READ_hIST_SUPPORTED) static VALUE libpng_reader_get_hIST(obj) VALUE obj; { png_object *png_obj; png_colorp palette; png_uint_16p histogram; int i, j, num_palette; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_PLTE(png_obj->obj, png_obj->info, &palette, &num_palette)){ if (png_get_hIST(png_obj->obj, png_obj->info, &histogram)){ ary = rb_ary_new2(num_palette); for (i = 0; i < num_palette; i++) rb_ary_push(ary, INT2NUM(histogram[i])); return ary; } } return Qnil; } #endif /* PNG_READ_hIST_SUPPORTED */ #if defined(PNG_READ_iCCP_SUPPORTED) static VALUE libpng_reader_get_iCCP(obj) VALUE obj; { png_object *png_obj; png_charpp name, profile; int compression_type; png_uint_32 proflen; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_iCCP(png_obj->obj, png_obj->info, name, &compression_type, profile, &proflen)){ ary = rb_ary_new(); rb_ary_push(ary, rb_str_new2(*name)); rb_ary_push(ary, INT2FIX(compression_type)); rb_ary_push(ary, rb_str_new(*profile, proflen)); rb_ary_push(ary, INT2FIX(proflen)); return ary; } return Qnil; } #endif /* PNG_READ_iCCP_SUPPORTED */ static VALUE libpng_reader_get_IHDR(obj) VALUE obj; { png_object *png_obj; png_uint_32 width, height; int bit_depth, color_type, interlace_type; int compression_type, filter_type; VALUE ary; GET_PNG_VAL(obj, png_obj); if(png_get_IHDR(png_obj->obj, png_obj->info, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type)){ ary = rb_ary_new(); rb_ary_push(ary, INT2NUM(width)); rb_ary_push(ary, INT2NUM(height)); rb_ary_push(ary, INT2FIX(bit_depth)); rb_ary_push(ary, INT2FIX(color_type)); rb_ary_push(ary, INT2FIX(interlace_type)); rb_ary_push(ary, INT2FIX(compression_type)); rb_ary_push(ary, INT2FIX(filter_type)); return ary; } return Qnil; } static VALUE libpng_reader_get_image_container(obj) VALUE obj; { png_object *png_obj; int height, row_bytes, i; VALUE ary, str; GET_PNG_VAL(obj, png_obj); height = png_get_image_height(png_obj->obj, png_obj->info); row_bytes = png_get_rowbytes(png_obj->obj, png_obj->info); ary = rb_ary_new(); for (i=0; iobj, png_obj->info)); } static VALUE libpng_reader_get_image_width(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_image_width(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #if defined(PNG_READ_oFFs_SUPPORTED) static VALUE libpng_reader_get_oFFs(obj) VALUE obj; { png_object *png_obj; png_uint_32 offset_x, offset_y; int unit_type; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_oFFs(png_obj->obj, png_obj->info, &offset_x, &offset_y, &unit_type)){ ary = rb_ary_new(); rb_ary_push(ary, INT2NUM(offset_x)); rb_ary_push(ary, INT2NUM(offset_y)); rb_ary_push(ary, INT2FIX(unit_type)); return ary; } return Qnil; } #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_x_offset_pixels(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_x_offset_pixels(png_obj->obj, png_obj->info)); } static VALUE libpng_reader_get_y_offset_pixels(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_y_offset_pixels(png_obj->obj, png_obj->info)); } static VALUE libpng_reader_get_x_offset_microns(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_x_offset_microns(png_obj->obj, png_obj->info)); } static VALUE libpng_reader_get_y_offset_microns(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_y_offset_microns(png_obj->obj, png_obj->info)); } #endif /* PNG_EASY_ACCESS_SUPPORTED */ #endif /* PNG_READ_oFFs_SUPPORTED */ #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_interlace_type(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_interlace_type(png_obj->obj, png_obj->info)); } #endif static VALUE libpng_reader_get_PLTE(obj) VALUE obj; { png_object *png_obj; png_colorp palette; int i, num_palette; VALUE ary, color; GET_PNG_VAL(obj, png_obj); if (png_get_PLTE(png_obj->obj, png_obj->info, &palette, &num_palette)){ ary = rb_ary_new(); for (i = 0; i < num_palette; i++){ color = libpng_color_new2(cPngColor, &palette[i]); rb_ary_push(ary, color); } return ary; } return Qnil; } #if defined(PNG_READ_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_get_sCAL(obj) { png_object *png_obj; int unit; double width, height; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_sCAL(png_obj->obj, png_obj->info, &unit, &width, &height)){ ary = rb_ary_new(); rb_ary_push(ary, INT2FIX(unit)); rb_ary_push(ary, rb_float_new(width)); rb_ary_push(ary, rb_float_new(height)); return ary; } return Qnil; } #else #ifdef PNG_FIXED_POINT_SUPPORTED static VALUE libpng_reader_png_get_sCAL(obj) { png_object *png_obj; int unit; png_charpp swidth, sheight; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_sCAL_s(png_obj->obj, png_obj->info, &unit, swidth, sheight)){ ary = rb_ary_new(); rb_ary_push(ary, INT2FIX(unit)); rb_ary_push(ary, rb_str_new2(swidth)); rb_ary_push(ary, rb_str_new2(sheight)); return ary; } return Qnil; } #endif /* PNG_FIXED_POINT_SUPPORTED */ #endif #endif /* PNG_READ_sCAL_SUPPORTED */ #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_get_pixel_aspect_ratio(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return rb_float_new(png_get_pixel_aspect_ratio(png_obj->obj, png_obj->info)); } #endif /* PNG_FLOATING_POINT_SUPPORTED */ #if defined(PNG_READ_pCAL_SUPPORTED) static VALUE libpng_reader_get_pCAL(obj) VALUE obj; { png_object *png_obj; png_charp purpose, units; png_int_32 X0, X1; int i, type, nparams; png_charpp params; VALUE ary, ary2; GET_PNG_VAL(obj, png_obj); if (png_get_pCAL(png_obj->obj, png_obj->info, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms)){ ary = rb_ary_new(); rb_ary_push(ary, rb_str_new2(purpose)); rb_ary_push(ary, INT2NUM(X0)); rb_ary_push(ary, INT2NUM(X1)); rb_ary_push(ary, INT2NUM(type)); rb_ary_push(ary, rb_str_new2(units)); ary2 = rb_ary_new(); for (i = 0; i < nparams; i++) rb_ary_push(ary2, rb_str_new2(params[i])); rb_ary_push(ary, ary2); return ary; } return Qnil; } #endif /* PNG_READ_pCAL_SUPPORTED */ #if defined(PNG_READ_pHYs_SUPPORTED) static VALUE libpng_reader_get_pHYs(obj) VALUE obj; { png_object *png_obj; png_uint_32 res_x, res_y; int unit_type; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_get_pHYs(png_obj->obj, png_obj->info, &res_x, &res_y, &unit_type)){ ary = rb_ary_new(); rb_ary_push(ary, INT2NUM(res_x)); rb_ary_push(ary, INT2NUM(res_y)); rb_ary_push(ary, INT2FIX(unit_type)); return ary; } return Qnil; } #endif /* PNG_READ_pHYs_SUPPORTED */ #ifdef PNG_EASY_ACCESS_SUPPORTED static VALUE libpng_reader_get_pixels_per_meter(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_pixels_per_meter(png_obj->obj, png_obj->info)); } static VALUE libpng_reader_get_x_pixels_per_meter(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_x_pixels_per_meter(png_obj->obj, png_obj->info)); } static VALUE libpng_reader_get_y_pixels_per_meter(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_y_pixels_per_meter(png_obj->obj, png_obj->info)); } #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) static VALUE libpng_reader_get_rgb_to_gray_status(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2NUM(png_get_rgb_to_gray_status(png_obj->obj)); } #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ static VALUE libpng_reader_get_signature(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return rb_str_new2(png_get_signature(png_obj->obj, png_obj->info)); } #if defined(PNG_sBIT_SUPPORTED) static VALUE libpng_reader_get_sBIT(obj) VALUE obj; { png_object *png_obj; png_color_8p sig_bit; int bit_depth, i; GET_PNG_VAL(obj, png_obj); if (png_get_sBIT(png_obj->obj, png_obj->info, &sig_bit)) return libpng_color_8_new2(cPngColor8, sig_bit); return Qnil; } #endif #if defined(PNG_READ_sRGB_SUPPORTED) static VALUE libpng_reader_get_sRGB(obj) VALUE obj; { png_object *png_obj; int intent; GET_PNG_VAL(obj, png_obj); if (png_get_sRGB(png_obj->obj, png_obj->info, &intent)) return INT2FIX(intent); return Qnil; } #endif /* PNG_READ_sRGB_SUPPORTED */ #if defined(PNG_sPLT_SUPPORTED) static VALUE libpng_reader_get_suggested_palette(obj, palette_name) VALUE obj, palette_name; { png_object *png_obj; png_sPLT_tpp entries = NULL; png_uint_32 num; png_sPLT_entryp entry; VALUE ary, tmp, sPLT_entry; int i, j; Check_Type(palette_name, T_STRING); GET_PNG_VAL(obj, png_obj); num = png_get_sPLT(png_obj->obj, png_obj->info, entries); if (num != 0 && entries){ ary = rb_ary_new(); for (i = 0; i < num; i++){ if (strcmp(STR2CSTR(palette_name), (*entries)->name) == 0){ tmp = rb_ary_new(); rb_ary_push(tmp, rb_str_new2((*entries)->name)); rb_ary_push(tmp, INT2FIX((*entries)->depth)); entry = (*entries)->entries; for (j = 0; j < (*entries)->nentries; j++){ sPLT_entry = libpng_sPLT_entry_new2(cSuggestedPaletteEntry, &entry[j]); rb_ary_push(tmp, sPLT_entry); } rb_ary_push(ary, tmp); entries++; } } return ary; } return Qnil; } static VALUE libpng_reader_get_sPLT(obj) VALUE obj; { png_object *png_obj; png_sPLT_tpp entries = NULL; png_uint_32 num; png_sPLT_entryp entry; VALUE ary, tmp, sPLT_entry; int i, j; GET_PNG_VAL(obj, png_obj); num = png_get_sPLT(png_obj->obj, png_obj->info, entries); if (num != 0 && entries){ ary = rb_ary_new(); for (i = 0; i < num; i++){ tmp = rb_ary_new(); rb_ary_push(tmp, rb_str_new2((*entries)->name)); rb_ary_push(tmp, INT2FIX((*entries)->depth)); entry = (*entries)->entries; for (j = 0; j < (*entries)->nentries; j++){ sPLT_entry = libpng_sPLT_entry_new2(cSuggestedPaletteEntry, &entry[j]); rb_ary_push(tmp, sPLT_entry); } rb_ary_push(ary, tmp); entries++; } return ary; } return Qnil; } #endif #if defined(PNG_READ_TEXT_SUPPORTED) static VALUE libpng_reader_get_text(obj, key) VALUE obj, key; { png_object *png_obj; png_textp text_ptr; png_infop info_ptr; int num_text, i; VALUE ary; Check_Type(key, T_STRING); GET_PNG_VAL(obj, png_obj); if (png_obj->obj->mode & PNG_AFTER_IDAT) info_ptr = png_obj->end_info; else info_ptr = png_obj->info; if (png_get_text(png_obj->obj, info_ptr, &text_ptr, &num_text) > 0){ ary = rb_ary_new(); for (i=0; ikey, STR2CSTR(key)) == 0) rb_ary_push(ary, libpng_text_new2(cText, &text_ptr[i])); } return ary; } return Qnil; } static VALUE libpng_reader_get_texts(obj) VALUE obj; { png_object *png_obj; png_textp text_ptr; png_infop info_ptr; int num_text, i; VALUE ary; GET_PNG_VAL(obj, png_obj); if (png_obj->obj->mode & PNG_AFTER_IDAT) info_ptr = png_obj->end_info; else info_ptr = png_obj->info; if (png_get_text(png_obj->obj, info_ptr, &text_ptr, &num_text) > 0){ ary = rb_ary_new(); for (i=0; iobj->mode & PNG_AFTER_IDAT) info_ptr = png_obj->end_info; else info_ptr = png_obj->info; if (png_get_tIME(png_obj->obj, info_ptr, &mod_time)){ time = rb_funcall(rb_eval_string("Time"), rb_intern("gm"), 6, INT2FIX(mod_time->year), INT2FIX(mod_time->month), INT2FIX(mod_time->day), INT2FIX(mod_time->hour), INT2FIX(mod_time->minute), INT2FIX(mod_time->second)); return time; } return Qnil; } #endif /* PNG_READ_tIME_SUPPORTED */ #if defined(PNG_READ_tRNS_SUPPORTED) static VALUE libpng_reader_get_tRNS(obj) VALUE obj; { png_object *png_obj; png_byte color_type; png_bytep trans; png_colorp palette; int i, num_trans; png_color_16p trans_values; VALUE ary; GET_PNG_VAL(obj, png_obj); color_type = png_get_color_type(png_obj->obj, png_obj->info); if (color_type == PNG_COLOR_TYPE_PALETTE){ if (png_get_tRNS(png_obj->obj, png_obj->info, &trans, &num_trans, &trans_values)){ ary = rb_ary_new(); for (i = 0; i < num_trans; i++) rb_ary_push(ary, INT2FIX(trans[i])); return ary; } } else if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_RGB){ if (png_get_tRNS(png_obj->obj, png_obj->info, &trans, &num_trans, &trans_values)) return libpng_color_16_new2(cPngColor16, trans_values); } return Qnil; } #endif /* PNG_READ_tRNS_SUPPORTED */ #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) static VALUE libpng_reader_get_unknown_chunks(obj) VALUE obj; { png_object *png_obj; png_unknown_chunkpp unknowns; png_uint_32 num_unknowns; VALUE ary; int i; GET_PNG_VAL(obj, png_obj); if (num_unknowns = png_get_unknown_chunks(png_obj->obj, png_obj->info, unknowns)){ ary = rb_ary_new(); for (i=0; iobj, png_obj->info, (png_uint_32)FIX2INT(flag))) return Qtrue; return Qfalse; } static VALUE libpng_reader_read_end(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_read_end(png_obj->obj, png_obj->end_info); return Qnil; } static VALUE libpng_reader_read_image(obj) VALUE obj; { png_object *png_obj; png_bytepp row_pointers; int number_passes, pass, height, row, row_bytes; VALUE str, ary; GET_PNG_VAL(obj, png_obj); number_passes = png_set_interlace_handling(png_obj->obj); height = png_get_image_height(png_obj->obj, png_obj->info); row_bytes = png_get_rowbytes(png_obj->obj, png_obj->info); row_pointers = ALLOC_N(png_bytep, height); for (row=0; rowobj, row_pointers); */ for (pass=0; passobj, &row_pointers[row], NULL, 1); ary = rb_ary_new(); for (row=0; rowobj, png_obj->info); if (RSTRING(row)->len < row_bytes) rb_raise(ePngError, "not enough to byte string size"); row_pointer = RSTRING(row)->ptr; break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected String/nil)", rb_class2name(CLASS_OF(row))); return Qnil; } switch(TYPE(display_row)){ case T_NIL: display_row_pointer = NULL; break; case T_STRING: row_bytes = png_get_rowbytes(png_obj->obj, png_obj->info); if (RSTRING(display_row)->len < row_bytes) rb_raise(ePngError, "not enough to byte string size"); display_row_pointer = RSTRING(display_row)->ptr; break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected String/nil)", rb_class2name(CLASS_OF(row))); return Qnil; } if (row_pointer != NULL || display_row_pointer != NULL){ png_read_row(png_obj->obj, row_pointer, display_row_pointer); } return Qnil; } static VALUE libpng_reader_read_rows(obj, row, display_row) VALUE obj, row, display_row; { png_object *png_obj; png_bytepp row_pointers, display_row_pointers; int num_rows, row_bytes, i; FIXNUM_P(num_rows); GET_PNG_VAL(obj, png_obj); row_bytes = png_get_rowbytes(png_obj->obj, png_obj->info); switch(TYPE(row)){ case T_NIL: row_pointers = NULL; break; case T_ARRAY: num_rows = RARRAY(row)->len; row_pointers = ALLOC_N(png_bytep, num_rows); for (i=0; iptr[i], T_STRING); if (RSTRING(RARRAY(row)->ptr[i])->len < row_bytes) rb_raise(ePngError, "not enough to byte string size"); row_pointers[i] = RSTRING(RARRAY(row)->ptr[i])->ptr; } break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected Array/nil)", rb_class2name(CLASS_OF(row))); return Qnil; } switch(TYPE(display_row)){ case T_NIL: display_row_pointers = NULL; break; case T_ARRAY: num_rows = RARRAY(display_row)->len; display_row_pointers = ALLOC_N(png_bytep, num_rows); for (i=0; iptr[i], T_STRING); if (RSTRING(RARRAY(display_row)->ptr[i])->len < row_bytes) rb_raise(ePngError, "not enough to byte string size"); display_row_pointers[i] = RSTRING(RARRAY(display_row)->ptr[i])->ptr; } break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected Array/nil)", rb_class2name(CLASS_OF(display_row))); return Qnil; } if (row_pointers != NULL || display_row_pointers != NULL) png_read_rows(png_obj->obj, row_pointers, display_row_pointers, num_rows); free(row_pointers); free(display_row_pointers); return Qnil; } static VALUE libpng_reader_read_update_info(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_read_update_info(png_obj->obj, png_obj->info); return Qnil; } #if defined(PNG_READ_BACKGROUND_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_set_background(obj, background_color, background_gamma_code, need_expand, background_gamma) VALUE obj, background_color, background_gamma_code, need_expand, background_gamma; { png_object *png_obj; png_color_16p bg_color; IS_COLOR_16_P(background_color); FIXNUM_P(background_gamma_code); FIXNUM_P(need_expand); Check_Type(background_gamma, T_FLOAT); GET_PNG_VAL(obj, png_obj); Data_Get_Struct(background_color, png_color_16, bg_color); png_set_background(png_obj->obj, bg_color, NUM2INT(background_gamma_code), NUM2INT(need_expand), RFLOAT(background_gamma)->value); return Qnil; } #endif /* PNG_FLOATING_POINT_SUPPORTED */ #endif /* PNG_READ_BACKGROUND_SUPPORTED */ #if defined(PNG_READ_BGR_SUPPORTED) static VALUE libpng_reader_set_bgr(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_bgr(png_obj->obj); return Qnil; } #endif /* PNG_READ_BGR_SUPPORTED */ static VALUE libpng_reader_set_crc_action(obj, crit_action, ancil_action) VALUE obj, crit_action, ancil_action; { png_object *png_obj; int critical_action, ancillary_action; FIXNUM_P(crit_action); FIXNUM_P(ancil_action); GET_PNG_VAL(obj, png_obj); critical_action = FIX2INT(crit_action); ancillary_action = FIX2INT(ancil_action); if (critical_action < PNG_CRC_DEFAULT || critical_action > PNG_CRC_NO_CHANGE){ rb_raise(ePngError, "invalid type to handle CRC errors in critical chunks: %d", critical_action); } if (ancillary_action < PNG_CRC_DEFAULT || ancillary_action > PNG_CRC_NO_CHANGE){ rb_raise(ePngError, "invalid type to handle CRC errors in ancillary chunks: %d", ancillary_action); } png_set_crc_action(png_obj->obj, critical_action, ancillary_action); return Qnil; } #if defined(PNG_READ_DITHER_SUPPORTED) static VALUE libpng_reader_set_dither(obj, palettes, maximum_colors, histogram, full_dither) VALUE obj, palettes, maximum_colors, histogram, full_dither; { png_object *png_obj; png_colorp dither_palette; png_uint_16p dither_histogram; png_color *color; VALUE cobj, val; int i; Check_Type(palettes, T_ARRAY); FIXNUM_P(maximum_colors); Check_Type(histogram, T_ARRAY); FIXNUM_P(full_dither); GET_PNG_VAL(obj, png_obj); dither_palette = ALLOCA_N(png_color, RARRAY(palettes)->len); for (i=0; ilen; i++){ cobj = RARRAY(palettes)->ptr[i]; IS_COLOR_P(cobj); Data_Get_Struct(cobj, png_color, color); dither_palette[i] = *color; } dither_histogram = ALLOCA_N(png_uint_16, RARRAY(histogram)->len); for (i=0; ilen; i++){ val = RARRAY(histogram)->ptr[i]; FIXNUM_P(val); dither_histogram[i] = NUM2LONG(val); } png_set_dither(png_obj->obj, dither_palette, FIX2INT(maximum_colors), RARRAY(palettes)->len, dither_histogram, FIX2INT(full_dither)); return Qnil; } #endif /* PNG_READ_DITHER_SUPPORTED */ #if defined(PNG_READ_EXPAND_SUPPORTED) static VALUE libpng_reader_set_expand(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_expand(png_obj->obj); return Qnil; } #endif /* PNG_READ_EXPAND_SUPPORTED */ #if defined(PNG_READ_FILLER_SUPPORTED) static VALUE libpng_reader_set_filler(obj, filler, flags) VALUE obj, filler, flags; { png_object *png_obj; int filler_flags; FIXNUM_P(filler); FIXNUM_P(flags); GET_PNG_VAL(obj, png_obj); filler_flags = FIX2INT(flags); if (filler_flags < PNG_FILLER_BEFORE || filler_flags > PNG_FILLER_AFTER) rb_raise(ePngError, "invalid filler flag type: %d", filler_flags); png_set_filler(png_obj->obj, NUM2LONG(filler), FIX2INT(flags)); return Qnil; } #endif /* PNG_READ_FILLER_SUPPORTED */ #if defined(PNG_READ_GAMMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_set_gamma(obj, screen_gamma, default_file_gamma) VALUE obj, screen_gamma, default_file_gamma; { png_object *png_obj; Check_Type(screen_gamma, T_FLOAT); Check_Type(default_file_gamma, T_FLOAT); GET_PNG_VAL(obj, png_obj); png_set_gamma(png_obj->obj, RFLOAT(screen_gamma)->value, RFLOAT(default_file_gamma)->value); return Qnil; } #endif /* PNG_FLOATING_POINT_SUPPORTED */ #endif /* PNG_READ_GAMMA_SUPPORTED */ #if defined(PNG_READ_EXPAND_SUPPORTED) static VALUE libpng_reader_set_gray_1_2_4_to_8(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_gray_1_2_4_to_8(png_obj->obj); return Qnil; } #endif /* PNG_READ_EXPAND_SUPPORTED */ #if defined(PNG_READ_INTERLACING_SUPPORTED) static VALUE libpng_reader_set_interlace_handling(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); return INT2FIX(png_set_interlace_handling(png_obj->obj)); } #endif /* PNG_READ_INTERLACING_SUPPORTE */ #if defined(PNG_READ_INVERT_SUPPORTED) static VALUE libpng_reader_set_invert_mono(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_invert_mono(png_obj->obj); return Qnil; } #endif /* PNG_READ_INVERT_SUPPORTE */ #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) static VALUE libpng_reader_set_keep_unknown_chunks(obj, keep, chunk_list) VALUE obj, keep, chunk_list; { png_object *png_obj; int keep_condition, num_chunks, i; png_bytep affect_chunk_list; FIXNUM_P(keep); keep_condition = FIX2INT(keep); if (keep_condition < HANDLE_CHUNK_AS_DEFAULT || keep_condition > HANDLE_CHUNK_ALWAYS){ rb_raise(ePngError, "invalid \"keep\" directive for unknown chunks: %d", keep_condition); } GET_PNG_VAL(obj, png_obj); switch(TYPE(chunk_list)){ case T_NIL: png_set_keep_unknown_chunks(png_obj->obj, keep_condition, NULL, 0); break; case T_ARRAY: num_chunks = RARRAY(chunk_list)->len; affect_chunk_list = ALLOCA_N(char, 5 * num_chunks); for (i=0; iptr[i], T_STRING); png_memcpy(affect_chunk_list, STR2CSTR(RARRAY(chunk_list)->ptr[i]), 4); png_memcpy(affect_chunk_list, '\0', 1); } png_set_keep_unknown_chunks(png_obj->obj, keep_condition, affect_chunk_list, num_chunks); break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected Array/nil)", rb_class2name(CLASS_OF(chunk_list))); } return Qnil; } #endif /* PNG_UNKNOWN_CHUNKS_SUPPORTED */ #if defined(PNG_READ_PACK_SUPPORTED) static VALUE libpng_reader_set_packing(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_packing(png_obj->obj); return Qnil; } #endif /* PNG_READ_PACK_SUPPORTED */ #if defined(PNG_READ_PACKSWAP_SUPPORTED) static VALUE libpng_reader_set_packswap(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_packswap(png_obj->obj); return Qnil; } #endif /* PNG_READ_PACKSWAP_SUPPORTED */ #if defined(PNG_READ_EXPAND_SUPPORTED) static VALUE libpng_reader_set_palette_to_rgb(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_palette_to_rgb(png_obj->obj); return Qnil; } #endif /* PNG_READ_EXPAND_SUPPORTED */ static VALUE libpng_reader_set_read_status_fn(obj, proc) VALUE obj, proc; { if (!rb_respond_to(proc, rb_intern("call"))) rb_raise(rb_eArgError, "argument have to respond to `call'"); return rb_iv_set(cReader, READ_STATUS_FN, proc); } #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) static VALUE libpng_reader_set_read_user_transform_fn(obj, proc) VALUE obj, proc; { if (!rb_respond_to(proc, rb_intern("call"))) rb_raise(rb_eArgError, "argument have to respond to `call'"); return rb_iv_set(cReader, READ_USER_TRANSFORM_FN, proc); } #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED */ #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED static VALUE libpng_reader_set_rgb_to_gray(obj, error_action, red, green) VALUE obj, error_action, red, green; { png_object *png_obj; FIXNUM_P(error_action); Check_Type(red, T_FLOAT); Check_Type(green, T_FLOAT); GET_PNG_VAL(obj, png_obj); png_set_rgb_to_gray(png_obj->obj, FIX2INT(error_action), RFLOAT(red)->value, RFLOAT(green)->value); return Qnil; } #endif /* PNG_FLOATING_POINT_SUPPORTED */ static VALUE libpng_reader_set_rgb_to_gray_fixed(obj, error_action, red, green) VALUE obj, error_action, red, green; { png_object *png_obj; FIXNUM_P(error_action); FIXNUM_P(red); FIXNUM_P(green); GET_PNG_VAL(obj, png_obj); png_set_rgb_to_gray(png_obj->obj, FIX2INT(error_action), FIX2INT(red), FIX2INT(green)); return Qnil; } #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ #if defined(PNG_READ_SHIFT_SUPPORTED) static VALUE libpng_reader_set_shift(obj, true_bits) VALUE obj, true_bits; { png_object *png_obj; png_color_8p sig_bit; VALUE cobj; int i; IS_COLOR_8_P(cobj); GET_PNG_VAL(obj, png_obj); Data_Get_Struct(cobj, png_color_8, sig_bit); png_set_shift(png_obj->obj, sig_bit); return Qnil; } #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) static VALUE libpng_reader_set_strip_16(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_strip_16(png_obj->obj); return Qnil; } #endif /* PNG_READ_16_TO_8_SUPPORTED */ #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) static VALUE libpng_reader_set_strip_alpha(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_strip_alpha(png_obj->obj); return Qnil; } #endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */ #if defined(PNG_READ_SWAP_SUPPORTED) static VALUE libpng_reader_set_swap(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_swap(png_obj->obj); return Qnil; } #endif /* PNG_READ_SWAP_SUPPORTED */ #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) static VALUE libpng_reader_set_swap_alpha(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_swap_alpha(png_obj->obj); return Qnil; } #endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */ #if defined(PNG_READ_EXPAND_SUPPORTED) static VALUE libpng_reader_set_tRNS_to_alpha(obj) VALUE obj; { png_object *png_obj; GET_PNG_VAL(obj, png_obj); png_set_tRNS_to_alpha(png_obj->obj); return Qnil; } #endif /* PNG_READ_EXPAND_SUPPORTED */ void Init_reader() { /* * --------------------- * Graphics::PNG::Reader * --------------------- */ cReader = rb_define_class_under(mPng, "Reader", rb_cObject); /* define class methods */ rb_define_singleton_method(cReader, "new", libpng_reader_new, 1); /* define instance methods */ rb_define_method(cReader, "initialize", libpng_reader_initialize, -1); rb_define_method(cReader, "get_bit_depth", libpng_reader_get_bit_depth, 0); #if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) rb_define_method(cReader, "get_bKGD", libpng_reader_get_bKGD, 0); #endif rb_define_method(cReader, "get_channels", libpng_reader_get_channels, 0); #if defined(PNG_cHRM_SUPPORTED) rb_define_method(cReader, "get_cHRM", libpng_reader_get_cHRM, 0); rb_define_method(cReader, "get_cHRM_fixed", libpng_reader_get_cHRM_fixed, 0); #endif rb_define_method(cReader, "get_color_type", libpng_reader_get_color_type, 0); rb_define_method(cReader, "get_compression_type", libpng_reader_get_compression_type, 0); rb_define_method(cReader, "get_filter_type", libpng_reader_get_filter_type, 0); #if defined(PNG_gAMA_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) rb_define_method(cReader, "get_gAMA", libpng_reader_get_gAMA, 0); rb_define_method(cReader, "get_gAMA_fixed", libpng_reader_get_gAMA_fixed, 0); #endif #if defined(PNG_hIST_SUPPORTED) rb_define_method(cReader, "get_hIST", libpng_reader_get_hIST, 0); #endif #if defined(PNG_iCCP_SUPPORTED) rb_define_method(cReader, "get_iCCP", libpng_reader_get_iCCP, 0); #endif rb_define_method(cReader, "get_IHDR", libpng_reader_get_IHDR, 0); rb_define_method(cReader, "get_image_container", libpng_reader_get_image_container, 0); rb_define_method(cReader, "get_image_height", libpng_reader_get_image_height, 0); rb_define_method(cReader, "get_image_width", libpng_reader_get_image_width, 0); #if defined(PNG_oFFs_SUPPORTED) rb_define_method(cReader, "get_oFFs", libpng_reader_get_oFFs, 0); #if defined(PNG_EASY_ACCESS_SUPPORTED) rb_define_method(cReader, "get_x_offset_pixels", libpng_reader_get_x_offset_pixels, 0); rb_define_method(cReader, "get_y_offset_pixels", libpng_reader_get_y_offset_pixels, 0); rb_define_method(cReader, "get_x_offset_microns", libpng_reader_get_x_offset_microns, 0); rb_define_method(cReader, "get_y_offset_microns", libpng_reader_get_y_offset_microns, 0); #endif /* PNG_EASY_ACCESS_SUPPORTED */ #endif /* PNG_oFFs_SUPPORTED */ rb_define_method(cReader, "get_interlace_type", libpng_reader_get_interlace_type, 0); rb_define_method(cReader, "get_PLTE", libpng_reader_get_PLTE, 0); #if defined(PNG_READ_sCAL_SUPPORTED) rb_define_method(cReader, "get_sCAL", libpng_reader_get_sCAL, 0); #endif #ifdef PNG_FLOATING_POINT_SUPPORTED rb_define_method(cReader, "get_pixel_aspect_ratio", libpng_reader_get_pixel_aspect_ratio, 0); #endif #if defined(PNG_pCAL_SUPPORTED) rb_define_method(cReader, "get_pCAL", libpng_reader_get_pCAL, 0); #endif #if defined(PNG_pHYs_SUPPORTED) rb_define_method(cReader, "get_pHYs", libpng_reader_get_pHYs, 0); #endif #ifdef PNG_EASY_ACCESS_SUPPORTED rb_define_method(cReader, "get_pixels_per_meter", libpng_reader_get_pixels_per_meter, 0); rb_define_method(cReader, "get_x_pixels_per_meter", libpng_reader_get_x_pixels_per_meter, 0); rb_define_method(cReader, "get_y_pixels_per_meter", libpng_reader_get_y_pixels_per_meter, 0); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) rb_define_method(cReader, "get_rgb_to_gray_status", libpng_reader_get_rgb_to_gray_status, 0); #endif rb_define_method(cReader, "get_signature", libpng_reader_get_signature, 0); #if defined(PNG_sBIT_SUPPORTED) rb_define_method(cReader, "get_sBIT", libpng_reader_get_sBIT, 0); #endif #if defined(PNG_READ_sRGB_SUPPORTED) rb_define_method(cReader, "get_sRGB", libpng_reader_get_sRGB, 0); #endif #if defined(PNG_sPLT_SUPPORTED) /* rb_define_method(cReader, "suggested_palette", libpng_reader_get_suggested_palette, 1); */ rb_define_method(cReader, "get_sPLT", libpng_reader_get_sPLT, 0); #endif #if defined(PNG_READ_TEXT_SUPPORTED) rb_define_method(cReader, "get_text", libpng_reader_get_text, 1); rb_define_method(cReader, "get_texts", libpng_reader_get_texts, 0); #endif #if defined(PNG_tIME_SUPPORTED) rb_define_method(cReader, "get_tIME", libpng_reader_get_tIME, 0); #endif #if defined(PNG_READ_tRNS_SUPPORTED) rb_define_method(cReader, "get_tRNS", libpng_reader_get_tRNS, 0); #endif rb_define_method(cReader, "valid?", libpng_reader_get_valid_p, 1); rb_define_method(cReader, "read_end", libpng_reader_read_end, 0); rb_define_method(cReader, "read_image", libpng_reader_read_image, 0); rb_define_method(cReader, "read_row", libpng_reader_read_row, 2); rb_define_method(cReader, "read_rows", libpng_reader_read_rows, 2); rb_define_method(cReader, "read_update_info", libpng_reader_read_update_info, 0); #if defined(PNG_READ_BACKGROUND_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED rb_define_method(cReader, "set_background", libpng_reader_set_background, 4); #endif #endif #if defined(PNG_READ_BGR_SUPPORTED) rb_define_method(cReader, "set_bgr", libpng_reader_set_bgr, 0); #endif rb_define_method(cReader, "set_crc_action", libpng_reader_set_crc_action, 2); #if defined(PNG_READ_DITHER_SUPPORTED) rb_define_method(cReader, "set_dither", libpng_reader_set_dither, 4); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) rb_define_method(cReader, "set_expand", libpng_reader_set_expand, 0); #endif #if defined(PNG_READ_FILLER_SUPPORTED) rb_define_method(cReader, "set_filler", libpng_reader_set_filler, 2); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED rb_define_method(cReader, "set_gamma", libpng_reader_set_gamma, 2); #endif #endif #if defined(PNG_READ_EXPAND_SUPPORTED) rb_define_method(cReader, "set_gray_1_2_4_to_8", libpng_reader_set_gray_1_2_4_to_8, 0); #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) rb_define_method(cReader, "set_interlace_handling", libpng_reader_set_interlace_handling, 0); #endif #if defined(PNG_READ_INVERT_SUPPORTED) rb_define_method(cReader, "set_invert_mono", libpng_reader_set_invert_mono, 0); #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) rb_define_method(cReader, "set_keep_unknown_chunks", libpng_reader_set_keep_unknown_chunks, 2); #endif #if defined(PNG_READ_PACK_SUPPORTED) rb_define_method(cReader, "set_packing", libpng_reader_set_packing, 0); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) rb_define_method(cReader, "set_packswap", libpng_reader_set_packswap, 0); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) rb_define_method(cReader, "set_palette_to_rgb", libpng_reader_set_palette_to_rgb, 0); #endif /* related progressive reading rb_define_method(cReader, "set_progressive_read_fn", libpng_set_progressive_read_fn, 3); png_process_data png_progressive_combine_row */ rb_define_method(cReader, "set_read_status_fn", libpng_reader_set_read_status_fn, 1); #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) rb_define_method(cReader, "set_read_user_transform_fn", libpng_reader_set_read_user_transform_fn, 1); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED rb_define_method(cReader, "set_rgb_to_gray", libpng_reader_set_rgb_to_gray, 3); #endif rb_define_method(cReader, "set_rgb_to_gray_fixed", libpng_reader_set_rgb_to_gray_fixed, 3); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) rb_define_method(cReader, "set_shift", libpng_reader_set_shift, 1); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) rb_define_method(cReader, "set_strip_16", libpng_reader_set_strip_16, 0); #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) rb_define_method(cReader, "set_strip_alpha", libpng_reader_set_strip_alpha, 0); #endif #if defined(PNG_READ_SWAP_SUPPORTED) rb_define_method(cReader, "set_swap", libpng_reader_set_swap, 0); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) rb_define_method(cReader, "set_swap_alpha", libpng_reader_set_swap_alpha, 0); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) rb_define_method(cReader, "set_tRNS_to_alpha", libpng_reader_set_tRNS_to_alpha, 0); #endif }