1 /*
2  * Copyright 2014 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 "SkImageGenerator.h"
9 
getPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const Options * options,SkPMColor ctable[],int * ctableCount)10 SkImageGenerator::Result SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels,
11                                                      size_t rowBytes, const Options* options,
12                                                      SkPMColor ctable[], int* ctableCount) {
13     if (kUnknown_SkColorType == info.colorType()) {
14         return kInvalidConversion;
15     }
16     if (NULL == pixels) {
17         return kInvalidParameters;
18     }
19     if (rowBytes < info.minRowBytes()) {
20         return kInvalidParameters;
21     }
22 
23     if (kIndex_8_SkColorType == info.colorType()) {
24         if (NULL == ctable || NULL == ctableCount) {
25             return kInvalidParameters;
26         }
27     } else {
28         if (ctableCount) {
29             *ctableCount = 0;
30         }
31         ctableCount = NULL;
32         ctable = NULL;
33     }
34 
35     // Default options.
36     Options optsStorage;
37     if (NULL == options) {
38         options = &optsStorage;
39     }
40     const Result result = this->onGetPixels(info, pixels, rowBytes, *options, ctable, ctableCount);
41 
42     if ((kIncompleteInput == result || kSuccess == result) && ctableCount) {
43         SkASSERT(*ctableCount >= 0 && *ctableCount <= 256);
44     }
45     return result;
46 }
47 
getPixels(const SkImageInfo & info,void * pixels,size_t rowBytes)48 SkImageGenerator::Result SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels,
49                                                      size_t rowBytes) {
50     SkASSERT(kIndex_8_SkColorType != info.colorType());
51     if (kIndex_8_SkColorType == info.colorType()) {
52         return kInvalidConversion;
53     }
54     return this->getPixels(info, pixels, rowBytes, NULL, NULL, NULL);
55 }
56 
getYUV8Planes(SkISize sizes[3],void * planes[3],size_t rowBytes[3],SkYUVColorSpace * colorSpace)57 bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
58                                      SkYUVColorSpace* colorSpace) {
59 #ifdef SK_DEBUG
60     // In all cases, we need the sizes array
61     SkASSERT(sizes);
62 
63     bool isValidWithPlanes = (planes) && (rowBytes) &&
64         ((planes[0]) && (planes[1]) && (planes[2]) &&
65          (0  != rowBytes[0]) && (0  != rowBytes[1]) && (0  != rowBytes[2]));
66     bool isValidWithoutPlanes =
67         ((NULL == planes) ||
68          ((NULL == planes[0]) && (NULL == planes[1]) && (NULL == planes[2]))) &&
69         ((NULL == rowBytes) ||
70          ((0 == rowBytes[0]) && (0 == rowBytes[1]) && (0 == rowBytes[2])));
71 
72     // Either we have all planes and rowBytes information or we have none of it
73     // Having only partial information is not supported
74     SkASSERT(isValidWithPlanes || isValidWithoutPlanes);
75 
76     // If we do have planes information, make sure all sizes are non 0
77     // and all rowBytes are valid
78     SkASSERT(!isValidWithPlanes ||
79              ((sizes[0].fWidth  >= 0) &&
80               (sizes[0].fHeight >= 0) &&
81               (sizes[1].fWidth  >= 0) &&
82               (sizes[1].fHeight >= 0) &&
83               (sizes[2].fWidth  >= 0) &&
84               (sizes[2].fHeight >= 0) &&
85               (rowBytes[0] >= (size_t)sizes[0].fWidth) &&
86               (rowBytes[1] >= (size_t)sizes[1].fWidth) &&
87               (rowBytes[2] >= (size_t)sizes[2].fWidth)));
88 #endif
89 
90     return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
91 }
92 
onGetYUV8Planes(SkISize sizes[3],void * planes[3],size_t rowBytes[3])93 bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
94     return false;
95 }
96 
onGetYUV8Planes(SkISize sizes[3],void * planes[3],size_t rowBytes[3],SkYUVColorSpace * colorSpace)97 bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
98                                        SkYUVColorSpace* colorSpace) {
99     // In order to maintain compatibility with clients that implemented the original
100     // onGetYUV8Planes interface, we assume that the color space is JPEG.
101     // TODO(rileya): remove this and the old onGetYUV8Planes once clients switch over to
102     // the new interface.
103     if (colorSpace) {
104         *colorSpace = kJPEG_SkYUVColorSpace;
105     }
106     return this->onGetYUV8Planes(sizes, planes, rowBytes);
107 }
108 
109 /////////////////////////////////////////////////////////////////////////////////////////////
110 
onRefEncodedData()111 SkData* SkImageGenerator::onRefEncodedData() {
112     return NULL;
113 }
114 
115 #ifdef SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
onGetPixels(const SkImageInfo &,void *,size_t,SkPMColor *,int *)116 SkImageGenerator::Result SkImageGenerator::onGetPixels(const SkImageInfo&, void*, size_t,
117                                                        SkPMColor*, int*) {
118     return kUnimplemented;
119 }
120 #endif
121 
onGetPixels(const SkImageInfo & info,void * dst,size_t rb,const Options & options,SkPMColor * colors,int * colorCount)122 SkImageGenerator::Result SkImageGenerator::onGetPixels(const SkImageInfo& info, void* dst,
123                                                        size_t rb, const Options& options,
124                                                        SkPMColor* colors, int* colorCount) {
125 #ifdef SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
126     return this->onGetPixels(info, dst, rb, colors, colorCount);
127 #else
128     return kUnimplemented;
129 #endif
130 }
131