OLD | NEW |
1 // Copyright 2010 Google Inc. All Rights Reserved. | 1 // Copyright 2010 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
9 // | 9 // |
10 // Main decoding functions for WEBP images. | 10 // Main decoding functions for WEBP images. |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 if (headers != NULL) { | 396 if (headers != NULL) { |
397 *headers = hdrs; | 397 *headers = hdrs; |
398 headers->offset = data - headers->data; | 398 headers->offset = data - headers->data; |
399 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD); | 399 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD); |
400 assert(headers->offset == headers->data_size - data_size); | 400 assert(headers->offset == headers->data_size - data_size); |
401 } | 401 } |
402 return VP8_STATUS_OK; // Return features from VP8 header. | 402 return VP8_STATUS_OK; // Return features from VP8 header. |
403 } | 403 } |
404 | 404 |
405 VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { | 405 VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { |
406 VP8StatusCode status; | 406 // status is marked volatile as a workaround for a clang-3.8 (aarch64) bug |
| 407 volatile VP8StatusCode status; |
407 int has_animation = 0; | 408 int has_animation = 0; |
408 assert(headers != NULL); | 409 assert(headers != NULL); |
409 // fill out headers, ignore width/height/has_alpha. | 410 // fill out headers, ignore width/height/has_alpha. |
410 status = ParseHeadersInternal(headers->data, headers->data_size, | 411 status = ParseHeadersInternal(headers->data, headers->data_size, |
411 NULL, NULL, NULL, &has_animation, | 412 NULL, NULL, NULL, &has_animation, |
412 NULL, headers); | 413 NULL, headers); |
413 if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) { | 414 if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) { |
414 // TODO(jzern): full support of animation frames will require API additions. | 415 // TODO(jzern): full support of animation frames will require API additions. |
415 if (has_animation) { | 416 if (has_animation) { |
416 status = VP8_STATUS_UNSUPPORTED_FEATURE; | 417 status = VP8_STATUS_UNSUPPORTED_FEATURE; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 if (!VP8LDecodeImage(dec)) { | 494 if (!VP8LDecodeImage(dec)) { |
494 status = dec->status_; | 495 status = dec->status_; |
495 } | 496 } |
496 } | 497 } |
497 } | 498 } |
498 VP8LDelete(dec); | 499 VP8LDelete(dec); |
499 } | 500 } |
500 | 501 |
501 if (status != VP8_STATUS_OK) { | 502 if (status != VP8_STATUS_OK) { |
502 WebPFreeDecBuffer(params->output); | 503 WebPFreeDecBuffer(params->output); |
503 } | 504 } else { |
504 | 505 if (params->options != NULL && params->options->flip) { |
505 if (params->options != NULL && params->options->flip) { | 506 // This restores the original stride values if options->flip was used |
506 status = WebPFlipBuffer(params->output); | 507 // during the call to WebPAllocateDecBuffer above. |
| 508 status = WebPFlipBuffer(params->output); |
| 509 } |
507 } | 510 } |
508 return status; | 511 return status; |
509 } | 512 } |
510 | 513 |
511 // Helpers | 514 // Helpers |
512 static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace, | 515 static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace, |
513 const uint8_t* const data, | 516 const uint8_t* const data, |
514 size_t data_size, | 517 size_t data_size, |
515 uint8_t* const rgba, | 518 uint8_t* const rgba, |
516 int stride, size_t size) { | 519 int stride, size_t size) { |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 | 742 |
740 status = GetFeatures(data, data_size, &config->input); | 743 status = GetFeatures(data, data_size, &config->input); |
741 if (status != VP8_STATUS_OK) { | 744 if (status != VP8_STATUS_OK) { |
742 if (status == VP8_STATUS_NOT_ENOUGH_DATA) { | 745 if (status == VP8_STATUS_NOT_ENOUGH_DATA) { |
743 return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error. | 746 return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error. |
744 } | 747 } |
745 return status; | 748 return status; |
746 } | 749 } |
747 | 750 |
748 WebPResetDecParams(¶ms); | 751 WebPResetDecParams(¶ms); |
| 752 params.options = &config->options; |
749 params.output = &config->output; | 753 params.output = &config->output; |
750 params.options = &config->options; | 754 if (WebPAvoidSlowMemory(params.output, &config->input)) { |
751 status = DecodeInto(data, data_size, ¶ms); | 755 // decoding to slow memory: use a temporary in-mem buffer to decode into. |
| 756 WebPDecBuffer in_mem_buffer; |
| 757 WebPInitDecBuffer(&in_mem_buffer); |
| 758 in_mem_buffer.colorspace = config->output.colorspace; |
| 759 in_mem_buffer.width = config->input.width; |
| 760 in_mem_buffer.height = config->input.height; |
| 761 params.output = &in_mem_buffer; |
| 762 status = DecodeInto(data, data_size, ¶ms); |
| 763 if (status == VP8_STATUS_OK) { // do the slow-copy |
| 764 status = WebPCopyDecBufferPixels(&in_mem_buffer, &config->output); |
| 765 } |
| 766 WebPFreeDecBuffer(&in_mem_buffer); |
| 767 } else { |
| 768 status = DecodeInto(data, data_size, ¶ms); |
| 769 } |
752 | 770 |
753 return status; | 771 return status; |
754 } | 772 } |
755 | 773 |
756 //------------------------------------------------------------------------------ | 774 //------------------------------------------------------------------------------ |
757 // Cropping and rescaling. | 775 // Cropping and rescaling. |
758 | 776 |
759 int WebPIoInitFromOptions(const WebPDecoderOptions* const options, | 777 int WebPIoInitFromOptions(const WebPDecoderOptions* const options, |
760 VP8Io* const io, WEBP_CSP_MODE src_colorspace) { | 778 VP8Io* const io, WEBP_CSP_MODE src_colorspace) { |
761 const int W = io->width; | 779 const int W = io->width; |
(...skipping 28 matching lines...) Expand all Loading... |
790 int scaled_width = options->scaled_width; | 808 int scaled_width = options->scaled_width; |
791 int scaled_height = options->scaled_height; | 809 int scaled_height = options->scaled_height; |
792 if (!WebPRescalerGetScaledDimensions(w, h, &scaled_width, &scaled_height)) { | 810 if (!WebPRescalerGetScaledDimensions(w, h, &scaled_width, &scaled_height)) { |
793 return 0; | 811 return 0; |
794 } | 812 } |
795 io->scaled_width = scaled_width; | 813 io->scaled_width = scaled_width; |
796 io->scaled_height = scaled_height; | 814 io->scaled_height = scaled_height; |
797 } | 815 } |
798 | 816 |
799 // Filter | 817 // Filter |
800 io->bypass_filtering = options && options->bypass_filtering; | 818 io->bypass_filtering = (options != NULL) && options->bypass_filtering; |
801 | 819 |
802 // Fancy upsampler | 820 // Fancy upsampler |
803 #ifdef FANCY_UPSAMPLING | 821 #ifdef FANCY_UPSAMPLING |
804 io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling); | 822 io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling); |
805 #endif | 823 #endif |
806 | 824 |
807 if (io->use_scaling) { | 825 if (io->use_scaling) { |
808 // disable filter (only for large downscaling ratio). | 826 // disable filter (only for large downscaling ratio). |
809 io->bypass_filtering = (io->scaled_width < W * 3 / 4) && | 827 io->bypass_filtering = (io->scaled_width < W * 3 / 4) && |
810 (io->scaled_height < H * 3 / 4); | 828 (io->scaled_height < H * 3 / 4); |
811 io->fancy_upsampling = 0; | 829 io->fancy_upsampling = 0; |
812 } | 830 } |
813 return 1; | 831 return 1; |
814 } | 832 } |
815 | 833 |
816 //------------------------------------------------------------------------------ | 834 //------------------------------------------------------------------------------ |
817 | |
OLD | NEW |