summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--io-psd.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/io-psd.c b/io-psd.c
index 6470f71..1d1b8ce 100644
--- a/io-psd.c
+++ b/io-psd.c
@@ -24,9 +24,10 @@
24 * TODO 24 * TODO
25 * - use http://library.gnome.org/devel/glib/unstable/glib-Byte-Order-Macros.html 25 * - use http://library.gnome.org/devel/glib/unstable/glib-Byte-Order-Macros.html
26 * - report errors from parse_psd_header 26 * - report errors from parse_psd_header
27 * - other color modes 27 * - other color modes (CMYK at least)
28 * - ... 28 * - ...
29 * - MODULE_ENTRY stuff 29 * - MODULE_ENTRY stuff
30 * - i18n
30 */ 31 */
31 32
32#include <stdlib.h> 33#include <stdlib.h>
@@ -99,7 +100,7 @@ typedef struct
99 guint32 width; /* width of image in pixels (1-30000) */ 100 guint32 width; /* width of image in pixels (1-30000) */
100 guint32 height; /* height of image in pixels (1-30000) */ 101 guint32 height; /* height of image in pixels (1-30000) */
101 guint16 channels; /* number of color channels (1-24) */ 102 guint16 channels; /* number of color channels (1-24) */
102 guint16 depth; /* number of bits per channel (1, 8, and 16) */ 103 guint16 depth; /* number of bits per channel (1/8/16) */
103 PsdColorMode color_mode; 104 PsdColorMode color_mode;
104 PsdCompressionType compression; 105 PsdCompressionType compression;
105 106
@@ -109,6 +110,7 @@ typedef struct
109 guint pos; // redundant? 110 guint pos; // redundant?
110 guint16* lines_lengths; 111 guint16* lines_lengths;
111 gboolean finalized; 112 gboolean finalized;
113 gboolean use_alpha;
112} PsdContext; 114} PsdContext;
113 115
114 116
@@ -282,6 +284,7 @@ gdk_pixbuf__psd_image_begin_load (GdkPixbufModuleSizeFunc size_func,
282 context->pos = 0; 284 context->pos = 0;
283 context->lines_lengths = NULL; 285 context->lines_lengths = NULL;
284 context->finalized = FALSE; 286 context->finalized = FALSE;
287 context->use_alpha = FALSE;
285 288
286 return (gpointer) context; 289 return (gpointer) context;
287} 290}
@@ -303,8 +306,10 @@ gdk_pixbuf__psd_image_stop_load (gpointer context_ptr, GError **error)
303 306
304 g_free(ctx->buffer); 307 g_free(ctx->buffer);
305 g_free(ctx->lines_lengths); 308 g_free(ctx->lines_lengths);
306 for (int i = 0; i < ctx->channels; i++) { 309 if (ctx->ch_bufs) {
307 g_free(ctx->ch_bufs[i]); 310 for (int i = 0; i < ctx->channels; i++) {
311 g_free(ctx->ch_bufs[i]);
312 }
308 } 313 }
309 g_free(ctx); 314 g_free(ctx);
310 315
@@ -318,7 +323,6 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
318 guint size, 323 guint size,
319 GError **error) 324 GError **error)
320{ 325{
321
322 PsdContext* ctx = (PsdContext*) context_ptr; 326 PsdContext* ctx = (PsdContext*) context_ptr;
323 327
324 while (size > 0) { 328 while (size > 0) {
@@ -336,11 +340,15 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
336 ctx->depth = hd.depth; 340 ctx->depth = hd.depth;
337 ctx->color_mode = hd.color_mode; 341 ctx->color_mode = hd.color_mode;
338 342
343 if (ctx->color_mode == PSD_MODE_RGB && ctx->channels == 4) {
344 ctx->use_alpha = TRUE;
345 }
346
339 //g_message("color_mode=%d, channels=%d, depth=%d", 347 //g_message("color_mode=%d, channels=%d, depth=%d",
340 // ctx->color_mode, ctx->channels, ctx->depth); 348 // ctx->color_mode, ctx->channels, ctx->depth);
341 349
342 if (ctx->color_mode != PSD_MODE_RGB/* && 350 if (ctx->color_mode != PSD_MODE_RGB
343 ctx->color_mode != PSD_MODE_CMYK*/ 351 //&& ctx->color_mode != PSD_MODE_CMYK
344 ) { 352 ) {
345 g_set_error (error, GDK_PIXBUF_ERROR, 353 g_set_error (error, GDK_PIXBUF_ERROR,
346 GDK_PIXBUF_ERROR_UNKNOWN_TYPE, 354 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
@@ -373,8 +381,8 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
373 ctx->lines_lengths = 381 ctx->lines_lengths =
374 g_malloc(2 * ctx->channels * ctx->height); 382 g_malloc(2 * ctx->channels * ctx->height);
375 383
376 ctx->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 384 ctx->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
377 8, ctx->width, ctx->height); 385 ctx->use_alpha, 8, ctx->width, ctx->height);
378 386
379 if (ctx->lines_lengths == NULL || ctx->buffer == NULL || 387 if (ctx->lines_lengths == NULL || ctx->buffer == NULL ||
380 ctx->pixbuf == NULL) 388 ctx->pixbuf == NULL)
@@ -500,7 +508,7 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
500 508
501 if (ctx->state == PSD_STATE_DONE && !ctx->finalized) { 509 if (ctx->state == PSD_STATE_DONE && !ctx->finalized) {
502 // convert or copy channel buffers to our GdkPixbuf 510 // convert or copy channel buffers to our GdkPixbuf
503 if (ctx->color_mode == PSD_MODE_RGB) { 511 if (ctx->color_mode == PSD_MODE_RGB && !ctx->use_alpha) {
504 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf); 512 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf);
505 for (int i = 0; i < ctx->height; i++) { 513 for (int i = 0; i < ctx->height; i++) {
506 for (int j = 0; j < ctx->width; j++) { 514 for (int j = 0; j < ctx->width; j++) {
@@ -510,6 +518,38 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
510 } 518 }
511 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf); 519 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf);
512 } 520 }
521 } else if (ctx->color_mode == PSD_MODE_RGB && ctx->use_alpha) {
522 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf);
523 for (int i = 0; i < ctx->height; i++) {
524 for (int j = 0; j < ctx->width; j++) {
525 pixels[4*j+0] = ctx->ch_bufs[0][ctx->width*i + j];
526 pixels[4*j+1] = ctx->ch_bufs[1][ctx->width*i + j];
527 pixels[4*j+2] = ctx->ch_bufs[2][ctx->width*i + j];
528 pixels[4*j+3] = ctx->ch_bufs[3][ctx->width*i + j];
529 }
530 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf);
531 }
532 } else if (ctx->color_mode == PSD_MODE_CMYK) {
533 // unfortunately, this doesn't seem to work correctly...
534
535 guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf);
536 for (int i = 0; i < ctx->height; i++) {
537 for (int j = 0; j < ctx->width; j++) {
538 double c = 1.0 -
539 (double) ctx->ch_bufs[0][ctx->width*i + j] / 255.0;
540 double m = 1.0 -
541 (double) ctx->ch_bufs[1][ctx->width*i + j] / 255.0;
542 double y = 1.0 -
543 (double) ctx->ch_bufs[2][ctx->width*i + j] / 255.0;
544 double k = 1.0 -
545 (double) ctx->ch_bufs[3][ctx->width*i + j] / 255.0;
546
547 pixels[3*j+0] = (1.0 - (c * (1.0 - k) + k)) * 255.0;
548 pixels[3*j+1] = (1.0 - (m * (1.0 - k) + k)) * 255.0;
549 pixels[3*j+2] = (1.0 - (y * (1.0 - k) + k)) * 255.0;
550 }
551 pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf);
552 }
513 } 553 }
514 ctx->finalized = TRUE; 554 ctx->finalized = TRUE;
515 } 555 }
@@ -518,17 +558,20 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr,
518} 558}
519 559
520 560
521void 561#ifndef INCLUDE_psd
522fill_vtable (GdkPixbufModule* module) 562#define MODULE_ENTRY(function) G_MODULE_EXPORT void function
563#else
564#define MODULE_ENTRY(function) void _gdk_pixbuf__psd_ ## function
565#endif
566
567MODULE_ENTRY (fill_vtable) (GdkPixbufModule* module)
523{ 568{
524 //module->load = gdk_pixbuf__psd_image_load;
525 module->begin_load = gdk_pixbuf__psd_image_begin_load; 569 module->begin_load = gdk_pixbuf__psd_image_begin_load;
526 module->stop_load = gdk_pixbuf__psd_image_stop_load; 570 module->stop_load = gdk_pixbuf__psd_image_stop_load;
527 module->load_increment = gdk_pixbuf__psd_image_load_increment; 571 module->load_increment = gdk_pixbuf__psd_image_load_increment;
528} 572}
529 573
530void 574MODULE_ENTRY (fill_info) (GdkPixbufFormat *info)
531fill_info (GdkPixbufFormat *info)
532{ 575{
533 static GdkPixbufModulePattern signature[] = { 576 static GdkPixbufModulePattern signature[] = {
534 { "8BPS", NULL, 100 }, 577 { "8BPS", NULL, 100 },