Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: src/codec/SkJpegCodec.cpp

Issue 2341143002: YUV and color xforms
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dm/DM.cpp ('k') | src/core/SkColorSpaceXform.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodec.h" 8 #include "SkCodec.h"
9 #include "SkMSAN.h" 9 #include "SkMSAN.h"
10 #include "SkJpegCodec.h" 10 #include "SkJpegCodec.h"
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 return count; 528 return count;
529 } 529 }
530 530
531 /* 531 /*
532 * Performs the jpeg decode 532 * Performs the jpeg decode
533 */ 533 */
534 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, 534 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
535 void* dst, size_t dstRowBytes, 535 void* dst, size_t dstRowBytes,
536 const Options& options, SkPMColor*, int *, 536 const Options& options, SkPMColor*, int *,
537 int* rowsDecoded) { 537 int* rowsDecoded) {
538 if (options.fSubset) { 538 /* if (options.fSubset) {
539 // Subsets are not supported. 539 // Subsets are not supported.
540 return kUnimplemented; 540 return kUnimplemented;
541 } 541 }
542 542
543 // Get a pointer to the decompress info since we will use it quite frequentl y 543 // Get a pointer to the decompress info since we will use it quite frequentl y
544 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo(); 544 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
545 545
546 // Set the jump location for libjpeg errors 546 // Set the jump location for libjpeg errors
547 if (setjmp(fDecoderMgr->getJmpBuf())) { 547 if (setjmp(fDecoderMgr->getJmpBuf())) {
548 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); 548 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
(...skipping 21 matching lines...) Expand all
570 570
571 this->allocateStorage(dstInfo); 571 this->allocateStorage(dstInfo);
572 572
573 int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height()); 573 int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height());
574 if (rows < dstInfo.height()) { 574 if (rows < dstInfo.height()) {
575 *rowsDecoded = rows; 575 *rowsDecoded = rows;
576 return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteIn put); 576 return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteIn put);
577 } 577 }
578 578
579 return kSuccess; 579 return kSuccess;
580 */
581
582 this->initializeColorXform(dstInfo);
583
584 // This will check is_yuv_supported(), so we don't need to here.
585 SkYUVSizeInfo yuvInfo;
586 if (!this->onQueryYUV8(&yuvInfo, nullptr)) {
587 return fDecoderMgr->returnFailure("onQueryYUV8", kInvalidInput);
588 }
589
590 // Set the jump location for libjpeg errors
591 if (setjmp(fDecoderMgr->getJmpBuf())) {
592 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
593 }
594
595 // Get a pointer to the decompress info since we will use it quite frequentl y
596 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
597
598 dinfo->raw_data_out = TRUE;
599 if (!jpeg_start_decompress(dinfo)) {
600 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
601 }
602
603 // Currently, we require that the Y plane dimensions match the image dimensi ons
604 // and that the U and V planes are the same dimensions.
605 SkASSERT(yuvInfo.fSizes[SkYUVSizeInfo::kU] == yuvInfo.fSizes[SkYUVSizeInfo:: kV]);
606 SkASSERT((uint32_t) yuvInfo.fSizes[SkYUVSizeInfo::kY].width() == dinfo->outp ut_width &&
607 (uint32_t) yuvInfo.fSizes[SkYUVSizeInfo::kY].height() == dinfo->outp ut_height);
608
609 // Build a JSAMPIMAGE to handle output from libjpeg-turbo. A JSAMPIMAGE has
610 // a 2-D array of pixels for each of the components (Y, U, V) in the image.
611 // Cheat Sheet:
612 // JSAMPIMAGE == JSAMPLEARRAY* == JSAMPROW** == JSAMPLE***
613 JSAMPARRAY yuv[3];
614
615 // Set aside enough space for pointers to rows of Y, U, and V.
616 JSAMPROW rowptrs[2 * DCTSIZE + DCTSIZE + DCTSIZE];
617 yuv[0] = &rowptrs[0]; // Y rows (DCTSIZE or 2 * DCTSIZE)
618 yuv[1] = &rowptrs[1 /******/* DCTSIZE]; // U rows (DCTSIZE)
619 yuv[2] = &rowptrs[2 /*******/* DCTSIZE]; // V rows (DCTSIZE)
620
621 // Initialize rowptrs.
622 SkASSERT(yuvInfo.fWidthBytes[0] == yuvInfo.fWidthBytes[1] && yuvInfo.fWidthB ytes[0] == yuvInfo.fWidthBytes[2]);
623 SkAutoTMalloc<uint8_t> storage(3 * DCTSIZE * yuvInfo.fWidthBytes[0]);
624 int numYRowsPerBlock = DCTSIZE * dinfo->comp_info[0].v_samp_factor;
625 SkASSERT(DCTSIZE == numYRowsPerBlock);
626 JSAMPLE* storagePtr = (JSAMPLE*) storage.get();
627 for (int i = 0; i < numYRowsPerBlock; i++) {
628 rowptrs[i] = storagePtr;
629 storagePtr += yuvInfo.fWidthBytes[0];
630 }
631 for (int i = 0; i < numYRowsPerBlock; i++) {
632 rowptrs[DCTSIZE + i] = storagePtr;
633 storagePtr += yuvInfo.fWidthBytes[0];
634 }
635 for (int i = 0; i < numYRowsPerBlock; i++) {
636 rowptrs[DCTSIZE + DCTSIZE + i] = storagePtr;
637 storagePtr += yuvInfo.fWidthBytes[0];
638 }
639
640 uint32_t numRowsPerBlock = numYRowsPerBlock;
641
642 // We intentionally round down here, as this first loop will only handle
643 // full block rows. As a special case at the end, we will handle any
644 // remaining rows that do not make up a full block.
645 const int numIters = dinfo->output_height / numRowsPerBlock;
646 for (int i = 0; i < numIters; i++) {
647 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
648 if (linesRead < numRowsPerBlock) {
649 // FIXME: Handle incomplete YUV decodes without signalling an error.
650 return kInvalidInput;
651 }
652
653 for (uint32_t j = 0; j < DCTSIZE; j++) {
654 fColorXform->applyYUV(dst, yuv[0][j], yuv[1][j], yuv[2][j], dstInfo. width());
655 dst = SkTAddOffset<void>(dst, dstRowBytes);
656 }
657 }
658
659 uint32_t remainingRows = dinfo->output_height - dinfo->output_scanline;
660 SkASSERT(remainingRows == dinfo->output_height % numRowsPerBlock);
661 SkASSERT(dinfo->output_scanline == numIters * numRowsPerBlock);
662 if (remainingRows > 0) {
663 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
664 if (linesRead < remainingRows) {
665 // FIXME: Handle incomplete YUV decodes without signalling an error.
666 return kInvalidInput;
667 }
668
669 for (uint32_t j = 0; j < remainingRows; j++) {
670 fColorXform->applyYUV(dst, yuv[0][j], yuv[1][j], yuv[2][j], dstInfo. width());
671 dst = SkTAddOffset<void>(dst, dstRowBytes);
672 }
673 }
674
675 return kSuccess;
580 } 676 }
581 677
582 void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) { 678 void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) {
583 int dstWidth = dstInfo.width(); 679 int dstWidth = dstInfo.width();
584 680
585 size_t swizzleBytes = 0; 681 size_t swizzleBytes = 0;
586 if (fSwizzler) { 682 if (fSwizzler) {
587 swizzleBytes = get_row_bytes(fDecoderMgr->dinfo()); 683 swizzleBytes = get_row_bytes(fDecoderMgr->dinfo());
588 dstWidth = fSwizzler->swizzleWidth(); 684 dstWidth = fSwizzler->swizzleWidth();
589 SkASSERT(!fColorXform || SkIsAlign4(swizzleBytes)); 685 SkASSERT(!fColorXform || SkIsAlign4(swizzleBytes));
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 1021
926 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock); 1022 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
927 if (linesRead < remainingRows) { 1023 if (linesRead < remainingRows) {
928 // FIXME: Handle incomplete YUV decodes without signalling an error. 1024 // FIXME: Handle incomplete YUV decodes without signalling an error.
929 return kInvalidInput; 1025 return kInvalidInput;
930 } 1026 }
931 } 1027 }
932 1028
933 return kSuccess; 1029 return kSuccess;
934 } 1030 }
OLDNEW
« no previous file with comments | « dm/DM.cpp ('k') | src/core/SkColorSpaceXform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698