static int image_gif_read_buf(GifFileType *gif, GifByteType *data, int len) { image *im = (image *)gif->UserData; //DEBUG_TRACE("GIF read_buf wants %d bytes, %d in buffer\n", len, buffer_len(im->buf)); if (im->fh != NULL) { if ( !_check_buf(im->fh, im->buf, len, MAX(len, BUFFER_SIZE)) ) { warn("Image::Scale not enough GIF data (%s)\n", SvPVX(im->path)); return 0; } } else { if (len > buffer_len(im->buf)) { // read from SV into buffer int sv_readlen = len - buffer_len(im->buf); if (sv_readlen > sv_len(im->sv_data) - im->sv_offset) { warn("Image::Scale not enough GIF data (%s)\n", SvPVX(im->path)); return 0; } DEBUG_TRACE(" Reading %d bytes of SV data @ %d\n", sv_readlen, im->sv_offset); buffer_append(im->buf, SvPVX(im->sv_data) + im->sv_offset, sv_readlen); im->sv_offset += sv_readlen; } } memcpy(data, buffer_ptr(im->buf), len); buffer_consume(im->buf, len); return len; }
int image_init(HV *self, image *im) { unsigned char *bptr; char *file = NULL; int ret = 1; if (my_hv_exists(self, "file")) { // Input from file SV *path = *(my_hv_fetch(self, "file")); file = SvPVX(path); im->fh = IoIFP(sv_2io(*(my_hv_fetch(self, "_fh")))); im->path = newSVsv(path); } else { // Input from scalar ref im->fh = NULL; im->path = newSVpv("(data)", 0); im->sv_data = *(my_hv_fetch(self, "data")); if (SvROK(im->sv_data)) im->sv_data = SvRV(im->sv_data); else croak("data is not a scalar ref\n"); } im->pixbuf = NULL; im->outbuf = NULL; im->outbuf_size = 0; im->type = UNKNOWN; im->sv_offset = 0; im->image_offset = 0; im->image_length = 0; im->width = 0; im->height = 0; im->width_padding = 0; im->width_inner = 0; im->height_padding = 0; im->height_inner = 0; im->flipped = 0; im->bpp = 0; im->channels = 0; im->has_alpha = 0; im->orientation = ORIENTATION_NORMAL; im->orientation_orig = ORIENTATION_NORMAL; im->memory_limit = 0; im->target_width = 0; im->target_height = 0; im->keep_aspect = 0; im->resize_type = IMAGE_SCALE_TYPE_GD_FIXED; im->filter = 0; im->bgcolor = 0; im->used = 0; im->palette = NULL; #ifdef HAVE_JPEG im->cinfo = NULL; #endif #ifdef HAVE_PNG im->png_ptr = NULL; im->info_ptr = NULL; #endif #ifdef HAVE_GIF im->gif = NULL; #endif // Read new() options if (my_hv_exists(self, "offset")) { im->image_offset = SvIV(*(my_hv_fetch(self, "offset"))); if (im->fh != NULL) PerlIO_seek(im->fh, im->image_offset, SEEK_SET); } if (my_hv_exists(self, "length")) im->image_length = SvIV(*(my_hv_fetch(self, "length"))); Newz(0, im->buf, sizeof(Buffer), Buffer); buffer_init(im->buf, BUFFER_SIZE); im->memory_used = BUFFER_SIZE; // Determine type of file from magic bytes if (im->fh != NULL) { if ( !_check_buf(im->fh, im->buf, 8, BUFFER_SIZE) ) { image_finish(im); croak("Unable to read image header for %s\n", file); } } else { im->sv_offset = MIN(sv_len(im->sv_data) - im->image_offset, BUFFER_SIZE); buffer_append(im->buf, SvPVX(im->sv_data) + im->image_offset, im->sv_offset); } bptr = buffer_ptr(im->buf); switch (bptr[0]) { case 0xff: if (bptr[1] == 0xd8 && bptr[2] == 0xff) { #ifdef HAVE_JPEG im->type = JPEG; #else image_finish(im); croak("Image::Scale was not built with JPEG support\n"); #endif } break; case 0x89: if (bptr[1] == 'P' && bptr[2] == 'N' && bptr[3] == 'G' && bptr[4] == 0x0d && bptr[5] == 0x0a && bptr[6] == 0x1a && bptr[7] == 0x0a) { #ifdef HAVE_PNG im->type = PNG; #else image_finish(im); croak("Image::Scale was not built with PNG support\n"); #endif } break; case 'G': if (bptr[1] == 'I' && bptr[2] == 'F' && bptr[3] == '8' && (bptr[4] == '7' || bptr[4] == '9') && bptr[5] == 'a') { #ifdef HAVE_GIF im->type = GIF; #else image_finish(im); croak("Image::Scale was not built with GIF support\n"); #endif } break; case 'B': if (bptr[1] == 'M') { im->type = BMP; } break; } DEBUG_TRACE("Image type: %d\n", im->type); // Read image header via type-specific function to determine dimensions switch (im->type) { #ifdef HAVE_JPEG case JPEG: if ( !image_jpeg_read_header(im) ) { ret = 0; goto out; } break; #endif #ifdef HAVE_PNG case PNG: if ( !image_png_read_header(im) ) { ret = 0; goto out; } break; #endif #ifdef HAVE_GIF case GIF: if ( !image_gif_read_header(im) ) { ret = 0; goto out; } break; #endif case BMP: image_bmp_read_header(im); break; case UNKNOWN: warn("Image::Scale unknown file type (%s), first 8 bytes were: %02x %02x %02x %02x %02x %02x %02x %02x\n", SvPVX(im->path), bptr[0], bptr[1], bptr[2], bptr[3], bptr[4], bptr[5], bptr[6], bptr[7]); ret = 0; break; } DEBUG_TRACE("Image dimenensions: %d x %d, channels %d\n", im->width, im->height, im->channels); out: if (ret == 0) image_finish(im); return ret; }