diff options
| author | 2008-12-15 21:24:28 +0000 | |
|---|---|---|
| committer | 2008-12-15 21:24:28 +0000 | |
| commit | 82c2d80e8579d13f2ad084b00d6868e2b5ab32c3 (patch) | |
| tree | 318bbdd8a6ad1afd79845eb158f3409001bc86b1 | |
| parent | bf27bdfa14d53b0239e34a232205757d4609dcc2 (diff) | |
| download | gdk-pixbuf-psd-82c2d80e8579d13f2ad084b00d6868e2b5ab32c3.tar.gz gdk-pixbuf-psd-82c2d80e8579d13f2ad084b00d6868e2b5ab32c3.tar.bz2 | |
RGB with alpha channels, uncomplete support for CMYK, some minor fixes
git-svn-id: http://gdk-pixbuf-psd.googlecode.com/svn/trunk@8 c5539ac3-5556-0410-9a1f-7faf0b045682
| -rw-r--r-- | io-psd.c | 73 |
1 files changed, 58 insertions, 15 deletions
| @@ -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 | ||
| 521 | void | 561 | #ifndef INCLUDE_psd |
| 522 | fill_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 | |||
| 567 | MODULE_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 | ||
| 530 | void | 574 | MODULE_ENTRY (fill_info) (GdkPixbufFormat *info) |
| 531 | fill_info (GdkPixbufFormat *info) | ||
| 532 | { | 575 | { |
| 533 | static GdkPixbufModulePattern signature[] = { | 576 | static GdkPixbufModulePattern signature[] = { |
| 534 | { "8BPS", NULL, 100 }, | 577 | { "8BPS", NULL, 100 }, |
