diff options
| author | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-07-29 15:25:37 +0000 | 
|---|---|---|
| committer | Fumitoshi UKAI <ukai@debian.or.jp> | 2002-07-29 15:25:37 +0000 | 
| commit | 3e1846025a4c064570c985a286e0effa73f95ed9 (patch) | |
| tree | a0cd627db33f7daa74b011c0f51d53f2b0d5a9b5 /w3mimg/fb | |
| parent | [w3m-dev 03280] w3m-img without w3mimgsize (diff) | |
| download | w3m-3e1846025a4c064570c985a286e0effa73f95ed9.tar.gz w3m-3e1846025a4c064570c985a286e0effa73f95ed9.zip | |
[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 <hito@crl.go.jp>
Diffstat (limited to 'w3mimg/fb')
| -rw-r--r-- | w3mimg/fb/fb.c | 118 | ||||
| -rw-r--r-- | w3mimg/fb/fb.h | 36 | ||||
| -rw-r--r-- | w3mimg/fb/fb_gdkpixbuf.c | 159 | ||||
| -rw-r--r-- | w3mimg/fb/fb_img.h | 4 | ||||
| -rw-r--r-- | w3mimg/fb/fb_imlib2.c | 21 | ||||
| -rw-r--r-- | w3mimg/fb/fb_w3mimg.c | 31 | 
6 files changed, 262 insertions, 107 deletions
| 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; @@ -253,6 +284,77 @@ fb_image_rotete(FB_IMAGE * image, int direction)  }  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)  {      unsigned long work; 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 <linux/fb.h> -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 <stdio.h>  #include <stdlib.h>  #include <ctype.h> @@ -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; | 
