From 3e1846025a4c064570c985a286e0effa73f95ed9 Mon Sep 17 00:00:00 2001 From: Fumitoshi UKAI Date: Mon, 29 Jul 2002 15:25:37 +0000 Subject: [w3m-dev 03282] Re: w3m-img for framebuffer update * w3mimg/fb/fb.c (fb_image_new): ignore no image calloc multiple images (fb_image_fill): added (fb_image_draw): width, height fix (fb_image_rotate): fix typo (fb_image_copy): added (fb_frame_new): added (fb_freme_free): added (fb_frame_rotate): added * w3mimg/fb/fb.h (FB_IMAGE): add num, id, delay (fb_frame_new): added (fb_frame_free): added (fb_frame_rotate): added * w3mimg/fb/fb_gdkpixbuf.c (get_image_size): animation support (fb_image_load): animation support (draw): add bg, x, y, w, h args * w3mimg/fb/fb_img.h (fb_image_load): return FB_IMAGE** * w3mimg/fb/fb_imlib2.c (fb_image_load): return FB_IMAGE** * w3mimg/fb/fb_w3mimg.c (w3mfb_show_image): animation support From: Hiroyuki Ito --- w3mimg/fb/fb.c | 118 ++++++++++++++++++++++++++++++++--- w3mimg/fb/fb.h | 36 +++++++---- w3mimg/fb/fb_gdkpixbuf.c | 159 +++++++++++++++++++++++++++-------------------- w3mimg/fb/fb_img.h | 4 +- w3mimg/fb/fb_imlib2.c | 21 ++++--- w3mimg/fb/fb_w3mimg.c | 31 ++++++--- 6 files changed, 262 insertions(+), 107 deletions(-) (limited to 'w3mimg') diff --git a/w3mimg/fb/fb.c b/w3mimg/fb/fb.c index 526441a..dca5832 100644 --- a/w3mimg/fb/fb.c +++ b/w3mimg/fb/fb.c @@ -1,4 +1,4 @@ -/* $Id: fb.c,v 1.4 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb.c,v 1.5 2002/07/29 15:25:37 ukai Exp $ */ /************************************************************************** fb.c 0.3 Copyright (C) 2002, hito **************************************************************************/ @@ -118,6 +118,8 @@ fb_close(void) is_open = FALSE; } +/*********** fb_image_* ***********/ + FB_IMAGE * fb_image_new(int width, int height) { @@ -126,19 +128,24 @@ fb_image_new(int width, int height) if (is_open != TRUE) return NULL; - if (width > IMAGE_SIZE_MAX || height > IMAGE_SIZE_MAX) + if (width > IMAGE_SIZE_MAX || height > IMAGE_SIZE_MAX || width < 1 + || height < 1) return NULL; image = malloc(sizeof(*image)); if (image == NULL) return NULL; - image->data = malloc(width * height * pixel_size); + image->data = calloc(sizeof(*(image->data)), width * height * pixel_size); if (image->data == NULL) { free(image); return NULL; } + image->num = 1; + image->id = 0; + image->delay = 0; + image->width = width; image->height = height; image->rowstride = width * pixel_size; @@ -171,15 +178,33 @@ fb_image_pset(FB_IMAGE * image, int x, int y, int r, int g, int b) offset = image->rowstride * y + pixel_size * x; - work = ((r >> (CHAR_BIT - vscinfo.red.length)) << vscinfo.red. - offset) + - ((g >> (CHAR_BIT - vscinfo.green.length)) << vscinfo.green. - offset) + + work = + ((r >> (CHAR_BIT - vscinfo.red.length)) << vscinfo.red.offset) + + ((g >> (CHAR_BIT - vscinfo.green.length)) << vscinfo.green.offset) + ((b >> (CHAR_BIT - vscinfo.blue.length)) << vscinfo.blue.offset); memcpy(image->data + offset, &work, pixel_size); } +void +fb_image_fill(FB_IMAGE * image, int r, int g, int b) +{ + unsigned long work; + int offset; + + if (image == NULL || is_open != TRUE) + return; + + work = + ((r >> (CHAR_BIT - vscinfo.red.length)) << vscinfo.red.offset) + + ((g >> (CHAR_BIT - vscinfo.green.length)) << vscinfo.green.offset) + + ((b >> (CHAR_BIT - vscinfo.blue.length)) << vscinfo.blue.offset); + + for (offset = 0; offset < image->len; offset += pixel_size) { + memcpy(image->data + offset, &work, pixel_size); + } +} + int fb_image_draw(FB_IMAGE * image, int x, int y, int sx, int sy, int width, int height) @@ -191,6 +216,12 @@ fb_image_draw(FB_IMAGE * image, int x, int y, int sx, int sy, int width, x > fb_width() || y > fb_height()) return 1; + if (sx + width > image->width) + width = image->width - sx; + + if (sy + height > image->height) + height = image->height - sy; + if (x + width > fb_width()) width = fb_width() - x; @@ -209,7 +240,7 @@ fb_image_draw(FB_IMAGE * image, int x, int y, int sx, int sy, int width, } void -fb_image_rotete(FB_IMAGE * image, int direction) +fb_image_rotate(FB_IMAGE * image, int direction) { unsigned char *src, *dest, *tmp; int x, y, i, ofst; @@ -252,6 +283,77 @@ fb_image_rotete(FB_IMAGE * image, int direction) free(tmp); } +void +fb_image_copy(FB_IMAGE * dest, FB_IMAGE * src) +{ + if (dest == NULL || src == NULL) + return; + + if (dest->len != src->len) + return; + + memcpy(dest->data, src->data, src->len); +} + +/*********** fb_frame_* ***********/ + +FB_IMAGE ** +fb_frame_new(int w, int h, int n) +{ + FB_IMAGE **frame; + int i, error = 0; + + if (w > IMAGE_SIZE_MAX || h > IMAGE_SIZE_MAX || w < 1 || h < 1 || n < 1) + return NULL; + + frame = malloc(sizeof(*frame) * n); + if (frame == NULL) + return NULL; + + for (i = 0; i < n; i++) { + frame[i] = fb_image_new(w, h); + frame[i]->num = n; + frame[i]->id = i; + frame[i]->delay = 1000; + if (frame[i] == NULL) + error = 1; + } + + if (error) { + fb_frame_free(frame); + return NULL; + } + + return frame; +} + + +void +fb_frame_free(FB_IMAGE ** frame) +{ + int i, n; + + if (frame == NULL) + return; + + n = frame[0]->num; + for (i = 0; i < n; i++) { + fb_image_free(frame[i]); + } + free(frame); +} + +void +fb_frame_rotate(FB_IMAGE ** frame, int direction) +{ + int i, n; + + n = frame[0]->num; + for (i = 0; i < n; i++) { + fb_image_rotate(frame[i], direction); + } +} + void fb_pset(int x, int y, int r, int g, int b) { diff --git a/w3mimg/fb/fb.h b/w3mimg/fb/fb.h index 391720c..77dcd20 100644 --- a/w3mimg/fb/fb.h +++ b/w3mimg/fb/fb.h @@ -1,26 +1,36 @@ -/* $Id: fb.h,v 1.4 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb.h,v 1.5 2002/07/29 15:25:37 ukai Exp $ */ #ifndef fb_header #define fb_header #include -typedef struct{ - unsigned char *data; - int width; - int height; - int rowstride; - int len; +typedef struct { + int num; + int id; + int delay; + int width; + int height; + int rowstride; + int len; + unsigned char *data; } FB_IMAGE; FB_IMAGE *fb_image_new(int width, int height); -void fb_image_pset(FB_IMAGE *image, int x, int y, int r, int g, int b); -int fb_image_draw(FB_IMAGE *image, int x, int y, int sx, int sy, int width, int height); -void fb_image_free(FB_IMAGE *image); -void fb_image_rotete(FB_IMAGE *image, int direction); +void fb_image_pset(FB_IMAGE * image, int x, int y, int r, int g, int b); +void fb_image_fill(FB_IMAGE * image, int r, int g, int b); +int fb_image_draw(FB_IMAGE * image, int x, int y, int sx, int sy, int width, + int height); +void fb_image_free(FB_IMAGE * image); +void fb_image_rotate(FB_IMAGE * image, int direction); +void fb_image_copy(FB_IMAGE * dest, FB_IMAGE * src); -int fb_open(void); +FB_IMAGE **fb_frame_new(int w, int h, int num); +void fb_frame_free(FB_IMAGE ** frame); +void fb_frame_rotate(FB_IMAGE ** frame, int direction); + +int fb_open(void); void fb_close(void); void fb_pset(int x, int y, int r, int g, int b); -int fb_get_color(int x, int y, int *r, int *g, int *b); +int fb_get_color(int x, int y, int *r, int *g, int *b); void fb_clear(void); int fb_width(void); int fb_height(void); diff --git a/w3mimg/fb/fb_gdkpixbuf.c b/w3mimg/fb/fb_gdkpixbuf.c index 003096a..99c8971 100644 --- a/w3mimg/fb/fb_gdkpixbuf.c +++ b/w3mimg/fb/fb_gdkpixbuf.c @@ -1,4 +1,4 @@ -/* $Id: fb_gdkpixbuf.c,v 1.6 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb_gdkpixbuf.c,v 1.7 2002/07/29 15:25:37 ukai Exp $ */ /************************************************************************** fb_gdkpixbuf.c 0.3 Copyright (C) 2002, hito **************************************************************************/ @@ -7,117 +7,144 @@ #include "fb.h" #include "fb_img.h" -static void draw(FB_IMAGE * img, GdkPixbuf * pixbuf); +static void draw(FB_IMAGE * img, int bg, int x, int y, int w, int h, + GdkPixbuf * pixbuf); static GdkPixbuf *resize_image(GdkPixbuf * pixbuf, int width, int height); int -get_image_size(char *filename, int *w, int *h) +get_image_size(char *filename, int *w, int *h) { - GdkPixbuf *pixbuf; - + GdkPixbufAnimation * animation; if (filename == NULL) return 1; - - pixbuf = gdk_pixbuf_new_from_file(filename); - if (pixbuf == NULL) + animation = gdk_pixbuf_animation_new_from_file(filename); + if (animation == NULL) return 1; - - *w = gdk_pixbuf_get_width(pixbuf); - *h = gdk_pixbuf_get_height(pixbuf); - - gdk_pixbuf_finalize(pixbuf); + *w = gdk_pixbuf_animation_get_width(animation); + *h = gdk_pixbuf_animation_get_height(animation); + gdk_pixbuf_animation_unref(animation); return 0; } -FB_IMAGE * -fb_image_load(char *filename, int w, int h) +FB_IMAGE ** fb_image_load(char *filename, int w, int h) { - GdkPixbuf *pixbuf; - FB_IMAGE *img; - + GdkPixbufAnimation * animation; + GList * frames; + double ratio_w, ratio_h; + int n, i, fw, fh; + FB_IMAGE ** fb_frame; + GdkPixbufFrameAction action = GDK_PIXBUF_FRAME_REVERT; if (filename == NULL) return NULL; - - pixbuf = gdk_pixbuf_new_from_file(filename); - if (pixbuf == NULL) - return NULL; - - pixbuf = resize_image(pixbuf, w, h); - if (pixbuf == NULL) - return NULL; - - w = gdk_pixbuf_get_width(pixbuf); - h = gdk_pixbuf_get_height(pixbuf); - - img = fb_image_new(w, h); - - if (img == NULL) { - gdk_pixbuf_finalize(pixbuf); + animation = gdk_pixbuf_animation_new_from_file(filename); + if (animation == NULL) return NULL; + frames = gdk_pixbuf_animation_get_frames(animation); + fw = gdk_pixbuf_animation_get_width(animation); + fh = gdk_pixbuf_animation_get_height(animation); + n = gdk_pixbuf_animation_get_num_frames(animation); + if (w < 1 || h < 1) { + w = fw; + h = fh; + ratio_w = ratio_h = 1; + } else { + ratio_w = 1.0 * w / fw; + ratio_h = 1.0 * h / fh; } - - draw(img, pixbuf); - - gdk_pixbuf_finalize(pixbuf); - - return img; + fb_frame = fb_frame_new(w, h, n); + if (fb_frame == NULL) + goto END; + for (i = 0; i < n; i++) { + GdkPixbufFrame * frame; + GdkPixbuf * org_pixbuf, *pixbuf; + int width, height, ofstx, ofsty; + frame = (GdkPixbufFrame *) g_list_nth_data(frames, i); + org_pixbuf = gdk_pixbuf_frame_get_pixbuf(frame); + ofstx = gdk_pixbuf_frame_get_x_offset(frame); + ofsty = gdk_pixbuf_frame_get_y_offset(frame); + width = gdk_pixbuf_get_width(org_pixbuf); + height = gdk_pixbuf_get_height(org_pixbuf); + if (ofstx == 0 && ofsty == 0 && width == fw && height == fh) { + pixbuf = resize_image(org_pixbuf, w, h); + } else { + pixbuf = + resize_image(org_pixbuf, width * ratio_w, height * ratio_h); + ofstx *= ratio_w; + ofsty *= ratio_h; + } + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + fb_frame[i]->delay = gdk_pixbuf_frame_get_delay_time(frame); + if (i > 0) { + switch (action) { + case GDK_PIXBUF_FRAME_RETAIN: + fb_image_copy(fb_frame[i], fb_frame[i - 1]); + break; + case GDK_PIXBUF_FRAME_DISPOSE: + if(bg_r != 0 || bg_g != 0 || bg_b != 0){ + fb_image_fill(fb_frame[i], bg_r, bg_g, bg_b); + } + break; + case GDK_PIXBUF_FRAME_REVERT: + fb_image_copy(fb_frame[i], fb_frame[0]); + break; + default: + fb_image_copy(fb_frame[i], fb_frame[0]); + } + } + action = gdk_pixbuf_frame_get_action(frame); + draw(fb_frame[i], !i, ofstx, ofsty, width, height, pixbuf); + if (org_pixbuf != pixbuf) + gdk_pixbuf_finalize(pixbuf); + } + END: + gdk_pixbuf_animation_unref(animation); + return fb_frame; } - -void -draw(FB_IMAGE * img, GdkPixbuf * pixbuf) +static void +draw(FB_IMAGE * img, int bg, int x, int y, int w, int h, GdkPixbuf * pixbuf) { int i, j, r, g, b, offset, bpp, rowstride; - guchar *pixels; + guchar * pixels; gboolean alpha; - if (img == NULL || pixbuf == NULL) return; - rowstride = gdk_pixbuf_get_rowstride(pixbuf); pixels = gdk_pixbuf_get_pixels(pixbuf); alpha = gdk_pixbuf_get_has_alpha(pixbuf); - - bpp = rowstride / img->width; - for (j = 0; j < img->height; j++) { + bpp = rowstride / w; + for (j = 0; j < h; j++) { offset = j * rowstride; - for (i = 0; i < img->width; i++, offset += bpp) { + for (i = 0; i < w; i++, offset += bpp) { r = pixels[offset]; g = pixels[offset + 1]; b = pixels[offset + 2]; - if (alpha && pixels[offset + 3] == 0) - fb_image_pset(img, i, j, bg_r, bg_g, bg_b); - else - fb_image_pset(img, i, j, r, g, b); + if (alpha && pixels[offset + 3] == 0) { + if (bg) + fb_image_pset(img, i + x, j + y, bg_r, bg_g, bg_b); + } else { + fb_image_pset(img, i + x, j + y, r, g, b); + } } } return; } - static GdkPixbuf * -resize_image(GdkPixbuf * pixbuf, int width, int height) +resize_image(GdkPixbuf * pixbuf, int width, int height) { GdkPixbuf * resized_pixbuf; int w, h; - if (pixbuf == NULL) return NULL; - w = gdk_pixbuf_get_width(pixbuf); h = gdk_pixbuf_get_height(pixbuf); - if (width < 1 || height < 1) return pixbuf; - if (w == width && h == height) return pixbuf; - - resized_pixbuf = + resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_HYPER); - - gdk_pixbuf_finalize(pixbuf); - if (resized_pixbuf == NULL) return NULL; - return resized_pixbuf; } diff --git a/w3mimg/fb/fb_img.h b/w3mimg/fb/fb_img.h index 80dcb20..772334b 100644 --- a/w3mimg/fb/fb_img.h +++ b/w3mimg/fb/fb_img.h @@ -1,9 +1,9 @@ -/* $Id: fb_img.h,v 1.4 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb_img.h,v 1.5 2002/07/29 15:25:37 ukai Exp $ */ #ifndef fb_img_header #define fb_img_header #include "fb.h" -FB_IMAGE *fb_image_load(char *filename, int w, int h); +FB_IMAGE **fb_image_load(char *filename, int w, int h); int fb_image_draw_simple(FB_IMAGE * img, int x, int y); void fb_image_set_bg(int r, int g, int b); int get_image_size(char *filename, int *w, int *h); diff --git a/w3mimg/fb/fb_imlib2.c b/w3mimg/fb/fb_imlib2.c index 44633a3..a8371ff 100644 --- a/w3mimg/fb/fb_imlib2.c +++ b/w3mimg/fb/fb_imlib2.c @@ -1,4 +1,4 @@ -/* $Id: fb_imlib2.c,v 1.6 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb_imlib2.c,v 1.7 2002/07/29 15:25:37 ukai Exp $ */ /************************************************************************** fb_imlib2.c 0.3 Copyright (C) 2002, hito **************************************************************************/ @@ -31,11 +31,11 @@ get_image_size(char *filename, int *w, int *h) return 0; } -FB_IMAGE * +FB_IMAGE ** fb_image_load(char *filename, int w, int h) { Imlib_Image image; - FB_IMAGE *img; + FB_IMAGE **frame; if (filename == NULL) return NULL; @@ -53,18 +53,18 @@ fb_image_load(char *filename, int w, int h) w = imlib_image_get_width(); h = imlib_image_get_height(); - img = fb_image_new(w, h); + frame = fb_frame_new(w, h, 1); - if (img == NULL) { + if (frame == NULL) { imlib_free_image(); return NULL; } - draw(img, image); + draw(frame[0], image); imlib_free_image(); - return img; + return frame; } static void @@ -87,10 +87,11 @@ draw(FB_IMAGE * img, Imlib_Image image) g = (data[offset + i] >> 8) & 0x000000ff; b = (data[offset + i]) & 0x000000ff; - if (a == 0) + if (a == 0) { fb_image_pset(img, i, j, bg_r, bg_g, bg_b); - else + } else { fb_image_pset(img, i, j, r, g, b); + } } } return; @@ -115,7 +116,7 @@ resize_image(Imlib_Image image, int width, int height) if (w == width && h == height) return image; - resized_image = + resized_image = imlib_create_cropped_scaled_image(0, 0, w, h, width, height); imlib_free_image(); diff --git a/w3mimg/fb/fb_w3mimg.c b/w3mimg/fb/fb_w3mimg.c index 71cc001..6810888 100644 --- a/w3mimg/fb/fb_w3mimg.c +++ b/w3mimg/fb/fb_w3mimg.c @@ -1,4 +1,4 @@ -/* $Id: fb_w3mimg.c,v 1.2 2002/07/22 16:17:32 ukai Exp $ */ +/* $Id: fb_w3mimg.c,v 1.3 2002/07/29 15:25:37 ukai Exp $ */ #include #include #include @@ -58,7 +58,7 @@ w3mfb_close(w3mimg_op *self) static int w3mfb_load_image(w3mimg_op *self, W3MImage *img, char *fname, int w, int h) { - FB_IMAGE *im; + FB_IMAGE **im; if (self == NULL) return 0; @@ -66,8 +66,8 @@ w3mfb_load_image(w3mimg_op *self, W3MImage *img, char *fname, int w, int h) if (!im) return 0; img->pixmap = im; - img->width = im->width; - img->height = im->height; + img->width = im[0]->width; + img->height = im[0]->height; return 1; } @@ -76,14 +76,29 @@ w3mfb_show_image(w3mimg_op *self, W3MImage *img, int sx, int sy, int sw, int sh, int x, int y) { + int i; + FB_IMAGE **frame; +#define WAIT_CNT 4 + if (self == NULL) return 0; - fb_image_draw((FB_IMAGE *)img->pixmap, + frame = (FB_IMAGE **)img->pixmap; + i = frame[0]->id; + fb_image_draw(frame[i], x + self->offset_x, y + self->offset_y, sx, sy, - (sw ? sw : img->width), - (sh ? sh : img->height)); + (sw ? sw : img->width), (sh ? sh : img->height)); + if(frame[0]->num > 1){ + if(frame[1]->id > WAIT_CNT){ + frame[1]->id = 0; + if(i < frame[0]->num - 1) + frame[0]->id = i + 1; + else + frame[0]->id = 0; + } + frame[1]->id += 1; + } return 1; } @@ -93,7 +108,7 @@ w3mfb_free_image(w3mimg_op *self, W3MImage *img) if (self == NULL) return; if (img && img->pixmap) { - fb_image_free((FB_IMAGE *)img->pixmap); + fb_frame_free((FB_IMAGE **)img->pixmap); img->pixmap = NULL; img->width = 0; img->height = 0; -- cgit v1.2.3