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 "SkCodec.h" 9 #include "SkJpegCodec.h" 10 #include "SkJpegDecoderMgr.h" 11 #include "SkJpegUtility.h" 12 #include "SkCodecPriv.h" 13 #include "SkColorPriv.h" 14 #include "SkStream.h" 15 #include "SkTemplates.h" 16 #include "SkTypes.h" 17 18 // stdio is needed for jpeglib 19 #include <stdio.h> 20 21 extern "C" { 22 #include "jerror.h" 23 #include "jmorecfg.h" 24 #include "jpegint.h" 25 #include "jpeglib.h" 26 } 27 28 // ANDROID_RGB 29 // If this is defined in the jpeg headers it indicates that jpeg offers 30 // support for two additional formats: JCS_RGBA_8888 and JCS_RGB_565. 31 32 /* 33 * Get the source configuarion for the swizzler 34 */ 35 SkSwizzler::SrcConfig get_src_config(const jpeg_decompress_struct& dinfo) { 36 if (JCS_CMYK == dinfo.out_color_space) { 37 // We will need to perform a manual conversion 38 return SkSwizzler::kRGBX; 39 } 40 if (3 == dinfo.out_color_components && JCS_RGB == dinfo.out_color_space) { 41 return SkSwizzler::kRGB; 42 } 43 #ifdef ANDROID_RGB 44 if (JCS_RGBA_8888 == dinfo.out_color_space) { 45 return SkSwizzler::kRGBX; 46 } 47 48 if (JCS_RGB_565 == dinfo.out_color_space) { 49 return SkSwizzler::kRGB_565; 50 } 51 #endif 52 if (1 == dinfo.out_color_components && JCS_GRAYSCALE == dinfo.out_color_space) { 53 return SkSwizzler::kGray; 54 } 55 return SkSwizzler::kUnknown; 56 } 57 58 /* 59 * Convert a row of CMYK samples to RGBX in place. 60 * Note that this method moves the row pointer. 61 * @param width the number of pixels in the row that is being converted 62 * CMYK is stored as four bytes per pixel 63 */ 64 static void convert_CMYK_to_RGB(uint8_t* row, uint32_t width) { 65 // We will implement a crude conversion from CMYK -> RGB using formulas 66 // from easyrgb.com. 67 // 68 // CMYK -> CMY 69 // C = C * (1 - K) + K 70 // M = M * (1 - K) + K 71 // Y = Y * (1 - K) + K 72 // 73 // libjpeg actually gives us inverted CMYK, so we must subtract the 74 // original terms from 1. 75 // CMYK -> CMY 76 // C = (1 - C) * (1 - (1 - K)) + (1 - K) 77 // M = (1 - M) * (1 - (1 - K)) + (1 - K) 78 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K) 79 // 80 // Simplifying the above expression. 81 // CMYK -> CMY 82 // C = 1 - CK 83 // M = 1 - MK 84 // Y = 1 - YK 85 // 86 // CMY -> RGB 87 // R = (1 - C) * 255 88 // G = (1 - M) * 255 89 // B = (1 - Y) * 255 90 // 91 // Therefore the full conversion is below. This can be verified at 92 // www.rapidtables.com (assuming inverted CMYK). 93 // CMYK -> RGB 94 // R = C * K * 255 95 // G = M * K * 255 96 // B = Y * K * 255 97 // 98 // As a final note, we have treated the CMYK values as if they were on 99 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255. 100 // We must divide each CMYK component by 255 to obtain the true conversion 101 // we should perform. 102 // CMYK -> RGB 103 // R = C * K / 255 104 // G = M * K / 255 105 // B = Y * K / 255 106 for (uint32_t x = 0; x < width; x++, row += 4) { 107 row[0] = SkMulDiv255Round(row[0], row[3]); 108 row[1] = SkMulDiv255Round(row[1], row[3]); 109 row[2] = SkMulDiv255Round(row[2], row[3]); 110 row[3] = 0xFF; 111 } 112 } 113 114 bool SkJpegCodec::IsJpeg(SkStream* stream) { 115 static const uint8_t jpegSig[] = { 0xFF, 0xD8, 0xFF }; 116 char buffer[sizeof(jpegSig)]; 117 return stream->read(buffer, sizeof(jpegSig)) == sizeof(jpegSig) && 118 !memcmp(buffer, jpegSig, sizeof(jpegSig)); 119 } 120 121 bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, 122 JpegDecoderMgr** decoderMgrOut) { 123 124 // Create a JpegDecoderMgr to own all of the decompress information 125 SkAutoTDelete<JpegDecoderMgr> decoderMgr(SkNEW_ARGS(JpegDecoderMgr, (stream))); 126 127 // libjpeg errors will be caught and reported here 128 if (setjmp(decoderMgr->getJmpBuf())) { 129 return decoderMgr->returnFalse("setjmp"); 130 } 131 132 // Initialize the decompress info and the source manager 133 decoderMgr->init(); 134 135 // Read the jpeg header 136 if (JPEG_HEADER_OK != jpeg_read_header(decoderMgr->dinfo(), true)) { 137 return decoderMgr->returnFalse("read_header"); 138 } 139 140 if (NULL != codecOut) { 141 // Recommend the color type to decode to 142 const SkColorType colorType = decoderMgr->getColorType(); 143 144 // Create image info object and the codec 145 const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->image_width, 146 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaType); 147 *codecOut = SkNEW_ARGS(SkJpegCodec, (imageInfo, stream, decoderMgr.detach())); 148 } else { 149 SkASSERT(NULL != decoderMgrOut); 150 *decoderMgrOut = decoderMgr.detach(); 151 } 152 return true; 153 } 154 155 SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) { 156 SkAutoTDelete<SkStream> streamDeleter(stream); 157 SkCodec* codec = NULL; 158 if (ReadHeader(stream, &codec, NULL)) { 159 // Codec has taken ownership of the stream, we do not need to delete it 160 SkASSERT(codec); 161 streamDeleter.detach(); 162 return codec; 163 } 164 return NULL; 165 } 166 167 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, 168 JpegDecoderMgr* decoderMgr) 169 : INHERITED(srcInfo, stream) 170 , fDecoderMgr(decoderMgr) 171 , fSwizzler(NULL) 172 , fSrcRowBytes(0) 173 {} 174 175 /* 176 * Return a valid set of output dimensions for this decoder, given an input scale 177 */ 178 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { 179 // libjpeg supports scaling by 1/1, 1/2, 1/4, and 1/8, so we will support these as well 180 long scale; 181 if (desiredScale > 0.75f) { 182 scale = 1; 183 } else if (desiredScale > 0.375f) { 184 scale = 2; 185 } else if (desiredScale > 0.1875f) { 186 scale = 4; 187 } else { 188 scale = 8; 189 } 190 191 // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions 192 jpeg_decompress_struct dinfo; 193 sk_bzero(&dinfo, sizeof(dinfo)); 194 dinfo.image_width = this->getInfo().width(); 195 dinfo.image_height = this->getInfo().height(); 196 dinfo.global_state = DSTATE_READY; 197 dinfo.num_components = 0; 198 dinfo.scale_num = 1; 199 dinfo.scale_denom = scale; 200 jpeg_calc_output_dimensions(&dinfo); 201 202 // Return the calculated output dimensions for the given scale 203 return SkISize::Make(dinfo.output_width, dinfo.output_height); 204 } 205 206 /* 207 * Checks if the conversion between the input image and the requested output 208 * image has been implemented 209 */ 210 static bool conversion_possible(const SkImageInfo& dst, 211 const SkImageInfo& src) { 212 // Ensure that the profile type is unchanged 213 if (dst.profileType() != src.profileType()) { 214 return false; 215 } 216 217 // Ensure that the alpha type is opaque 218 if (kOpaque_SkAlphaType != dst.alphaType()) { 219 return false; 220 } 221 222 // Always allow kN32 as the color type 223 if (kN32_SkColorType == dst.colorType()) { 224 return true; 225 } 226 227 // Otherwise require that the destination color type match our recommendation 228 return dst.colorType() == src.colorType(); 229 } 230 231 /* 232 * Handles rewinding the input stream if it is necessary 233 */ 234 bool SkJpegCodec::handleRewind() { 235 switch(this->rewindIfNeeded()) { 236 case kCouldNotRewind_RewindState: 237 return fDecoderMgr->returnFalse("could not rewind"); 238 case kRewound_RewindState: { 239 JpegDecoderMgr* decoderMgr = NULL; 240 if (!ReadHeader(this->stream(), NULL, &decoderMgr)) { 241 return fDecoderMgr->returnFalse("could not rewind"); 242 } 243 SkASSERT(NULL != decoderMgr); 244 fDecoderMgr.reset(decoderMgr); 245 return true; 246 } 247 case kNoRewindNecessary_RewindState: 248 return true; 249 default: 250 SkASSERT(false); 251 return false; 252 } 253 } 254 255 /* 256 * Checks if we can scale to the requested dimensions and scales the dimensions 257 * if possible 258 */ 259 bool SkJpegCodec::scaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) { 260 // libjpeg can scale to 1/1, 1/2, 1/4, and 1/8 261 SkASSERT(1 == fDecoderMgr->dinfo()->scale_num); 262 SkASSERT(1 == fDecoderMgr->dinfo()->scale_denom); 263 jpeg_calc_output_dimensions(fDecoderMgr->dinfo()); 264 while (fDecoderMgr->dinfo()->output_width != dstWidth || 265 fDecoderMgr->dinfo()->output_height != dstHeight) { 266 267 // Return a failure if we have tried all of the possible scales 268 if (8 == fDecoderMgr->dinfo()->scale_denom || 269 dstWidth > fDecoderMgr->dinfo()->output_width || 270 dstHeight > fDecoderMgr->dinfo()->output_height) { 271 return fDecoderMgr->returnFalse("could not scale to requested dimensions"); 272 } 273 274 // Try the next scale 275 fDecoderMgr->dinfo()->scale_denom *= 2; 276 jpeg_calc_output_dimensions(fDecoderMgr->dinfo()); 277 } 278 return true; 279 } 280 281 /* 282 * Create the swizzler based on the encoded format 283 */ 284 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, 285 void* dst, size_t dstRowBytes, 286 const Options& options) { 287 SkSwizzler::SrcConfig srcConfig = get_src_config(*fDecoderMgr->dinfo()); 288 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, NULL, dstInfo, dst, dstRowBytes, 289 options.fZeroInitialized)); 290 fSrcRowBytes = SkSwizzler::BytesPerPixel(srcConfig) * dstInfo.width(); 291 } 292 293 /* 294 * Performs the jpeg decode 295 */ 296 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, 297 void* dst, size_t dstRowBytes, 298 const Options& options, SkPMColor*, int*) { 299 300 // Rewind the stream if needed 301 if (!this->handleRewind()) { 302 fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRewind); 303 } 304 305 // Get a pointer to the decompress info since we will use it quite frequently 306 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo(); 307 308 // Set the jump location for libjpeg errors 309 if (setjmp(fDecoderMgr->getJmpBuf())) { 310 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); 311 } 312 313 // Check if we can decode to the requested destination 314 if (!conversion_possible(dstInfo, this->getInfo())) { 315 return fDecoderMgr->returnFailure("conversion_possible", kInvalidConversion); 316 } 317 318 // Perform the necessary scaling 319 if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) { 320 fDecoderMgr->returnFailure("cannot scale to requested dims", kInvalidScale); 321 } 322 323 // Now, given valid output dimensions, we can start the decompress 324 if (!jpeg_start_decompress(dinfo)) { 325 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput); 326 } 327 328 // Create the swizzler 329 this->initializeSwizzler(dstInfo, dst, dstRowBytes, options); 330 if (NULL == fSwizzler) { 331 return fDecoderMgr->returnFailure("getSwizzler", kUnimplemented); 332 } 333 334 // This is usually 1, but can also be 2 or 4. 335 // If we wanted to always read one row at a time, we could, but we will save space and time 336 // by using the recommendation from libjpeg. 337 const uint32_t rowsPerDecode = dinfo->rec_outbuf_height; 338 SkASSERT(rowsPerDecode <= 4); 339 340 // Create a buffer to contain decoded rows (libjpeg requires a 2D array) 341 SkASSERT(0 != fSrcRowBytes); 342 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, fSrcRowBytes * rowsPerDecode)); 343 JSAMPLE* srcRows[4]; 344 uint8_t* srcPtr = srcBuffer.get(); 345 for (uint8_t i = 0; i < rowsPerDecode; i++) { 346 srcRows[i] = (JSAMPLE*) srcPtr; 347 srcPtr += fSrcRowBytes; 348 } 349 350 // Ensure that we loop enough times to decode all of the rows 351 // libjpeg will prevent us from reading past the bottom of the image 352 uint32_t dstHeight = dstInfo.height(); 353 for (uint32_t y = 0; y < dstHeight + rowsPerDecode - 1; y += rowsPerDecode) { 354 // Read rows of the image 355 uint32_t rowsDecoded = jpeg_read_scanlines(dinfo, srcRows, rowsPerDecode); 356 357 // Convert to RGB if necessary 358 if (JCS_CMYK == dinfo->out_color_space) { 359 convert_CMYK_to_RGB(srcRows[0], dstInfo.width() * rowsDecoded); 360 } 361 362 // Swizzle to output destination 363 for (uint32_t i = 0; i < rowsDecoded; i++) { 364 fSwizzler->next(srcRows[i]); 365 } 366 367 // If we cannot read enough rows, assume the input is incomplete 368 if (rowsDecoded < rowsPerDecode && y + rowsDecoded < dstHeight) { 369 // Fill the remainder of the image with black. This error handling 370 // behavior is unspecified but SkCodec consistently uses black as 371 // the fill color for opaque images. If the destination is kGray, 372 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, 373 // these are zeros, which is the representation for black in kGray. 374 SkSwizzler::Fill(fSwizzler->getDstRow(), dstInfo, dstRowBytes, 375 dstHeight - y - rowsDecoded, SK_ColorBLACK, NULL); 376 377 // Prevent libjpeg from failing on incomplete decode 378 dinfo->output_scanline = dstHeight; 379 380 // Finish the decode and indicate that the input was incomplete. 381 jpeg_finish_decompress(dinfo); 382 return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput); 383 } 384 } 385 jpeg_finish_decompress(dinfo); 386 387 return kSuccess; 388 } 389 390 /* 391 * Enable scanline decoding for jpegs 392 */ 393 class SkJpegScanlineDecoder : public SkScanlineDecoder { 394 public: 395 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec) 396 : INHERITED(dstInfo) 397 , fCodec(codec) 398 { 399 fStorage.reset(fCodec->fSrcRowBytes); 400 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 401 } 402 403 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t rowBytes) override { 404 // Set the jump location for libjpeg errors 405 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 406 return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator::kInvalidInput); 407 } 408 409 // Read rows one at a time 410 for (int y = 0; y < count; y++) { 411 // Read row of the image 412 uint32_t rowsDecoded = jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1); 413 if (rowsDecoded != 1) { 414 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count - y, SK_ColorBLACK, NULL); 415 return SkImageGenerator::kIncompleteInput; 416 } 417 418 // Convert to RGB if necessary 419 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { 420 convert_CMYK_to_RGB(fSrcRow, dstInfo().width()); 421 } 422 423 // Swizzle to output destination 424 fCodec->fSwizzler->setDstRow(dst); 425 fCodec->fSwizzler->next(fSrcRow); 426 dst = SkTAddOffset<void>(dst, rowBytes); 427 } 428 429 return SkImageGenerator::kSuccess; 430 } 431 432 SkImageGenerator::Result onSkipScanlines(int count) override { 433 // Set the jump location for libjpeg errors 434 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 435 return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator::kInvalidInput); 436 } 437 438 // Read rows but ignore the output 439 for (int y = 0; y < count; y++) { 440 jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1); 441 } 442 443 return SkImageGenerator::kSuccess; 444 } 445 446 void onFinish() override { 447 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { 448 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n"); 449 return; 450 } 451 452 jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo()); 453 } 454 455 private: 456 SkJpegCodec* fCodec; // unowned 457 SkAutoMalloc fStorage; 458 uint8_t* fSrcRow; // ptr into fStorage 459 460 typedef SkScanlineDecoder INHERITED; 461 }; 462 463 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 464 const Options& options, SkPMColor ctable[], int* ctableCount) { 465 466 // Rewind the stream if needed 467 if (!this->handleRewind()) { 468 SkCodecPrintf("Could not rewind\n"); 469 return NULL; 470 } 471 472 // Set the jump location for libjpeg errors 473 if (setjmp(fDecoderMgr->getJmpBuf())) { 474 SkCodecPrintf("setjmp: Error from libjpeg\n"); 475 return NULL; 476 } 477 478 // Check if we can decode to the requested destination 479 if (!conversion_possible(dstInfo, this->getInfo())) { 480 SkCodecPrintf("Cannot convert to output type\n"); 481 return NULL; 482 } 483 484 // Perform the necessary scaling 485 if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) { 486 SkCodecPrintf("Cannot scale ot output dimensions\n"); 487 return NULL; 488 } 489 490 // Now, given valid output dimensions, we can start the decompress 491 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { 492 SkCodecPrintf("start decompress failed\n"); 493 return NULL; 494 } 495 496 // Create the swizzler 497 this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options); 498 if (NULL == fSwizzler) { 499 SkCodecPrintf("Could not create swizzler\n"); 500 return NULL; 501 } 502 503 // Return the new scanline decoder 504 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this)); 505 } 506