summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar jan.dudek2008-12-15 01:28:30 +0000
committerGravatar jan.dudek2008-12-15 01:28:30 +0000
commitbf27bdfa14d53b0239e34a232205757d4609dcc2 (patch)
tree5a34085a387cad29a55d64e4e7862d17160c8d5c
parent91b7713ed55ddba7c00ecd40e4ce137f90456326 (diff)
downloadgdk-pixbuf-psd-bf27bdfa14d53b0239e34a232205757d4609dcc2.tar.gz
gdk-pixbuf-psd-bf27bdfa14d53b0239e34a232205757d4609dcc2.tar.bz2
Minor fixes, removed non-incremental loading
git-svn-id: http://gdk-pixbuf-psd.googlecode.com/svn/trunk@7 c5539ac3-5556-0410-9a1f-7faf0b045682
-rw-r--r--io-psd.c301
1 files changed, 75 insertions, 226 deletions
diff --git a/io-psd.c b/io-psd.c
index 363b2ef..6470f71 100644
--- a/io-psd.c
+++ b/io-psd.c
@@ -26,6 +26,7 @@
26 * - report errors from parse_psd_header 26 * - report errors from parse_psd_header
27 * - other color modes 27 * - other color modes
28 * - ... 28 * - ...
29 * - MODULE_ENTRY stuff
29 */ 30 */
30 31
31#include <stdlib.h> 32#include <stdlib.h>
@@ -39,7 +40,7 @@ typedef struct
39{ 40{
40 guchar signature[4]; /* file ID, always "8BPS" */ 41 guchar signature[4]; /* file ID, always "8BPS" */
41 guint16 version; /* version number, always 1 */ 42 guint16 version; /* version number, always 1 */
42 guchar reserved[6]; 43 guchar resetved[6];
43 guint16 channels; /* number of color channels (1-24) */ 44 guint16 channels; /* number of color channels (1-24) */
44 guint32 rows; /* height of image in pixels (1-30000) */ 45 guint32 rows; /* height of image in pixels (1-30000) */
45 guint32 columns; /* width of image in pixels (1-30000) */ 46 guint32 columns; /* width of image in pixels (1-30000) */
@@ -95,7 +96,6 @@ typedef struct
95 guint32 bytes_to_skip; 96 guint32 bytes_to_skip;
96 gboolean bytes_to_skip_known; 97 gboolean bytes_to_skip_known;
97 98
98 //PsdHeader hd;
99 guint32 width; /* width of image in pixels (1-30000) */ 99 guint32 width; /* width of image in pixels (1-30000) */
100 guint32 height; /* height of image in pixels (1-30000) */ 100 guint32 height; /* height of image in pixels (1-30000) */
101 guint16 channels; /* number of color channels (1-24) */ 101 guint16 channels; /* number of color channels (1-24) */
@@ -103,79 +103,31 @@ typedef struct
103 PsdColorMode color_mode; 103 PsdColorMode color_mode;
104 PsdCompressionType compression; 104 PsdCompressionType compression;
105 105
106 guchar** channels_buffers; 106 guchar** ch_bufs; /* channels buffers */
107 guint current_channel; 107 guint curr_ch; /* current channel */
108 guint current_row; 108 guint curr_row;
109 guint position; // ? redundant? 109 guint pos; // redundant?
110 guint16* lines_lengths; 110 guint16* lines_lengths;
111 gboolean finalized; 111 gboolean finalized;
112} PsdContext; 112} PsdContext;
113 113
114static guint16
115read_uint16 (FILE *fp)
116{
117 guint16 t;
118 t = fgetc(fp) << 8;
119 t |= fgetc(fp);
120 return t;
121}
122
123static guint32
124read_uint32 (FILE *fp)
125{
126 guint32 t;
127 t = fgetc(fp) << 24;
128 t |= fgetc(fp) << 16;
129 t |= fgetc(fp) << 8;
130 t |= fgetc(fp);
131 return t;
132}
133 114
134static guint16 115static guint16
135parse_uint16 (guchar* buf) 116read_uint16 (guchar* buf)
136{ 117{
137 return (buf[0] << 8) | buf[1]; 118 return (buf[0] << 8) | buf[1];
138} 119}
139 120
140static guint32 121static guint32
141parse_uint32 (guchar* buf) 122read_uint32 (guchar* buf)
142{ 123{
143 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; 124 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
144} 125}
145 126
146 127
147static PsdHeader
148psd_read_header (FILE *fp)
149{
150 PsdHeader hd;
151 int t;
152
153 fread(hd.signature, 1, 4, fp);
154 hd.version = read_uint16(fp);
155 fread(hd.reserved, 1, 6, fp);
156 hd.channels = read_uint16(fp);
157 hd.rows = read_uint32(fp);
158 hd.columns = read_uint32(fp);
159 hd.depth = read_uint16(fp);
160 hd.color_mode = read_uint16(fp);
161
162 // skip Color Mode Data Block
163 t = read_uint32(fp);
164 fseek(fp, t, SEEK_CUR);
165
166 // skip Image Resources Block
167 t = read_uint32(fp);
168 fseek(fp, t, SEEK_CUR);
169
170 // skip Layer and Mask Information Block
171 t = read_uint32(fp);
172 fseek(fp, t, SEEK_CUR);
173
174 return hd;
175}
176
177/* 128/*
178 * Parse Psdheader from buffer 129 * Parse Psdheader from buffer
130 *
179 * str is expected to be at least PSD_HEADER_SIZE long 131 * str is expected to be at least PSD_HEADER_SIZE long
180 */ 132 */
181static PsdHeader 133static PsdHeader
@@ -184,130 +136,22 @@ psd_parse_header (guchar* str)
184 PsdHeader hd; 136 PsdHeader hd;
185 137
186 memcpy(hd.signature, str, 4); 138 memcpy(hd.signature, str, 4);
187 hd.version = parse_uint16(str + 4); 139 hd.version = read_uint16(str + 4);
188 hd.channels = parse_uint16(str + 12); 140 hd.channels = read_uint16(str + 12);
189 hd.rows = parse_uint32(str + 14); 141 hd.rows = read_uint32(str + 14);
190 hd.columns = parse_uint32(str + 18); 142 hd.columns = read_uint32(str + 18);
191 hd.depth = parse_uint16(str + 22); 143 hd.depth = read_uint16(str + 22);
192 hd.color_mode = parse_uint16(str + 24); 144 hd.color_mode = read_uint16(str + 24);
193 145
194 return hd; 146 return hd;
195} 147}
196 148
197// -- non-progressive loading -------------------------------------------------- 149/*
198 150 * Attempts to read bytes_needed bytes from data and stores them in buffer.
199static GdkPixbuf* 151 *
200gdk_pixbuf__psd_image_load (FILE *fp, 152 * Returns true if there were enough bytes and false otherwise
201 GError **error) 153 * (which means we need to call feed_buffer again)
202{ 154 */
203 guint rowstride;
204 guint16 compression_type;
205 guchar *pixels;
206 GdkPixbuf *pixbuf;
207 guchar **buffers;
208
209 PsdHeader hd = psd_read_header(fp);
210 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, hd.columns, hd.rows);
211
212 if (pixbuf == NULL) {
213 g_set_error (error, GDK_PIXBUF_ERROR,
214 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
215 ("Insufficient memory to load PSD image file"));
216 return NULL;
217 }
218
219 pixels = gdk_pixbuf_get_pixels (pixbuf);
220 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
221
222 compression_type = read_uint16(fp);
223
224 if (compression_type != PSD_COMPRESSION_NONE &&
225 compression_type != PSD_COMPRESSION_RLE) {
226 g_set_error (error, GDK_PIXBUF_ERROR,
227 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
228 ("Unsupported compression type"));
229 return NULL;
230 }
231
232 if (hd.color_mode != PSD_MODE_RGB) {
233 g_set_error (error, GDK_PIXBUF_ERROR,
234 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
235 ("Unsupported color mode"));
236 return NULL;
237 }
238
239 //g_message("mode=%d, channels=%d", hd.color_mode, hd.channels);
240
241 buffers = g_malloc(sizeof(guchar*) * hd.channels);
242
243 if (compression_type == PSD_COMPRESSION_RLE) {
244 guint16 *line_lengths = g_malloc(2 * hd.rows * hd.channels);
245
246 for (int i = 0; i < hd.rows * hd.channels; ++i) {
247 line_lengths[i] = read_uint16(fp);
248 }
249
250 for (int i = 0; i < hd.channels; ++i) {
251 buffers[i] = g_malloc(hd.rows * hd.columns);
252 gint position = 0;
253
254 for (int j = 0; j < hd.rows; ++j) {
255 guint16 bytes_read = 0;
256 while (bytes_read < line_lengths[i * hd.rows + j]) {
257 gchar byte = fgetc(fp);
258 ++bytes_read;
259
260 if (byte == -128) {
261 continue;
262 } else if (byte > -1) {
263 gint count = byte + 1;
264
265 // copy next count bytes
266 for (int k = 0; k < count; ++k) {
267 buffers[i][position] = fgetc(fp);
268 ++bytes_read;
269 ++position;
270 }
271 } else {
272 gint count = -byte + 1;
273
274 // copy next byte count times
275 guchar next_byte = fgetc(fp);
276 ++bytes_read;
277 for (int k = 0; k < count; ++k) {
278 buffers[i][position] = next_byte;
279 ++position;
280 }
281 }
282 }
283 }
284 }
285
286 g_free(line_lengths);
287 }
288
289 if (hd.color_mode == PSD_MODE_RGB) {
290 for (int i = 0; i < hd.rows; ++i) {
291 for (int j = 0; j < hd.columns; ++j) {
292 pixels[i*rowstride + 3*j + 0] = buffers[0][i*hd.columns + j];
293 pixels[i*rowstride + 3*j + 1] = buffers[1][i*hd.columns + j];
294 pixels[i*rowstride + 3*j + 2] = buffers[2][i*hd.columns + j];
295 }
296 }
297 }
298 // TODO: other color modes, CMYK at least
299
300 return pixbuf;
301}
302
303
304// --- progressive loading -----------------------------------------------------
305
306// Attempts to read bytes_needed bytes from data and stores them
307// in buffer.
308// Returns true if there were enough bytes and false otherwise
309// (which means we need to call feed_buffer again)
310
311static gboolean 155static gboolean
312feed_buffer (guchar* buffer, 156feed_buffer (guchar* buffer,
313 guint* bytes_read, 157 guint* bytes_read,
@@ -326,10 +170,12 @@ feed_buffer (guchar* buffer,
326 return (*bytes_read == bytes_needed); 170 return (*bytes_read == bytes_needed);
327} 171}
328 172
329// Attempts to read size of the block and then skip this block. 173/*
330// Returns true when finishes consuming block data, otherwise false 174 * Attempts to read size of the block and then skip this block.
331// (false means we must call skip_block once again) 175 *
332 176 * Returns true when finishes consuming block data, otherwise false
177 * (false means we must call skip_block once again)
178 */
333static gboolean 179static gboolean
334skip_block (PsdContext* context, const guchar** data, guint* size) 180skip_block (PsdContext* context, const guchar** data, guint* size)
335{ 181{
@@ -338,7 +184,7 @@ skip_block (PsdContext* context, const guchar** data, guint* size)
338 if (!context->bytes_to_skip_known) { 184 if (!context->bytes_to_skip_known) {
339 context->bytes_read = 0; 185 context->bytes_read = 0;
340 if (feed_buffer(context->buffer, &context->bytes_read, data, size, 4)) { 186 if (feed_buffer(context->buffer, &context->bytes_read, data, size, 4)) {
341 context->bytes_to_skip = parse_uint32(context->buffer); 187 context->bytes_to_skip = read_uint32(context->buffer);
342 context->bytes_to_skip_known = TRUE; 188 context->bytes_to_skip_known = TRUE;
343 counter = 0; 189 counter = 0;
344 } else { 190 } else {
@@ -359,7 +205,9 @@ skip_block (PsdContext* context, const guchar** data, guint* size)
359 } 205 }
360} 206}
361 207
362// Decodes RLE-compressed data 208/*
209 * Decodes RLE-compressed data
210 */
363static void 211static void
364decompress_line(const guchar* src, guint line_length, guchar* dest) 212decompress_line(const guchar* src, guint line_length, guchar* dest)
365{ 213{
@@ -394,7 +242,7 @@ decompress_line(const guchar* src, guint line_length, guchar* dest)
394} 242}
395 243
396static void 244static void
397reset_context(PsdContext* ctx) 245reset_context_buffer(PsdContext* ctx)
398{ 246{
399 ctx->bytes_read = 0; 247 ctx->bytes_read = 0;
400 ctx->bytes_to_skip = 0; 248 ctx->bytes_to_skip = 0;
@@ -426,12 +274,12 @@ gdk_pixbuf__psd_image_begin_load (GdkPixbufModuleSizeFunc size_func,
426 274
427 // we'll allocate larger buffer once we know image size 275 // we'll allocate larger buffer once we know image size
428 context->buffer = g_malloc(PSD_HEADER_SIZE); 276 context->buffer = g_malloc(PSD_HEADER_SIZE);
429 reset_context(context); 277 reset_context_buffer(context);
430 278
431 context->channels_buffers = NULL; 279 context->ch_bufs = NULL;
432 context->current_channel = 0; 280 context->curr_ch = 0;
433 context->current_row = 0; 281 context->curr_row = 0;
434 context->position = 0; 282 context->pos = 0;
435 context->lines_lengths = NULL; 283 context->lines_lengths = NULL;
436 context->finalized = FALSE; 284 context->finalized = FALSE;
437 285
@@ -449,12 +297,16 @@ gdk_pixbuf__psd_image_stop_load (gpointer context_ptr, GError **error)
449 error, 297 error,
450 GDK_PIXBUF_ERROR, 298 GDK_PIXBUF_ERROR,
451 GDK_PIXBUF_ERROR_CORRUPT_IMAGE, 299 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
452 ("PSD file was corrupted or incomplete. (not PSD_STATE_DONE)")); 300 ("PSD file was corrupted or incomplete."));
453 retval = FALSE; 301 retval = FALSE;
454 } 302 }
455 303
456 g_free (ctx->buffer); // TODO a few more buffers need freeing 304 g_free(ctx->buffer);
457 g_free (ctx); 305 g_free(ctx->lines_lengths);
306 for (int i = 0; i < ctx->channels; i++) {
307 g_free(ctx->ch_bufs[i]);
308 }
309 g_free(ctx);
458 310
459 return retval; 311 return retval;
460} 312}
@@ -467,14 +319,13 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
467 GError **error) 319 GError **error)
468{ 320{
469 321
470 PsdContext* context = (PsdContext*) context_ptr; 322 PsdContext* ctx = (PsdContext*) context_ptr;
471 PsdContext* ctx = context;
472 323
473 while (size > 0) { 324 while (size > 0) {
474 switch (context->state) { 325 switch (ctx->state) {
475 case PSD_STATE_HEADER: 326 case PSD_STATE_HEADER:
476 if (feed_buffer( 327 if (feed_buffer(
477 context->buffer, &context->bytes_read, 328 ctx->buffer, &ctx->bytes_read,
478 &data, &size, PSD_HEADER_SIZE)) 329 &data, &size, PSD_HEADER_SIZE))
479 { 330 {
480 PsdHeader hd = psd_parse_header(ctx->buffer); 331 PsdHeader hd = psd_parse_header(ctx->buffer);
@@ -485,8 +336,8 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
485 ctx->depth = hd.depth; 336 ctx->depth = hd.depth;
486 ctx->color_mode = hd.color_mode; 337 ctx->color_mode = hd.color_mode;
487 338
488 g_message("color_mode=%d, channels=%d, depth=%d", 339 //g_message("color_mode=%d, channels=%d, depth=%d",
489 ctx->color_mode, ctx->channels, ctx->depth); 340 // ctx->color_mode, ctx->channels, ctx->depth);
490 341
491 if (ctx->color_mode != PSD_MODE_RGB/* && 342 if (ctx->color_mode != PSD_MODE_RGB/* &&
492 ctx->color_mode != PSD_MODE_CMYK*/ 343 ctx->color_mode != PSD_MODE_CMYK*/
@@ -535,13 +386,12 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
535 } 386 }
536 387
537 // create separate buffers for each channel 388 // create separate buffers for each channel
538 context->channels_buffers = 389 ctx->ch_bufs = g_malloc(sizeof(guchar*) * ctx->channels);
539 g_malloc(sizeof(guchar*) * ctx->channels);
540 for (int i = 0; i < ctx->channels; i++) { 390 for (int i = 0; i < ctx->channels; i++) {
541 ctx->channels_buffers[i] = 391 ctx->ch_bufs[i] =
542 g_malloc(ctx->width * ctx->height); 392 g_malloc(ctx->width * ctx->height);
543 393
544 if (ctx->channels_buffers[i] == NULL) { 394 if (ctx->ch_bufs[i] == NULL) {
545 g_set_error (error, GDK_PIXBUF_ERROR, 395 g_set_error (error, GDK_PIXBUF_ERROR,
546 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, 396 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
547 ("Insufficient memory to load PSD image file")); 397 ("Insufficient memory to load PSD image file"));
@@ -552,35 +402,35 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
552 ctx->prepared_func(ctx->pixbuf, NULL, ctx->user_data); 402 ctx->prepared_func(ctx->pixbuf, NULL, ctx->user_data);
553 403
554 ctx->state = PSD_STATE_COLOR_MODE_BLOCK; 404 ctx->state = PSD_STATE_COLOR_MODE_BLOCK;
555 reset_context(ctx); 405 reset_context_buffer(ctx);
556 } 406 }
557 break; 407 break;
558 case PSD_STATE_COLOR_MODE_BLOCK: 408 case PSD_STATE_COLOR_MODE_BLOCK:
559 if (skip_block(ctx, &data, &size)) { 409 if (skip_block(ctx, &data, &size)) {
560 ctx->state = PSD_STATE_RESOURCES_BLOCK; 410 ctx->state = PSD_STATE_RESOURCES_BLOCK;
561 reset_context(ctx); 411 reset_context_buffer(ctx);
562 } 412 }
563 break; 413 break;
564 case PSD_STATE_RESOURCES_BLOCK: 414 case PSD_STATE_RESOURCES_BLOCK:
565 if (skip_block(ctx, &data, &size)) { 415 if (skip_block(ctx, &data, &size)) {
566 ctx->state = PSD_STATE_LAYERS_BLOCK; 416 ctx->state = PSD_STATE_LAYERS_BLOCK;
567 reset_context(ctx); 417 reset_context_buffer(ctx);
568 } 418 }
569 break; 419 break;
570 case PSD_STATE_LAYERS_BLOCK: 420 case PSD_STATE_LAYERS_BLOCK:
571 if (skip_block(ctx, &data, &size)) { 421 if (skip_block(ctx, &data, &size)) {
572 ctx->state = PSD_STATE_COMPRESSION; 422 ctx->state = PSD_STATE_COMPRESSION;
573 reset_context(ctx); 423 reset_context_buffer(ctx);
574 } 424 }
575 break; 425 break;
576 case PSD_STATE_COMPRESSION: 426 case PSD_STATE_COMPRESSION:
577 if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, &size, 2)) 427 if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, &size, 2))
578 { 428 {
579 ctx->compression = parse_uint16(ctx->buffer); 429 ctx->compression = read_uint16(ctx->buffer);
580 430
581 if (ctx->compression == PSD_COMPRESSION_RLE) { 431 if (ctx->compression == PSD_COMPRESSION_RLE) {
582 ctx->state = PSD_STATE_LINES_LENGTHS; 432 ctx->state = PSD_STATE_LINES_LENGTHS;
583 reset_context(ctx); 433 reset_context_buffer(ctx);
584 } else if (ctx->compression == PSD_COMPRESSION_NONE) { 434 } else if (ctx->compression == PSD_COMPRESSION_NONE) {
585 ctx->state = PSD_STATE_CHANNEL_DATA; 435 ctx->state = PSD_STATE_CHANNEL_DATA;
586 } else { 436 } else {
@@ -598,11 +448,11 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
598 { 448 {
599 // convert from different endianness 449 // convert from different endianness
600 for (int i = 0; i < ctx->height * ctx->channels; i++) { 450 for (int i = 0; i < ctx->height * ctx->channels; i++) {
601 ctx->lines_lengths[i] = parse_uint16( 451 ctx->lines_lengths[i] = read_uint16(
602 (guchar*) &ctx->lines_lengths[i]); 452 (guchar*) &ctx->lines_lengths[i]);
603 } 453 }
604 ctx->state = PSD_STATE_CHANNEL_DATA; 454 ctx->state = PSD_STATE_CHANNEL_DATA;
605 reset_context(ctx); 455 reset_context_buffer(ctx);
606 } 456 }
607 break; 457 break;
608 case PSD_STATE_CHANNEL_DATA: 458 case PSD_STATE_CHANNEL_DATA:
@@ -610,32 +460,31 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
610 guint line_length = ctx->width; 460 guint line_length = ctx->width;
611 if (ctx->compression == PSD_COMPRESSION_RLE) { 461 if (ctx->compression == PSD_COMPRESSION_RLE) {
612 line_length = ctx->lines_lengths[ 462 line_length = ctx->lines_lengths[
613 ctx->current_channel * ctx->height + ctx->current_row]; 463 ctx->curr_ch * ctx->height + ctx->curr_row];
614 } 464 }
615 465
616 if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, &size, 466 if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, &size,
617 line_length)) 467 line_length))
618 { 468 {
619 ctx->bytes_read = 0; 469 reset_context_buffer(ctx);
620 470
621 if (ctx->compression == PSD_COMPRESSION_RLE) { 471 if (ctx->compression == PSD_COMPRESSION_RLE) {
622 decompress_line(ctx->buffer, line_length, 472 decompress_line(ctx->buffer, line_length,
623 ctx->channels_buffers[ctx->current_channel] 473 ctx->ch_bufs[ctx->curr_ch] + ctx->pos
624 + ctx->position
625 ); 474 );
626 } else { 475 } else {
627 memcpy(ctx->channels_buffers[ctx->current_channel] 476 memcpy(ctx->ch_bufs[ctx->curr_ch] + ctx->pos,
628 + ctx->position, ctx->buffer, ctx->width); 477 ctx->buffer, ctx->width);
629 } 478 }
630 479
631 ctx->position += ctx->width; 480 ctx->pos += ctx->width;
632 ++ctx->current_row; 481 ++ctx->curr_row;
633 482
634 if (ctx->current_row >= ctx->height) { 483 if (ctx->curr_row >= ctx->height) {
635 ++ctx->current_channel; 484 ++ctx->curr_ch;
636 ctx->current_row = 0; 485 ctx->curr_row = 0;
637 ctx->position = 0; 486 ctx->pos = 0;
638 if (ctx->current_channel >= ctx->channels) { 487 if (ctx->curr_ch >= ctx->channels) {
639 ctx->state = PSD_STATE_DONE; 488 ctx->state = PSD_STATE_DONE;
640 } 489 }
641 } 490 }
@@ -655,9 +504,9 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
655 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf); 504 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf);
656 for (int i = 0; i < ctx->height; i++) { 505 for (int i = 0; i < ctx->height; i++) {
657 for (int j = 0; j < ctx->width; j++) { 506 for (int j = 0; j < ctx->width; j++) {
658 pixels[3*j+0] = ctx->channels_buffers[0][ctx->width*i + j]; 507 pixels[3*j+0] = ctx->ch_bufs[0][ctx->width*i + j];
659 pixels[3*j+1] = ctx->channels_buffers[1][ctx->width*i + j]; 508 pixels[3*j+1] = ctx->ch_bufs[1][ctx->width*i + j];
660 pixels[3*j+2] = ctx->channels_buffers[2][ctx->width*i + j]; 509 pixels[3*j+2] = ctx->ch_bufs[2][ctx->width*i + j];
661 } 510 }
662 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf); 511 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf);
663 } 512 }