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

Side by Side Diff: src/images/SkImageDecoder_libjpeg.cpp

Issue 1426943009: Delete dead SkImageDecoder::buildTileIndex and decodeSubset code (Closed) Base URL: https://skia.googlesource.com/skia.git@delete-tools
Patch Set: Created 5 years, 1 month 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 | « src/images/SkImageDecoder.cpp ('k') | src/images/SkImageDecoder_libpng.cpp » ('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 2007 The Android Open Source Project 2 * Copyright 2007 The Android Open Source Project
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 8
9 #include "SkImageDecoder.h" 9 #include "SkImageDecoder.h"
10 #include "SkImageEncoder.h" 10 #include "SkImageEncoder.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 /* To suppress error messages with a SK_DEBUG binary, set the 79 /* To suppress error messages with a SK_DEBUG binary, set the
80 * environment variable "skia_images_jpeg_suppressDecoderErrors" 80 * environment variable "skia_images_jpeg_suppressDecoderErrors"
81 * to "true". Inside a program that links to skia: 81 * to "true". Inside a program that links to skia:
82 * SK_CONF_SET("images.jpeg.suppressDecoderErrors", true); */ 82 * SK_CONF_SET("images.jpeg.suppressDecoderErrors", true); */
83 if (c_suppressJPEGImageDecoderErrors) { 83 if (c_suppressJPEGImageDecoderErrors) {
84 cinfo->err->output_message = &do_nothing_output_message; 84 cinfo->err->output_message = &do_nothing_output_message;
85 } 85 }
86 } 86 }
87 87
88 #ifdef SK_JPEG_INDEX_SUPPORTED
89 class SkJPEGImageIndex {
90 public:
91 // Takes ownership of stream.
92 SkJPEGImageIndex(SkStreamRewindable* stream, SkImageDecoder* decoder)
93 : fSrcMgr(stream, decoder)
94 , fStream(stream)
95 , fInfoInitialized(false)
96 , fHuffmanCreated(false)
97 , fDecompressStarted(false)
98 {
99 SkDEBUGCODE(fReadHeaderSucceeded = false;)
100 }
101
102 ~SkJPEGImageIndex() {
103 if (fHuffmanCreated) {
104 // Set to false before calling the libjpeg function, in case
105 // the libjpeg function calls longjmp. Our setjmp handler may
106 // attempt to delete this SkJPEGImageIndex, thus entering this
107 // destructor again. Setting fHuffmanCreated to false first
108 // prevents an infinite loop.
109 fHuffmanCreated = false;
110 jpeg_destroy_huffman_index(&fHuffmanIndex);
111 }
112 if (fDecompressStarted) {
113 // Like fHuffmanCreated, set to false before calling libjpeg
114 // function to prevent potential infinite loop.
115 fDecompressStarted = false;
116 jpeg_finish_decompress(&fCInfo);
117 }
118 if (fInfoInitialized) {
119 this->destroyInfo();
120 }
121 }
122
123 /**
124 * Destroy the cinfo struct.
125 * After this call, if a huffman index was already built, it
126 * can be used after calling initializeInfoAndReadHeader
127 * again. Must not be called after startTileDecompress except
128 * in the destructor.
129 */
130 void destroyInfo() {
131 SkASSERT(fInfoInitialized);
132 SkASSERT(!fDecompressStarted);
133 // Like fHuffmanCreated, set to false before calling libjpeg
134 // function to prevent potential infinite loop.
135 fInfoInitialized = false;
136 jpeg_destroy_decompress(&fCInfo);
137 SkDEBUGCODE(fReadHeaderSucceeded = false;)
138 }
139
140 /**
141 * Initialize the cinfo struct.
142 * Calls jpeg_create_decompress, makes customizations, and
143 * finally calls jpeg_read_header. Returns true if jpeg_read_header
144 * returns JPEG_HEADER_OK.
145 * If cinfo was already initialized, destroyInfo must be called to
146 * destroy the old one. Must not be called after startTileDecompress.
147 */
148 bool initializeInfoAndReadHeader() {
149 SkASSERT(!fInfoInitialized && !fDecompressStarted);
150 initialize_info(&fCInfo, &fSrcMgr);
151 fInfoInitialized = true;
152 const bool success = (JPEG_HEADER_OK == jpeg_read_header(&fCInfo, true)) ;
153 SkDEBUGCODE(fReadHeaderSucceeded = success;)
154 return success;
155 }
156
157 jpeg_decompress_struct* cinfo() { return &fCInfo; }
158
159 huffman_index* huffmanIndex() { return &fHuffmanIndex; }
160
161 /**
162 * Build the index to be used for tile based decoding.
163 * Must only be called after a successful call to
164 * initializeInfoAndReadHeader and must not be called more
165 * than once.
166 */
167 bool buildHuffmanIndex() {
168 SkASSERT(fReadHeaderSucceeded);
169 SkASSERT(!fHuffmanCreated);
170 jpeg_create_huffman_index(&fCInfo, &fHuffmanIndex);
171 SkASSERT(1 == fCInfo.scale_num && 1 == fCInfo.scale_denom);
172 fHuffmanCreated = jpeg_build_huffman_index(&fCInfo, &fHuffmanIndex);
173 return fHuffmanCreated;
174 }
175
176 /**
177 * Start tile based decoding. Must only be called after a
178 * successful call to buildHuffmanIndex, and must only be
179 * called once.
180 */
181 bool startTileDecompress() {
182 SkASSERT(fHuffmanCreated);
183 SkASSERT(fReadHeaderSucceeded);
184 SkASSERT(!fDecompressStarted);
185 if (jpeg_start_tile_decompress(&fCInfo)) {
186 fDecompressStarted = true;
187 return true;
188 }
189 return false;
190 }
191
192 private:
193 skjpeg_source_mgr fSrcMgr;
194 SkAutoTDelete<SkStream> fStream;
195 jpeg_decompress_struct fCInfo;
196 huffman_index fHuffmanIndex;
197 bool fInfoInitialized;
198 bool fHuffmanCreated;
199 bool fDecompressStarted;
200 SkDEBUGCODE(bool fReadHeaderSucceeded;)
201 };
202 #endif
203
204 class SkJPEGImageDecoder : public SkImageDecoder { 88 class SkJPEGImageDecoder : public SkImageDecoder {
205 public: 89 public:
206 #ifdef SK_JPEG_INDEX_SUPPORTED
207 SkJPEGImageDecoder() {
208 fImageIndex = nullptr;
209 fImageWidth = 0;
210 fImageHeight = 0;
211 }
212
213 virtual ~SkJPEGImageDecoder() { delete fImageIndex; }
214 #endif
215 90
216 Format getFormat() const override { 91 Format getFormat() const override {
217 return kJPEG_Format; 92 return kJPEG_Format;
218 } 93 }
219 94
220 protected: 95 protected:
221 #ifdef SK_JPEG_INDEX_SUPPORTED
222 bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) o verride;
223 bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) override;
224 #endif
225 Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override; 96 Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
226 bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], 97 bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
227 void* planes[3], size_t rowBytes[3], 98 void* planes[3], size_t rowBytes[3],
228 SkYUVColorSpace* colorSpace) override; 99 SkYUVColorSpace* colorSpace) override;
229 100
230 private: 101 private:
231 #ifdef SK_JPEG_INDEX_SUPPORTED
232 SkJPEGImageIndex* fImageIndex;
233 int fImageWidth;
234 int fImageHeight;
235 #endif
236 102
237 /** 103 /**
238 * Determine the appropriate bitmap colortype and out_color_space based on 104 * Determine the appropriate bitmap colortype and out_color_space based on
239 * both the preference of the caller and the jpeg_color_space on the 105 * both the preference of the caller and the jpeg_color_space on the
240 * jpeg_decompress_struct passed in. 106 * jpeg_decompress_struct passed in.
241 * Must be called after jpeg_read_header. 107 * Must be called after jpeg_read_header.
242 */ 108 */
243 SkColorType getBitmapColorType(jpeg_decompress_struct*); 109 SkColorType getBitmapColorType(jpeg_decompress_struct*);
244 110
245 typedef SkImageDecoder INHERITED; 111 typedef SkImageDecoder INHERITED;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 for (int i = 0; i < count; i++) { 154 for (int i = 0; i < count; i++) {
289 JSAMPLE* rowptr = (JSAMPLE*)buffer; 155 JSAMPLE* rowptr = (JSAMPLE*)buffer;
290 int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1); 156 int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1);
291 if (1 != row_count) { 157 if (1 != row_count) {
292 return false; 158 return false;
293 } 159 }
294 } 160 }
295 return true; 161 return true;
296 } 162 }
297 163
298 #ifdef SK_JPEG_INDEX_SUPPORTED
299 static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo,
300 huffman_index *index, void* buffer, int count) {
301 for (int i = 0; i < count; i++) {
302 JSAMPLE* rowptr = (JSAMPLE*)buffer;
303 int row_count = jpeg_read_tile_scanline(cinfo, index, &rowptr);
304 if (1 != row_count) {
305 return false;
306 }
307 }
308 return true;
309 }
310 #endif
311
312 /////////////////////////////////////////////////////////////////////////////// 164 ///////////////////////////////////////////////////////////////////////////////
313 165
314 // This guy exists just to aid in debugging, as it allows debuggers to just 166 // This guy exists just to aid in debugging, as it allows debuggers to just
315 // set a break-point in one place to see all error exists. 167 // set a break-point in one place to see all error exists.
316 static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo, 168 static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo,
317 int width, int height, const char caller[]) { 169 int width, int height, const char caller[]) {
318 if (!(c_suppressJPEGImageDecoderErrors)) { 170 if (!(c_suppressJPEGImageDecoderErrors)) {
319 char buffer[JMSG_LENGTH_MAX]; 171 char buffer[JMSG_LENGTH_MAX];
320 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer); 172 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer);
321 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", 173 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n",
322 cinfo.err->msg_code, buffer, caller, width, height); 174 cinfo.err->msg_code, buffer, caller, width, height);
323 } 175 }
324 } 176 }
325 177
326 static bool return_false(const jpeg_decompress_struct& cinfo, 178 static bool return_false(const jpeg_decompress_struct& cinfo,
327 const char caller[]) { 179 const char caller[]) {
328 print_jpeg_decoder_errors(cinfo, 0, 0, caller); 180 print_jpeg_decoder_errors(cinfo, 0, 0, caller);
329 return false; 181 return false;
330 } 182 }
331 183
332 #ifdef SK_JPEG_INDEX_SUPPORTED
333 static bool return_false(const jpeg_decompress_struct& cinfo,
334 const SkBitmap& bm, const char caller[]) {
335 print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller);
336 return false;
337 }
338 #endif
339
340 static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo , 184 static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo ,
341 const SkBitmap& bm, const char call er[]) { 185 const SkBitmap& bm, const char call er[]) {
342 print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller); 186 print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller);
343 return SkImageDecoder::kFailure; 187 return SkImageDecoder::kFailure;
344 } 188 }
345 189
346 /////////////////////////////////////////////////////////////////////////////// 190 ///////////////////////////////////////////////////////////////////////////////
347 191
348 // Convert a scanline of CMYK samples to RGBX in place. Note that this 192 // Convert a scanline of CMYK samples to RGBX in place. Note that this
349 // method moves the "scanline" pointer in its processing 193 // method moves the "scanline" pointer in its processing
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 776
933 if (nullptr != colorSpace) { 777 if (nullptr != colorSpace) {
934 *colorSpace = kJPEG_SkYUVColorSpace; 778 *colorSpace = kJPEG_SkYUVColorSpace;
935 } 779 }
936 780
937 return true; 781 return true;
938 } 782 }
939 783
940 /////////////////////////////////////////////////////////////////////////////// 784 ///////////////////////////////////////////////////////////////////////////////
941 785
942 #ifdef SK_JPEG_INDEX_SUPPORTED
943 bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width , int *height) {
944 SkAutoTDelete<SkJPEGImageIndex> imageIndex(new SkJPEGImageIndex(stream, this ));
945
946 skjpeg_error_mgr sk_err;
947 set_error_mgr(imageIndex->cinfo(), &sk_err);
948
949 // All objects need to be instantiated before this setjmp call so that
950 // they will be cleaned up properly if an error occurs.
951 if (setjmp(sk_err.fJmpBuf)) {
952 return false;
953 }
954
955 // create the cinfo used to create/build the huffmanIndex
956 if (!imageIndex->initializeInfoAndReadHeader()) {
957 return false;
958 }
959
960 if (!imageIndex->buildHuffmanIndex()) {
961 return false;
962 }
963
964 // destroy the cinfo used to create/build the huffman index
965 imageIndex->destroyInfo();
966
967 // Init decoder to image decode mode
968 if (!imageIndex->initializeInfoAndReadHeader()) {
969 return false;
970 }
971
972 jpeg_decompress_struct* cinfo = imageIndex->cinfo();
973 // We have a new cinfo, so set the error mgr again.
974 set_error_mgr(cinfo, &sk_err);
975
976 // FIXME: This sets cinfo->out_color_space, which we may change later
977 // based on the config in onDecodeSubset. This should be fine, since
978 // jpeg_init_read_tile_scanline will check out_color_space again after
979 // that change (when it calls jinit_color_deconverter).
980 (void) this->getBitmapColorType(cinfo);
981
982 turn_off_visual_optimizations(cinfo);
983
984 // instead of jpeg_start_decompress() we start a tiled decompress
985 if (!imageIndex->startTileDecompress()) {
986 return false;
987 }
988
989 SkASSERT(1 == cinfo->scale_num);
990 fImageWidth = cinfo->output_width;
991 fImageHeight = cinfo->output_height;
992
993 if (width) {
994 *width = fImageWidth;
995 }
996 if (height) {
997 *height = fImageHeight;
998 }
999
1000 delete fImageIndex;
1001 fImageIndex = imageIndex.detach();
1002
1003 return true;
1004 }
1005
1006 bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
1007 if (nullptr == fImageIndex) {
1008 return false;
1009 }
1010 jpeg_decompress_struct* cinfo = fImageIndex->cinfo();
1011
1012 SkIRect rect = SkIRect::MakeWH(fImageWidth, fImageHeight);
1013 if (!rect.intersect(region)) {
1014 // If the requested region is entirely outside the image return false
1015 return false;
1016 }
1017
1018
1019 skjpeg_error_mgr errorManager;
1020 set_error_mgr(cinfo, &errorManager);
1021
1022 if (setjmp(errorManager.fJmpBuf)) {
1023 return false;
1024 }
1025
1026 int requestedSampleSize = this->getSampleSize();
1027 cinfo->scale_denom = requestedSampleSize;
1028
1029 set_dct_method(*this, cinfo);
1030
1031 const SkColorType colorType = this->getBitmapColorType(cinfo);
1032 adjust_out_color_space_and_dither(cinfo, colorType, *this);
1033
1034 int startX = rect.fLeft;
1035 int startY = rect.fTop;
1036 int width = rect.width();
1037 int height = rect.height();
1038
1039 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(),
1040 &startX, &startY, &width, &height);
1041 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
1042 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz e);
1043
1044 SkScaledBitmapSampler sampler(width, height, skiaSampleSize);
1045
1046 SkBitmap bitmap;
1047 // Assume an A8 bitmap is not opaque to avoid the check of each
1048 // individual pixel. It is very unlikely to be opaque, since
1049 // an opaque A8 bitmap would not be very interesting.
1050 // Otherwise, a jpeg image is opaque.
1051 bitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight (), colorType,
1052 kAlpha_8_SkColorType == colorType ?
1053 kPremul_SkAlphaType : kOpaque_SkAlphaTy pe));
1054
1055 // Check ahead of time if the swap(dest, src) is possible or not.
1056 // If yes, then we will stick to AllocPixelRef since it's cheaper with the
1057 // swap happening. If no, then we will use alloc to allocate pixels to
1058 // prevent garbage collection.
1059 int w = rect.width() / actualSampleSize;
1060 int h = rect.height() / actualSampleSize;
1061 bool swapOnly = (rect == region) && bm->isNull() &&
1062 (w == bitmap.width()) && (h == bitmap.height()) &&
1063 ((startX - rect.x()) / actualSampleSize == 0) &&
1064 ((startY - rect.y()) / actualSampleSize == 0);
1065 if (swapOnly) {
1066 if (!this->allocPixelRef(&bitmap, nullptr)) {
1067 return return_false(*cinfo, bitmap, "allocPixelRef");
1068 }
1069 } else {
1070 if (!bitmap.tryAllocPixels()) {
1071 return return_false(*cinfo, bitmap, "allocPixels");
1072 }
1073 }
1074
1075 SkAutoLockPixels alp(bitmap);
1076
1077 #ifdef ANDROID_RGB
1078 /* short-circuit the SkScaledBitmapSampler when possible, as this gives
1079 a significant performance boost.
1080 */
1081 if (skiaSampleSize == 1 &&
1082 ((kN32_SkColorType == colorType && cinfo->out_color_space == JCS_RGBA_88 88) ||
1083 (kRGB_565_SkColorType == colorType && cinfo->out_color_space == JCS_RGB _565)))
1084 {
1085 JSAMPLE* rowptr = (JSAMPLE*)bitmap.getPixels();
1086 INT32 const bpr = bitmap.rowBytes();
1087 int rowTotalCount = 0;
1088
1089 while (rowTotalCount < height) {
1090 int rowCount = jpeg_read_tile_scanline(cinfo,
1091 fImageIndex->huffmanIndex(),
1092 &rowptr);
1093 // if rowCount == 0, then we didn't get a scanline, so abort.
1094 // onDecodeSubset() relies on onBuildTileIndex(), which
1095 // needs a complete image to succeed.
1096 if (0 == rowCount) {
1097 return return_false(*cinfo, bitmap, "read_scanlines");
1098 }
1099 if (this->shouldCancelDecode()) {
1100 return return_false(*cinfo, bitmap, "shouldCancelDecode");
1101 }
1102 rowTotalCount += rowCount;
1103 rowptr += bpr;
1104 }
1105
1106 if (swapOnly) {
1107 bm->swap(bitmap);
1108 return true;
1109 }
1110
1111 return cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
1112 region.width(), region.height(), startX, startY);
1113 }
1114 #endif
1115
1116 // check for supported formats
1117 SkScaledBitmapSampler::SrcConfig sc;
1118 int srcBytesPerPixel;
1119
1120 if (!get_src_config(*cinfo, &sc, &srcBytesPerPixel)) {
1121 return return_false(*cinfo, *bm, "jpeg colorspace");
1122 }
1123
1124 if (!sampler.begin(&bitmap, sc, *this)) {
1125 return return_false(*cinfo, bitmap, "sampler.begin");
1126 }
1127
1128 SkAutoMalloc srcStorage(width * srcBytesPerPixel);
1129 uint8_t* srcRow = (uint8_t*)srcStorage.get();
1130
1131 // Possibly skip initial rows [sampler.srcY0]
1132 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler. srcY0())) {
1133 return return_false(*cinfo, bitmap, "skip rows");
1134 }
1135
1136 // now loop through scanlines until y == bitmap->height() - 1
1137 for (int y = 0;; y++) {
1138 JSAMPLE* rowptr = (JSAMPLE*)srcRow;
1139 int row_count = jpeg_read_tile_scanline(cinfo, fImageIndex->huffmanIndex (), &rowptr);
1140 // if row_count == 0, then we didn't get a scanline, so abort.
1141 // onDecodeSubset() relies on onBuildTileIndex(), which
1142 // needs a complete image to succeed.
1143 if (0 == row_count) {
1144 return return_false(*cinfo, bitmap, "read_scanlines");
1145 }
1146 if (this->shouldCancelDecode()) {
1147 return return_false(*cinfo, bitmap, "shouldCancelDecode");
1148 }
1149
1150 if (JCS_CMYK == cinfo->out_color_space) {
1151 convert_CMYK_to_RGB(srcRow, width);
1152 }
1153
1154 sampler.next(srcRow);
1155 if (bitmap.height() - 1 == y) {
1156 // we're done
1157 break;
1158 }
1159
1160 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow,
1161 sampler.srcDY() - 1)) {
1162 return return_false(*cinfo, bitmap, "skip rows");
1163 }
1164 }
1165 if (swapOnly) {
1166 bm->swap(bitmap);
1167 return true;
1168 }
1169 return cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
1170 region.width(), region.height(), startX, startY);
1171 }
1172 #endif
1173
1174 ///////////////////////////////////////////////////////////////////////////////
1175
1176 #include "SkColorPriv.h" 786 #include "SkColorPriv.h"
1177 787
1178 // taken from jcolor.c in libjpeg 788 // taken from jcolor.c in libjpeg
1179 #if 0 // 16bit - precise but slow 789 #if 0 // 16bit - precise but slow
1180 #define CYR 19595 // 0.299 790 #define CYR 19595 // 0.299
1181 #define CYG 38470 // 0.587 791 #define CYG 38470 // 0.587
1182 #define CYB 7471 // 0.114 792 #define CYB 7471 // 0.114
1183 793
1184 #define CUR -11059 // -0.16874 794 #define CUR -11059 // -0.16874
1185 #define CUG -21709 // -0.33126 795 #define CUG -21709 // -0.33126
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 return SkImageDecoder::kUnknown_Format; 1056 return SkImageDecoder::kUnknown_Format;
1447 } 1057 }
1448 1058
1449 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { 1059 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
1450 return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr; 1060 return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr;
1451 } 1061 }
1452 1062
1453 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); 1063 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
1454 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); 1064 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
1455 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); 1065 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder.cpp ('k') | src/images/SkImageDecoder_libpng.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698