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

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

Issue 1322623004: Call standard libjpeg/libjpeg-turbo APIs from SkJpegCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Need to save the state, so we can call onGetScaledDimensions before rewinding Created 5 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 | « src/codec/SkJpegCodec.h ('k') | src/codec/SkJpegDecoderMgr.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 "SkJpegCodec.h" 9 #include "SkJpegCodec.h"
10 #include "SkJpegDecoderMgr.h" 10 #include "SkJpegDecoderMgr.h"
11 #include "SkJpegUtility_codec.h" 11 #include "SkJpegUtility_codec.h"
12 #include "SkCodecPriv.h" 12 #include "SkCodecPriv.h"
13 #include "SkColorPriv.h" 13 #include "SkColorPriv.h"
14 #include "SkScaledCodec.h" 14 #include "SkScaledCodec.h"
15 #include "SkScanlineDecoder.h" 15 #include "SkScanlineDecoder.h"
16 #include "SkStream.h" 16 #include "SkStream.h"
17 #include "SkTemplates.h" 17 #include "SkTemplates.h"
18 #include "SkTypes.h" 18 #include "SkTypes.h"
19 19
20 // stdio is needed for libjpeg-turbo 20 // stdio is needed for libjpeg-turbo
21 #include <stdio.h> 21 #include <stdio.h>
22 22
23 extern "C" { 23 extern "C" {
24 #include "jpeglibmangler.h"
25 #include "jerror.h" 24 #include "jerror.h"
26 #include "jpegint.h"
27 #include "jpeglib.h" 25 #include "jpeglib.h"
28 } 26 }
29 27
30 /* 28 /*
31 * Convert a row of CMYK samples to RGBA in place. 29 * Convert a row of CMYK samples to RGBA in place.
32 * Note that this method moves the row pointer. 30 * Note that this method moves the row pointer.
33 * @param width the number of pixels in the row that is being converted 31 * @param width the number of pixels in the row that is being converted
34 * CMYK is stored as four bytes per pixel 32 * CMYK is stored as four bytes per pixel
35 */ 33 */
36 static void convert_CMYK_to_RGBA(uint8_t* row, uint32_t width) { 34 static void convert_CMYK_to_RGBA(uint8_t* row, uint32_t width) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 103
106 // libjpeg errors will be caught and reported here 104 // libjpeg errors will be caught and reported here
107 if (setjmp(decoderMgr->getJmpBuf())) { 105 if (setjmp(decoderMgr->getJmpBuf())) {
108 return decoderMgr->returnFalse("setjmp"); 106 return decoderMgr->returnFalse("setjmp");
109 } 107 }
110 108
111 // Initialize the decompress info and the source manager 109 // Initialize the decompress info and the source manager
112 decoderMgr->init(); 110 decoderMgr->init();
113 111
114 // Read the jpeg header 112 // Read the jpeg header
115 if (JPEG_HEADER_OK != chromium_jpeg_read_header(decoderMgr->dinfo(), true)) { 113 if (JPEG_HEADER_OK != jpeg_read_header(decoderMgr->dinfo(), true)) {
116 return decoderMgr->returnFalse("read_header"); 114 return decoderMgr->returnFalse("read_header");
117 } 115 }
118 116
119 if (nullptr != codecOut) { 117 if (nullptr != codecOut) {
120 // Recommend the color type to decode to 118 // Recommend the color type to decode to
121 const SkColorType colorType = decoderMgr->getColorType(); 119 const SkColorType colorType = decoderMgr->getColorType();
122 120
123 // Create image info object and the codec 121 // Create image info object and the codec
124 const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->im age_width, 122 const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->im age_width,
125 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaTyp e); 123 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaTyp e);
(...skipping 14 matching lines...) Expand all
140 streamDeleter.detach(); 138 streamDeleter.detach();
141 return codec; 139 return codec;
142 } 140 }
143 return nullptr; 141 return nullptr;
144 } 142 }
145 143
146 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, 144 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream,
147 JpegDecoderMgr* decoderMgr) 145 JpegDecoderMgr* decoderMgr)
148 : INHERITED(srcInfo, stream) 146 : INHERITED(srcInfo, stream)
149 , fDecoderMgr(decoderMgr) 147 , fDecoderMgr(decoderMgr)
148 , fReadyState(decoderMgr->dinfo()->global_state)
150 {} 149 {}
151 150
152 /* 151 /*
153 * Return the row bytes of a particular image type and width 152 * Return the row bytes of a particular image type and width
154 */ 153 */
155 static int get_row_bytes(const j_decompress_ptr dinfo) { 154 static int get_row_bytes(const j_decompress_ptr dinfo) {
156 int colorBytes = (dinfo->out_color_space == JCS_RGB565) ? 2 : dinfo->out_col or_components; 155 int colorBytes = (dinfo->out_color_space == JCS_RGB565) ? 2 : dinfo->out_col or_components;
157 return dinfo->output_width * colorBytes; 156 return dinfo->output_width * colorBytes;
158 157
159 } 158 }
(...skipping 21 matching lines...) Expand all
181 num = 2; 180 num = 2;
182 } else { 181 } else {
183 num = 1; 182 num = 1;
184 } 183 }
185 184
186 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions 185 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions
187 jpeg_decompress_struct dinfo; 186 jpeg_decompress_struct dinfo;
188 sk_bzero(&dinfo, sizeof(dinfo)); 187 sk_bzero(&dinfo, sizeof(dinfo));
189 dinfo.image_width = this->getInfo().width(); 188 dinfo.image_width = this->getInfo().width();
190 dinfo.image_height = this->getInfo().height(); 189 dinfo.image_height = this->getInfo().height();
191 dinfo.global_state = DSTATE_READY; 190 dinfo.global_state = fReadyState;
192 dinfo.num_components = 0; 191 dinfo.num_components = 0;
193 dinfo.scale_num = num; 192 dinfo.scale_num = num;
194 dinfo.scale_denom = denom; 193 dinfo.scale_denom = denom;
195 chromium_jpeg_calc_output_dimensions(&dinfo); 194 jpeg_calc_output_dimensions(&dinfo);
196 195
197 // Return the calculated output dimensions for the given scale 196 // Return the calculated output dimensions for the given scale
198 return SkISize::Make(dinfo.output_width, dinfo.output_height); 197 return SkISize::Make(dinfo.output_width, dinfo.output_height);
199 } 198 }
200 199
201 bool SkJpegCodec::onRewind() { 200 bool SkJpegCodec::onRewind() {
202 JpegDecoderMgr* decoderMgr = nullptr; 201 JpegDecoderMgr* decoderMgr = nullptr;
203 if (!ReadHeader(this->stream(), nullptr, &decoderMgr)) { 202 if (!ReadHeader(this->stream(), nullptr, &decoderMgr)) {
204 return fDecoderMgr->returnFalse("could not rewind"); 203 return fDecoderMgr->returnFalse("could not rewind");
205 } 204 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 266 }
268 267
269 /* 268 /*
270 * Checks if we can natively scale to the requested dimensions and natively scal es the 269 * Checks if we can natively scale to the requested dimensions and natively scal es the
271 * dimensions if possible 270 * dimensions if possible
272 */ 271 */
273 bool SkJpegCodec::nativelyScaleToDimensions(uint32_t dstWidth, uint32_t dstHeigh t) { 272 bool SkJpegCodec::nativelyScaleToDimensions(uint32_t dstWidth, uint32_t dstHeigh t) {
274 // libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1 273 // libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1
275 fDecoderMgr->dinfo()->scale_denom = 8; 274 fDecoderMgr->dinfo()->scale_denom = 8;
276 fDecoderMgr->dinfo()->scale_num = 8; 275 fDecoderMgr->dinfo()->scale_num = 8;
277 chromium_jpeg_calc_output_dimensions(fDecoderMgr->dinfo()); 276 jpeg_calc_output_dimensions(fDecoderMgr->dinfo());
278 while (fDecoderMgr->dinfo()->output_width != dstWidth || 277 while (fDecoderMgr->dinfo()->output_width != dstWidth ||
279 fDecoderMgr->dinfo()->output_height != dstHeight) { 278 fDecoderMgr->dinfo()->output_height != dstHeight) {
280 279
281 // Return a failure if we have tried all of the possible scales 280 // Return a failure if we have tried all of the possible scales
282 if (1 == fDecoderMgr->dinfo()->scale_num || 281 if (1 == fDecoderMgr->dinfo()->scale_num ||
283 dstWidth > fDecoderMgr->dinfo()->output_width || 282 dstWidth > fDecoderMgr->dinfo()->output_width ||
284 dstHeight > fDecoderMgr->dinfo()->output_height) { 283 dstHeight > fDecoderMgr->dinfo()->output_height) {
285 // reset native scale settings on failure because this may be suppor ted by the swizzler 284 // reset native scale settings on failure because this may be suppor ted by the swizzler
286 this->fDecoderMgr->dinfo()->scale_num = 8; 285 this->fDecoderMgr->dinfo()->scale_num = 8;
287 chromium_jpeg_calc_output_dimensions(this->fDecoderMgr->dinfo()); 286 jpeg_calc_output_dimensions(this->fDecoderMgr->dinfo());
288 return false; 287 return false;
289 } 288 }
290 289
291 // Try the next scale 290 // Try the next scale
292 fDecoderMgr->dinfo()->scale_num -= 1; 291 fDecoderMgr->dinfo()->scale_num -= 1;
293 chromium_jpeg_calc_output_dimensions(fDecoderMgr->dinfo()); 292 jpeg_calc_output_dimensions(fDecoderMgr->dinfo());
294 } 293 }
295 return true; 294 return true;
296 } 295 }
297 296
298 /* 297 /*
299 * Performs the jpeg decode 298 * Performs the jpeg decode
300 */ 299 */
301 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, 300 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
302 void* dst, size_t dstRowBytes, 301 void* dst, size_t dstRowBytes,
303 const Options& options, SkPMColor*, int *) { 302 const Options& options, SkPMColor*, int *) {
(...skipping 19 matching lines...) Expand all
323 if (!this->setOutputColorSpace(dstInfo)) { 322 if (!this->setOutputColorSpace(dstInfo)) {
324 return fDecoderMgr->returnFailure("conversion_possible", kInvalidConvers ion); 323 return fDecoderMgr->returnFailure("conversion_possible", kInvalidConvers ion);
325 } 324 }
326 325
327 // Perform the necessary scaling 326 // Perform the necessary scaling
328 if (!this->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) { 327 if (!this->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) {
329 return fDecoderMgr->returnFailure("cannot scale to requested dims", kInv alidScale); 328 return fDecoderMgr->returnFailure("cannot scale to requested dims", kInv alidScale);
330 } 329 }
331 330
332 // Now, given valid output dimensions, we can start the decompress 331 // Now, given valid output dimensions, we can start the decompress
333 if (!chromium_jpeg_start_decompress(dinfo)) { 332 if (!jpeg_start_decompress(dinfo)) {
334 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput); 333 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
335 } 334 }
336 335
337 // The recommended output buffer height should always be 1 in high quality m odes. 336 // The recommended output buffer height should always be 1 in high quality m odes.
338 // If it's not, we want to know because it means our strategy is not optimal . 337 // If it's not, we want to know because it means our strategy is not optimal .
339 SkASSERT(1 == dinfo->rec_outbuf_height); 338 SkASSERT(1 == dinfo->rec_outbuf_height);
340 339
341 // Perform the decode a single row at a time 340 // Perform the decode a single row at a time
342 uint32_t dstHeight = dstInfo.height(); 341 uint32_t dstHeight = dstInfo.height();
343 JSAMPLE* dstRow = (JSAMPLE*) dst; 342 JSAMPLE* dstRow = (JSAMPLE*) dst;
344 for (uint32_t y = 0; y < dstHeight; y++) { 343 for (uint32_t y = 0; y < dstHeight; y++) {
345 // Read rows of the image 344 // Read rows of the image
346 uint32_t rowsDecoded = chromium_jpeg_read_scanlines(dinfo, &dstRow, 1); 345 uint32_t rowsDecoded = jpeg_read_scanlines(dinfo, &dstRow, 1);
347 346
348 // If we cannot read enough rows, assume the input is incomplete 347 // If we cannot read enough rows, assume the input is incomplete
349 if (rowsDecoded != 1) { 348 if (rowsDecoded != 1) {
350 // Fill the remainder of the image with black. This error handling 349 // Fill the remainder of the image with black. This error handling
351 // behavior is unspecified but SkCodec consistently uses black as 350 // behavior is unspecified but SkCodec consistently uses black as
352 // the fill color for opaque images. If the destination is kGray, 351 // the fill color for opaque images. If the destination is kGray,
353 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, 352 // the low 8 bits of SK_ColorBLACK will be used. Conveniently,
354 // these are zeros, which is the representation for black in kGray. 353 // these are zeros, which is the representation for black in kGray.
355 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK 354 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK
356 // will be used. Conveniently, these are zeros, which is the 355 // will be used. Conveniently, these are zeros, which is the
357 // representation for black in kRGB_565. 356 // representation for black in kRGB_565.
358 if (kNo_ZeroInitialized == options.fZeroInitialized || 357 if (kNo_ZeroInitialized == options.fZeroInitialized ||
359 kN32_SkColorType == dstInfo.colorType()) { 358 kN32_SkColorType == dstInfo.colorType()) {
360 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y, 359 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y,
361 SK_ColorBLACK, nullptr); 360 SK_ColorBLACK, nullptr);
362 } 361 }
363 362
364 // Prevent libjpeg from failing on incomplete decode 363 // Prevent libjpeg from failing on incomplete decode
365 dinfo->output_scanline = dstHeight; 364 dinfo->output_scanline = dstHeight;
366 365
367 // Finish the decode and indicate that the input was incomplete. 366 // Finish the decode and indicate that the input was incomplete.
368 chromium_jpeg_finish_decompress(dinfo); 367 jpeg_finish_decompress(dinfo);
369 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple teInput); 368 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple teInput);
370 } 369 }
371 370
372 // Convert to RGBA if necessary 371 // Convert to RGBA if necessary
373 if (JCS_CMYK == dinfo->out_color_space) { 372 if (JCS_CMYK == dinfo->out_color_space) {
374 convert_CMYK_to_RGBA(dstRow, dstInfo.width()); 373 convert_CMYK_to_RGBA(dstRow, dstInfo.width());
375 } 374 }
376 375
377 // Move to the next row 376 // Move to the next row
378 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); 377 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes);
379 } 378 }
380 chromium_jpeg_finish_decompress(dinfo); 379 jpeg_finish_decompress(dinfo);
381 380
382 return kSuccess; 381 return kSuccess;
383 } 382 }
384 383
385 /* 384 /*
386 * Enable scanline decoding for jpegs 385 * Enable scanline decoding for jpegs
387 */ 386 */
388 class SkJpegScanlineDecoder : public SkScanlineDecoder { 387 class SkJpegScanlineDecoder : public SkScanlineDecoder {
389 public: 388 public:
390 SkJpegScanlineDecoder(const SkImageInfo& srcInfo, SkJpegCodec* codec) 389 SkJpegScanlineDecoder(const SkImageInfo& srcInfo, SkJpegCodec* codec)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return result; 466 return result;
468 } 467 }
469 fStorage.reset(get_row_bytes(fCodec->fDecoderMgr->dinfo())); 468 fStorage.reset(get_row_bytes(fCodec->fDecoderMgr->dinfo()));
470 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 469 fSrcRow = static_cast<uint8_t*>(fStorage.get());
471 } else { 470 } else {
472 fSrcRow = nullptr; 471 fSrcRow = nullptr;
473 fSwizzler.reset(nullptr); 472 fSwizzler.reset(nullptr);
474 } 473 }
475 474
476 // Now, given valid output dimensions, we can start the decompress 475 // Now, given valid output dimensions, we can start the decompress
477 if (!chromium_jpeg_start_decompress(fCodec->fDecoderMgr->dinfo())) { 476 if (!jpeg_start_decompress(fCodec->fDecoderMgr->dinfo())) {
478 SkCodecPrintf("start decompress failed\n"); 477 SkCodecPrintf("start decompress failed\n");
479 return SkCodec::kInvalidInput; 478 return SkCodec::kInvalidInput;
480 } 479 }
481 480
482 fOpts = options; 481 fOpts = options;
483 482
484 return SkCodec::kSuccess; 483 return SkCodec::kSuccess;
485 } 484 }
486 485
487 virtual ~SkJpegScanlineDecoder() { 486 virtual ~SkJpegScanlineDecoder() {
488 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 487 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
489 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n"); 488 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
490 return; 489 return;
491 } 490 }
492 491
493 // We may not have decoded the entire image. Prevent libjpeg-turbo from failing on a 492 // We may not have decoded the entire image. Prevent libjpeg-turbo from failing on a
494 // partial decode. 493 // partial decode.
495 fCodec->fDecoderMgr->dinfo()->output_scanline = fCodec->getInfo().height (); 494 fCodec->fDecoderMgr->dinfo()->output_scanline = fCodec->getInfo().height ();
496 chromium_jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo()); 495 jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo());
497 } 496 }
498 497
499 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { 498 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de {
500 // Set the jump location for libjpeg errors 499 // Set the jump location for libjpeg errors
501 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 500 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
502 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali dInput); 501 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali dInput);
503 } 502 }
504 // Read rows one at a time 503 // Read rows one at a time
505 JSAMPLE* dstRow; 504 JSAMPLE* dstRow;
506 if (fSwizzler) { 505 if (fSwizzler) {
507 // write data to storage row, then sample using swizzler 506 // write data to storage row, then sample using swizzler
508 dstRow = fSrcRow; 507 dstRow = fSrcRow;
509 } else { 508 } else {
510 // write data directly to dst 509 // write data directly to dst
511 dstRow = (JSAMPLE*) dst; 510 dstRow = (JSAMPLE*) dst;
512 } 511 }
513 512
514 for (int y = 0; y < count; y++) { 513 for (int y = 0; y < count; y++) {
515 // Read row of the image 514 // Read row of the image
516 uint32_t rowsDecoded = 515 uint32_t rowsDecoded = jpeg_read_scanlines(fCodec->fDecoderMgr->dinf o(), &dstRow, 1);
517 chromium_jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), & dstRow, 1);
518 if (rowsDecoded != 1) { 516 if (rowsDecoded != 1) {
519 if (SkCodec::kNo_ZeroInitialized == fOpts.fZeroInitialized || 517 if (SkCodec::kNo_ZeroInitialized == fOpts.fZeroInitialized ||
520 kN32_SkColorType == this->dstInfo().colorType()) { 518 kN32_SkColorType == this->dstInfo().colorType()) {
521 SkSwizzler::Fill(dstRow, this->dstInfo(), rowBytes, 519 SkSwizzler::Fill(dstRow, this->dstInfo(), rowBytes,
522 count - y, SK_ColorBLACK, nullptr); 520 count - y, SK_ColorBLACK, nullptr);
523 } 521 }
524 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo(). height(); 522 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo(). height();
525 return SkCodec::kIncompleteInput; 523 return SkCodec::kIncompleteInput;
526 } 524 }
527 525
528 // Convert to RGBA if necessary 526 // Convert to RGBA if necessary
529 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { 527 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) {
530 convert_CMYK_to_RGBA(dstRow, fCodec->fDecoderMgr->dinfo()->outpu t_width); 528 convert_CMYK_to_RGBA(dstRow, fCodec->fDecoderMgr->dinfo()->outpu t_width);
531 } 529 }
532 530
533 if(fSwizzler) { 531 if(fSwizzler) {
534 // use swizzler to sample row 532 // use swizzler to sample row
535 fSwizzler->swizzle(dst, dstRow); 533 fSwizzler->swizzle(dst, dstRow);
536 dst = SkTAddOffset<JSAMPLE>(dst, rowBytes); 534 dst = SkTAddOffset<JSAMPLE>(dst, rowBytes);
537 } else { 535 } else {
538 dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes); 536 dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes);
539 } 537 }
540 } 538 }
541 return SkCodec::kSuccess; 539 return SkCodec::kSuccess;
542 } 540 }
543 541
544 #ifndef TURBO_HAS_SKIP 542 #ifndef TURBO_HAS_SKIP
545 // TODO (msarett): Make this a member function and avoid reallocating the 543 // TODO (msarett): Make this a member function and avoid reallocating the
546 // memory buffer on each call to skip. 544 // memory buffer on each call to skip.
547 #define chromium_jpeg_skip_scanlines(dinfo, count) \ 545 #define jpeg_skip_scanlines(dinfo, count) \
548 SkAutoMalloc storage(get_row_bytes(dinfo)); \ 546 SkAutoMalloc storage(get_row_bytes(dinfo)); \
549 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); \ 547 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); \
550 for (int y = 0; y < count; y++) { \ 548 for (int y = 0; y < count; y++) { \
551 chromium_jpeg_read_scanlines(dinfo, &storagePtr, 1); \ 549 jpeg_read_scanlines(dinfo, &storagePtr, 1); \
552 } 550 }
553 #endif 551 #endif
554 552
555 SkCodec::Result onSkipScanlines(int count) override { 553 SkCodec::Result onSkipScanlines(int count) override {
556 // Set the jump location for libjpeg errors 554 // Set the jump location for libjpeg errors
557 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 555 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
558 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali dInput); 556 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali dInput);
559 } 557 }
560 558
561 chromium_jpeg_skip_scanlines(fCodec->fDecoderMgr->dinfo(), count); 559 jpeg_skip_scanlines(fCodec->fDecoderMgr->dinfo(), count);
562 560
563 return SkCodec::kSuccess; 561 return SkCodec::kSuccess;
564 } 562 }
565 563
566 SkEncodedFormat onGetEncodedFormat() const override { 564 SkEncodedFormat onGetEncodedFormat() const override {
567 return kJPEG_SkEncodedFormat; 565 return kJPEG_SkEncodedFormat;
568 } 566 }
569 567
570 private: 568 private:
571 SkAutoTDelete<SkJpegCodec> fCodec; 569 SkAutoTDelete<SkJpegCodec> fCodec;
572 SkAutoMalloc fStorage; // Only used if sampling is needed 570 SkAutoMalloc fStorage; // Only used if sampling is needed
573 uint8_t* fSrcRow; // Only used if sampling is needed 571 uint8_t* fSrcRow; // Only used if sampling is needed
574 SkCodec::Options fOpts; 572 SkCodec::Options fOpts;
575 SkAutoTDelete<SkSwizzler> fSwizzler; 573 SkAutoTDelete<SkSwizzler> fSwizzler;
576 574
577 typedef SkScanlineDecoder INHERITED; 575 typedef SkScanlineDecoder INHERITED;
578 }; 576 };
579 577
580 SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) { 578 SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) {
581 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF romStream(stream))); 579 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF romStream(stream)));
582 if (!codec) { 580 if (!codec) {
583 return nullptr; 581 return nullptr;
584 } 582 }
585 583
586 const SkImageInfo& srcInfo = codec->getInfo(); 584 const SkImageInfo& srcInfo = codec->getInfo();
587 585
588 // Return the new scanline decoder 586 // Return the new scanline decoder
589 return new SkJpegScanlineDecoder(srcInfo, codec.detach()); 587 return new SkJpegScanlineDecoder(srcInfo, codec.detach());
590 } 588 }
OLDNEW
« no previous file with comments | « src/codec/SkJpegCodec.h ('k') | src/codec/SkJpegDecoderMgr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698