diff options
| author | 2008-12-15 00:57:55 +0000 | |
|---|---|---|
| committer | 2008-12-15 00:57:55 +0000 | |
| commit | 91b7713ed55ddba7c00ecd40e4ce137f90456326 (patch) | |
| tree | fd6f30d07372b00c6e8020802f0a25f4d9d3dd32 /io-psd.c | |
| parent | de21a479786b7733dbcadb422e62b447a87fe7d1 (diff) | |
| download | gdk-pixbuf-psd-91b7713ed55ddba7c00ecd40e4ce137f90456326.tar.gz gdk-pixbuf-psd-91b7713ed55ddba7c00ecd40e4ce137f90456326.tar.bz2 | |
Add support for uncompressed PSDs
git-svn-id: http://gdk-pixbuf-psd.googlecode.com/svn/trunk@6 c5539ac3-5556-0410-9a1f-7faf0b045682
Diffstat (limited to 'io-psd.c')
| -rw-r--r-- | io-psd.c | 114 |
1 files changed, 62 insertions, 52 deletions
| @@ -108,6 +108,7 @@ typedef struct | |||
| 108 | guint current_row; | 108 | guint current_row; |
| 109 | guint position; // ? redundant? | 109 | guint position; // ? redundant? |
| 110 | guint16* lines_lengths; | 110 | guint16* lines_lengths; |
| 111 | gboolean finalized; | ||
| 111 | } PsdContext; | 112 | } PsdContext; |
| 112 | 113 | ||
| 113 | static guint16 | 114 | static guint16 |
| @@ -424,18 +425,15 @@ gdk_pixbuf__psd_image_begin_load (GdkPixbufModuleSizeFunc size_func, | |||
| 424 | context->state = PSD_STATE_HEADER; | 425 | context->state = PSD_STATE_HEADER; |
| 425 | 426 | ||
| 426 | // we'll allocate larger buffer once we know image size | 427 | // we'll allocate larger buffer once we know image size |
| 427 | context->buffer = g_malloc(256); | 428 | context->buffer = g_malloc(PSD_HEADER_SIZE); |
| 428 | reset_context(context); | 429 | reset_context(context); |
| 429 | 430 | ||
| 430 | //context->bytes_read = 0; | ||
| 431 | //context->bytes_to_skip = 0; | ||
| 432 | //context->bytes_to_skip_known = FALSE; | ||
| 433 | |||
| 434 | context->channels_buffers = NULL; | 431 | context->channels_buffers = NULL; |
| 435 | context->current_channel = 0; | 432 | context->current_channel = 0; |
| 436 | context->current_row = 0; | 433 | context->current_row = 0; |
| 437 | context->position = 0; | 434 | context->position = 0; |
| 438 | context->lines_lengths = NULL; | 435 | context->lines_lengths = NULL; |
| 436 | context->finalized = FALSE; | ||
| 439 | 437 | ||
| 440 | return (gpointer) context; | 438 | return (gpointer) context; |
| 441 | } | 439 | } |
| @@ -451,32 +449,8 @@ gdk_pixbuf__psd_image_stop_load (gpointer context_ptr, GError **error) | |||
| 451 | error, | 449 | error, |
| 452 | GDK_PIXBUF_ERROR, | 450 | GDK_PIXBUF_ERROR, |
| 453 | GDK_PIXBUF_ERROR_CORRUPT_IMAGE, | 451 | GDK_PIXBUF_ERROR_CORRUPT_IMAGE, |
| 454 | ("PSD file was corrupted or incomplete.")); | 452 | ("PSD file was corrupted or incomplete. (not PSD_STATE_DONE)")); |
| 455 | retval = FALSE; | 453 | retval = FALSE; |
| 456 | } else { | ||
| 457 | // convert or copy channel buffers to our GdkPixbuf | ||
| 458 | |||
| 459 | //for (int i = 0; i < ctx->channels; i++) { | ||
| 460 | guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf); | ||
| 461 | for (int i = 0; i < ctx->height; i++) { | ||
| 462 | for (int j = 0; j < ctx->width; j++) { | ||
| 463 | pixels[3*j+0] = 0x00; | ||
| 464 | pixels[3*j+1] = 0x00; | ||
| 465 | pixels[3*j+2] = 0x00; | ||
| 466 | } | ||
| 467 | pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf); | ||
| 468 | } | ||
| 469 | |||
| 470 | for (int i = 0; i < 3; i++) { | ||
| 471 | guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf); | ||
| 472 | for (int j = 0; j < ctx->height; j++) { | ||
| 473 | guchar* src_buf = &ctx->channels_buffers[i][ctx->width * j]; | ||
| 474 | for (int k = 0; k < ctx->width; k++) { | ||
| 475 | pixels[3 * k + i] = src_buf[k]; | ||
| 476 | } | ||
| 477 | pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | } | 454 | } |
| 481 | 455 | ||
| 482 | g_free (ctx->buffer); // TODO a few more buffers need freeing | 456 | g_free (ctx->buffer); // TODO a few more buffers need freeing |
| @@ -511,6 +485,25 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr, | |||
| 511 | ctx->depth = hd.depth; | 485 | ctx->depth = hd.depth; |
| 512 | ctx->color_mode = hd.color_mode; | 486 | ctx->color_mode = hd.color_mode; |
| 513 | 487 | ||
| 488 | g_message("color_mode=%d, channels=%d, depth=%d", | ||
| 489 | ctx->color_mode, ctx->channels, ctx->depth); | ||
| 490 | |||
| 491 | if (ctx->color_mode != PSD_MODE_RGB/* && | ||
| 492 | ctx->color_mode != PSD_MODE_CMYK*/ | ||
| 493 | ) { | ||
| 494 | g_set_error (error, GDK_PIXBUF_ERROR, | ||
| 495 | GDK_PIXBUF_ERROR_UNKNOWN_TYPE, | ||
| 496 | ("Unsupported color mode")); | ||
| 497 | return FALSE; | ||
| 498 | } | ||
| 499 | |||
| 500 | if (ctx->depth != 8) { | ||
| 501 | g_set_error (error, GDK_PIXBUF_ERROR, | ||
| 502 | GDK_PIXBUF_ERROR_UNKNOWN_TYPE, | ||
| 503 | ("Unsupported color depth")); | ||
| 504 | return FALSE; | ||
| 505 | } | ||
| 506 | |||
| 514 | if (ctx->size_func) { | 507 | if (ctx->size_func) { |
| 515 | gint w = ctx->width; | 508 | gint w = ctx->width; |
| 516 | gint h = ctx->height; | 509 | gint h = ctx->height; |
| @@ -613,23 +606,31 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr, | |||
| 613 | } | 606 | } |
| 614 | break; | 607 | break; |
| 615 | case PSD_STATE_CHANNEL_DATA: | 608 | case PSD_STATE_CHANNEL_DATA: |
| 616 | if (context->compression == PSD_COMPRESSION_RLE) | ||
| 617 | { | 609 | { |
| 618 | guint line_length = ctx->lines_lengths[ | 610 | guint line_length = ctx->width; |
| 619 | ctx->current_channel * ctx->height + ctx->current_row]; | 611 | if (ctx->compression == PSD_COMPRESSION_RLE) { |
| 620 | if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, | 612 | line_length = ctx->lines_lengths[ |
| 621 | &size, line_length)) | 613 | ctx->current_channel * ctx->height + ctx->current_row]; |
| 614 | } | ||
| 615 | |||
| 616 | if (feed_buffer(ctx->buffer, &ctx->bytes_read, &data, &size, | ||
| 617 | line_length)) | ||
| 622 | { | 618 | { |
| 623 | ctx->bytes_read = 0; | 619 | ctx->bytes_read = 0; |
| 624 | decompress_line( | 620 | |
| 625 | ctx->buffer, | 621 | if (ctx->compression == PSD_COMPRESSION_RLE) { |
| 626 | line_length, | 622 | decompress_line(ctx->buffer, line_length, |
| 627 | ctx->channels_buffers[ctx->current_channel] | 623 | ctx->channels_buffers[ctx->current_channel] |
| 628 | + ctx->position | 624 | + ctx->position |
| 629 | ); | 625 | ); |
| 630 | context->position += context->width; | 626 | } else { |
| 631 | ++context->current_row; | 627 | memcpy(ctx->channels_buffers[ctx->current_channel] |
| 632 | 628 | + ctx->position, ctx->buffer, ctx->width); | |
| 629 | } | ||
| 630 | |||
| 631 | ctx->position += ctx->width; | ||
| 632 | ++ctx->current_row; | ||
| 633 | |||
| 633 | if (ctx->current_row >= ctx->height) { | 634 | if (ctx->current_row >= ctx->height) { |
| 634 | ++ctx->current_channel; | 635 | ++ctx->current_channel; |
| 635 | ctx->current_row = 0; | 636 | ctx->current_row = 0; |
| @@ -639,14 +640,6 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr, | |||
| 639 | } | 640 | } |
| 640 | } | 641 | } |
| 641 | } | 642 | } |
| 642 | } else { | ||
| 643 | if (feed_buffer( | ||
| 644 | context->buffer, &context->bytes_read, | ||
| 645 | &data, &size, context->width)) | ||
| 646 | { | ||
| 647 | //memcpy(dest, context->buffer, context->hd.columns); | ||
| 648 | // TODO | ||
| 649 | } | ||
| 650 | } | 643 | } |
| 651 | break; | 644 | break; |
| 652 | case PSD_STATE_DONE: | 645 | case PSD_STATE_DONE: |
| @@ -655,6 +648,23 @@ gdk_pixbuf__psd_image_load_increment (gpointer context_ptr, | |||
| 655 | break; | 648 | break; |
| 656 | } | 649 | } |
| 657 | } | 650 | } |
| 651 | |||
| 652 | if (ctx->state == PSD_STATE_DONE && !ctx->finalized) { | ||
| 653 | // convert or copy channel buffers to our GdkPixbuf | ||
| 654 | if (ctx->color_mode == PSD_MODE_RGB) { | ||
| 655 | guchar* pixels = gdk_pixbuf_get_pixels(ctx->pixbuf); | ||
| 656 | for (int i = 0; i < ctx->height; i++) { | ||
| 657 | for (int j = 0; j < ctx->width; j++) { | ||
| 658 | pixels[3*j+0] = ctx->channels_buffers[0][ctx->width*i + j]; | ||
| 659 | pixels[3*j+1] = ctx->channels_buffers[1][ctx->width*i + j]; | ||
| 660 | pixels[3*j+2] = ctx->channels_buffers[2][ctx->width*i + j]; | ||
| 661 | } | ||
| 662 | pixels += gdk_pixbuf_get_rowstride(ctx->pixbuf); | ||
| 663 | } | ||
| 664 | } | ||
| 665 | ctx->finalized = TRUE; | ||
| 666 | } | ||
| 667 | |||
| 658 | return TRUE; | 668 | return TRUE; |
| 659 | } | 669 | } |
| 660 | 670 | ||
