… | |
… | |
4 | |
4 | |
5 | #include <gdk-pixbuf/gdk-pixbuf.h> |
5 | #include <gdk-pixbuf/gdk-pixbuf.h> |
6 | |
6 | |
7 | #include <gperl.h> |
7 | #include <gperl.h> |
8 | #include <gtk2perl.h> |
8 | #include <gtk2perl.h> |
|
|
9 | |
|
|
10 | #define IW 80 |
|
|
11 | |
|
|
12 | #define RAND (seed = (seed + 7141) * 54773 % 134456) |
9 | |
13 | |
10 | static guint32 a85_val; |
14 | static guint32 a85_val; |
11 | static guint a85_cnt; |
15 | static guint a85_cnt; |
12 | static guchar a85_buf[80], *a85_ptr; |
16 | static guchar a85_buf[80], *a85_ptr; |
13 | |
17 | |
… | |
… | |
149 | int x, y; |
153 | int x, y; |
150 | guchar *dst; |
154 | guchar *dst; |
151 | int bpp = gdk_pixbuf_get_has_alpha (pb) ? 4 : 3; |
155 | int bpp = gdk_pixbuf_get_has_alpha (pb) ? 4 : 3; |
152 | guchar *src = gdk_pixbuf_get_pixels (pb); |
156 | guchar *src = gdk_pixbuf_get_pixels (pb); |
153 | int sstr = gdk_pixbuf_get_rowstride (pb); |
157 | int sstr = gdk_pixbuf_get_rowstride (pb); |
|
|
158 | int Er[IW], Eg[IW], Eb[IW]; |
|
|
159 | int seed = 77; |
154 | |
160 | |
155 | RETVAL = newSV (w * h); |
161 | RETVAL = newSV (w * h); |
156 | SvPOK_only (RETVAL); |
162 | SvPOK_only (RETVAL); |
157 | SvCUR_set (RETVAL, w * h); |
163 | SvCUR_set (RETVAL, w * h); |
158 | |
164 | |
159 | dst = SvPVX (RETVAL); |
165 | dst = SvPVX (RETVAL); |
160 | |
166 | |
|
|
167 | memset (Er, 0, sizeof (int) * IW); |
|
|
168 | memset (Eg, 0, sizeof (int) * IW); |
|
|
169 | memset (Eb, 0, sizeof (int) * IW); |
|
|
170 | |
|
|
171 | /* some primitive error distribution + random dithering */ |
|
|
172 | |
161 | for (y = 0; y < h; y++) |
173 | for (y = 0; y < h; y++) |
162 | { |
174 | { |
163 | /* use a very primitive form of error distribution. */ |
|
|
164 | int er = 0, eg = 0, eb = 0; |
175 | int er = 0, eg = 0, eb = 0; |
165 | |
176 | |
166 | for (x = 0; x < w; x++) |
177 | for (x = 0; x < w; x++) |
167 | { |
178 | { |
168 | int r, g, b; |
179 | int r, g, b; |
169 | guchar *p = src + x * bpp + y * sstr; |
180 | guchar *p = src + x * bpp + y * sstr; |
170 | |
181 | |
171 | r = ((p[0] + er) * 7 + 128) / 255; |
182 | r = ((p[0] + er + Er[x]) * 7 + 128) / 255; |
172 | g = ((p[1] + eg) * 7 + 128) / 255; |
183 | g = ((p[1] + eg + Eg[x]) * 7 + 128) / 255; |
173 | b = ((p[2] + eb) * 3 + 128) / 255; |
184 | b = ((p[2] + eb + Eb[x]) * 3 + 128) / 255; |
174 | |
185 | |
175 | r = r > 7 ? 7 : r < 0 ? 0 : r; |
186 | r = r > 7 ? 7 : r < 0 ? 0 : r; |
176 | g = g > 7 ? 7 : g < 0 ? 0 : g; |
187 | g = g > 7 ? 7 : g < 0 ? 0 : g; |
177 | b = b > 3 ? 3 : b < 0 ? 0 : b; |
188 | b = b > 3 ? 3 : b < 0 ? 0 : b; |
178 | |
189 | |
179 | er += p[0] - (r * 255 + 4) / 7; |
190 | er += p[0] - (r * 255 + 4) / 7; |
180 | eg += p[1] - (g * 255 + 4) / 7; |
191 | eg += p[1] - (g * 255 + 4) / 7; |
181 | eb += p[2] - (b * 255 + 2) / 3; |
192 | eb += p[2] - (b * 255 + 2) / 3; |
|
|
193 | |
|
|
194 | Er[x] = er / 2; er -= er / 2 + RAND % 7 - 3; |
|
|
195 | Eg[x] = eg / 2; eg -= eg / 2 + RAND % 7 - 3; |
|
|
196 | Eb[x] = eb / 2; eb -= eb / 2 + RAND % 7 - 3; |
182 | |
197 | |
183 | *dst++ = r << 5 | g << 2 | b; |
198 | *dst++ = r << 5 | g << 2 | b; |
184 | } |
199 | } |
185 | } |
200 | } |
186 | } |
201 | } |