1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkCodecImageGenerator.h"
9 
NewFromEncodedCodec(SkData * data)10 SkImageGenerator* SkCodecImageGenerator::NewFromEncodedCodec(SkData* data) {
11     SkCodec* codec = SkCodec::NewFromData(data);
12     if (nullptr == codec) {
13         return nullptr;
14     }
15 
16     return new SkCodecImageGenerator(codec, data);
17 }
18 
make_premul(const SkImageInfo & info)19 static SkImageInfo make_premul(const SkImageInfo& info) {
20     if (kUnpremul_SkAlphaType == info.alphaType()) {
21         return info.makeAlphaType(kPremul_SkAlphaType);
22     }
23 
24     return info;
25 }
26 
SkCodecImageGenerator(SkCodec * codec,SkData * data)27 SkCodecImageGenerator::SkCodecImageGenerator(SkCodec* codec, SkData* data)
28     : INHERITED(make_premul(codec->getInfo()))
29     , fCodec(codec)
30     , fData(SkRef(data))
31     , fYWidth(0)
32     , fUWidth(0)
33     , fVWidth(0)
34 {}
35 
onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM)36 SkData* SkCodecImageGenerator::onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM) {
37     return SkRef(fData.get());
38 }
39 
onGetPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,SkPMColor ctable[],int * ctableCount)40 bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
41         SkPMColor ctable[], int* ctableCount) {
42 
43     SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, nullptr, ctable,
44             ctableCount);
45     switch (result) {
46         case SkCodec::kSuccess:
47         case SkCodec::kIncompleteInput:
48             return true;
49         default:
50             return false;
51     }
52 }
53 
onGetYUV8Planes(SkISize sizes[3],void * planes[3],size_t rowBytes[3],SkYUVColorSpace * colorSpace)54 bool SkCodecImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
55         SkYUVColorSpace* colorSpace) {
56     // TODO (msarett): Change the YUV API in ImageGenerator to match SkCodec.
57     //                 This function is currently a hack to match the implementation
58     //                 in SkCodec with the old API.
59     SkCodec::YUVSizeInfo sizeInfo;
60 
61     // If planes is NULL, we just need to return the size.
62     if (nullptr == planes) {
63         bool result = fCodec->queryYUV8(&sizeInfo, colorSpace);
64         if (result) {
65             // Save the true widths
66             fYWidth = sizeInfo.fYSize.width();
67             fUWidth = sizeInfo.fUSize.width();
68             fVWidth = sizeInfo.fVSize.width();
69 
70             // Set the sizes so that the client allocates enough memory
71             sizes[0].fWidth = (int) sizeInfo.fYWidthBytes;
72             sizes[0].fHeight = sizeInfo.fYSize.height();
73             sizes[1].fWidth = (int) sizeInfo.fUWidthBytes;
74             sizes[1].fHeight = sizeInfo.fUSize.height();
75             sizes[2].fWidth = (int) sizeInfo.fVWidthBytes;
76             sizes[2].fHeight = sizeInfo.fVSize.height();
77         }
78         return result;
79     }
80 
81     // Set the sizeInfo with the true widths and heights
82     SkASSERT(fYWidth != 0 && fUWidth != 0 && fVWidth != 0);
83     sizeInfo.fYSize.set(fYWidth, sizes[0].height());
84     sizeInfo.fUSize.set(fUWidth, sizes[1].height());
85     sizeInfo.fVSize.set(fVWidth, sizes[2].height());
86 
87     // Set the sizeInfo with the allocated widths
88     sizeInfo.fYWidthBytes = sizes[0].width();
89     sizeInfo.fUWidthBytes = sizes[1].width();
90     sizeInfo.fVWidthBytes = sizes[2].width();
91     SkCodec::Result result = fCodec->getYUV8Planes(sizeInfo, planes);
92     if ((result == SkCodec::kSuccess || result == SkCodec::kIncompleteInput) && colorSpace) {
93         *colorSpace = kJPEG_SkYUVColorSpace;
94     }
95 
96     switch (result) {
97         case SkCodec::kSuccess:
98         case SkCodec::kIncompleteInput:
99             return true;
100         default:
101             return false;
102     }
103 }
104