annotate src/img_ldr_imlib2.c @ 1517:31a21656c0a8

Describe designs of Scribboo
author Thinker K.F. Li <thinker@codemud.net>
date Sat, 14 May 2011 01:07:23 +0800
parents 1c64a9cec2f2
children
rev   line source
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*-
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
2 // vim: sw=4:ts=8:sts=4
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
3 #include <stdio.h>
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
4 #include <stdint.h>
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
5 #include <string.h>
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
6 #include <Imlib2.h>
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
7 #include "mb_graph_engine.h"
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
8 #include "mb_tools.h"
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
9 #include "mb_paint.h"
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
10 #include "mb_img_ldr.h"
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
11
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
12 /*! \brief Simple image loader.
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
13 *
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
14 */
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
15 struct _simple_mb_img_ldr {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
16 mb_img_ldr_t ldr;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
17 const char *repo; /*!< \brief The directory of repository. */
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
18 };
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
19 typedef struct _simple_mb_img_ldr simple_mb_img_ldr_t;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
20
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
21 struct _simple_mb_img_data {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
22 mb_img_data_t img;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
23 };
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
24 typedef struct _simple_mb_img_data simple_mb_img_data_t;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
25
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
26 static void simple_mb_img_ldr_img_free(mb_img_data_t *img);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28 static
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
29 mb_img_data_t *simple_mb_img_ldr_load(mb_img_ldr_t *ldr, const char *img_id) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
30 simple_mb_img_ldr_t *sldr = (simple_mb_img_ldr_t *)ldr;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
31 simple_mb_img_data_t *img;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
32 Imlib_Image img_hdl;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
33 int w, h;
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
34 int i, j, pos;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
35 uint32_t alpha;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
36 uint32_t value;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
37 uint32_t *data;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
38 uint32_t *premultiple_data;
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
39 char *fname;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
40 int sz;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
41
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
42 sz = strlen(sldr->repo);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
43 sz += strlen(img_id);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
44 fname = (char *)malloc(sz + 2);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
45 if (img_id[0] != '/')
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
46 strcpy(fname, sldr->repo);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
47 else
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
48 fname[0] = 0;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
49 strcat(fname, img_id);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
50
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
51 img_hdl = imlib_load_image(fname);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
52 if(!img_hdl)
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
53 return NULL;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
54 imlib_context_set_image(img_hdl);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
55 w = imlib_image_get_width();
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
56 h = imlib_image_get_height();
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
57 data = (uint32_t *)imlib_image_get_data_for_reading_only();
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
58
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
59 img = O_ALLOC(simple_mb_img_data_t);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
60 if(img == NULL) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
61 imlib_free_image();
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
62 return NULL;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
63 }
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
64
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
65 premultiple_data = (uint32_t *)malloc(4 * w * h);
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
66 if(premultiple_data == NULL) {
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
67 free(img);
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
68 imlib_free_image();
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
69 return NULL;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
70 }
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
71 memcpy(premultiple_data, data, 4 * w * h);
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
72
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
73 /* Pre-multiply
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
74 *
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
75 * Our reference model is Cairo. In Cairo model, image is
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
76 * pre-multiplied with alpha, but imlib2 is not. So, we do it
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
77 * here.
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
78 */
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
79 pos = 0;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
80 for(i = 0; i < h; i++) {
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
81 for(j = 0; j < w; j++) {
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
82 value = data[pos];
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
83 alpha = value >> 24;
1107
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
84 if(alpha != 0xff) {
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
85 if(alpha == 0)
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
86 value = 0;
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
87 else {
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
88 value = (value & 0xff000000) |
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
89 (((value & 0xff0000) * alpha / 0xff) & 0xff0000) |
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
90 (((value & 0xff00) * alpha / 0xff) & 0xff00) |
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
91 ((value & 0xff) * alpha / 0xff);
1c64a9cec2f2 Improve performance of pre-multipling for imlib2 image loader
Thinker K.F. Li <thinker@codemud.net>
parents: 1106
diff changeset
92 }
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
93 }
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
94 premultiple_data[pos++] = value;
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
95 }
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
96 }
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
97
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
98 img->img.content = premultiple_data;
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
99 img->img.w = w;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
100 img->img.h = h;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
101 img->img.stride = w * 4;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
102 img->img.fmt = MB_IFMT_ARGB32;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
103 img->img.free = simple_mb_img_ldr_img_free;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
104
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
105 imlib_free_image();
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
106
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
107 return (mb_img_data_t *)img;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
108 }
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
109
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
110 static
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
111 void simple_mb_img_ldr_img_free(mb_img_data_t *img) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
112 simple_mb_img_data_t *simg = (simple_mb_img_data_t *)img;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
113
1106
b5145de15ace Fix issue of alpha channel not working.
Thinker K.F. Li <thinker@codemud.net>
parents: 1067
diff changeset
114 free(simg->img.content);
1067
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
115 free(img);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
116 }
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
117
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
118 static
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
119 void simple_mb_img_ldr_free(mb_img_ldr_t *ldr) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
120 simple_mb_img_ldr_t *defldr = (simple_mb_img_ldr_t *)ldr;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
121
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
122 free((void *)defldr->repo);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
123 }
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
124
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
125 mb_img_ldr_t *simple_mb_img_ldr_new(const char *img_repository) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
126 simple_mb_img_ldr_t *ldr;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
127 int sz;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
128
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
129 if(img_repository == NULL)
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
130 return NULL;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
131
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
132 ldr = O_ALLOC(simple_mb_img_ldr_t);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
133 if(ldr == NULL)
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
134 return NULL;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
135
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
136 /*
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
137 * Copy and formalize path of image repository.
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
138 */
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
139 sz = strlen(img_repository);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
140 ldr->repo = (const char *)malloc(sz + 2);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
141 if(ldr->repo == NULL) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
142 free(ldr);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
143 return NULL;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
144 }
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
145 strcpy((char *)ldr->repo, img_repository);
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
146 if(img_repository[sz - 1] != '/' && strlen(img_repository) != 0) {
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
147 ((char *)ldr->repo)[sz] = '/';
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
148 ((char *)ldr->repo)[sz + 1] = 0;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
149 }
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
150
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
151 ldr->ldr.load = simple_mb_img_ldr_load;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
152 ldr->ldr.free = simple_mb_img_ldr_free;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
153
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
154 return (mb_img_ldr_t *)ldr;
7b4e80ab671a merge from default branch
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
155 }