| OLD | NEW | 
|---|
| 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 "SkBmpRLECodec.h" | 8 #include "SkBmpRLECodec.h" | 
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" | 
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" | 
| 11 #include "SkStream.h" | 11 #include "SkStream.h" | 
| 12 | 12 | 
| 13 /* | 13 /* | 
| 14  * Creates an instance of the decoder | 14  * Creates an instance of the decoder | 
| 15  * Called only by NewFromStream | 15  * Called only by NewFromStream | 
| 16  */ | 16  */ | 
| 17 SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream, | 17 SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream, | 
| 18                              uint16_t bitsPerPixel, uint32_t numColors, | 18                              uint16_t bitsPerPixel, uint32_t numColors, | 
| 19                              uint32_t bytesPerColor, uint32_t offset, | 19                              uint32_t bytesPerColor, uint32_t offset, | 
| 20                              SkCodec::SkScanlineOrder rowOrder, | 20                              SkCodec::SkScanlineOrder rowOrder, | 
| 21                              size_t RLEBytes) | 21                              size_t RLEBytes) | 
| 22     : INHERITED(info, stream, bitsPerPixel, rowOrder) | 22     : INHERITED(info, stream, bitsPerPixel, rowOrder) | 
| 23     , fColorTable(nullptr) | 23     , fColorTable(nullptr) | 
| 24     , fNumColors(numColors) | 24     , fNumColors(numColors) | 
| 25     , fBytesPerColor(bytesPerColor) | 25     , fBytesPerColor(bytesPerColor) | 
| 26     , fOffset(offset) | 26     , fOffset(offset) | 
| 27     , fStreamBuffer(new uint8_t[RLEBytes]) | 27     , fStreamBuffer(new uint8_t[RLEBytes]) | 
| 28     , fRLEBytes(RLEBytes) | 28     , fRLEBytes(RLEBytes) | 
|  | 29     , fOrigRLEBytes(RLEBytes) | 
| 29     , fCurrRLEByte(0) | 30     , fCurrRLEByte(0) | 
| 30     , fSampleX(1) | 31     , fSampleX(1) | 
| 31 {} | 32 {} | 
| 32 | 33 | 
| 33 /* | 34 /* | 
| 34  * Initiates the bitmap decode | 35  * Initiates the bitmap decode | 
| 35  */ | 36  */ | 
| 36 SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, | 37 SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, | 
| 37                                            void* dst, size_t dstRowBytes, | 38                                            void* dst, size_t dstRowBytes, | 
| 38                                            const Options& opts, | 39                                            const Options& opts, | 
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 263         const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputCo
     lorCount) { | 264         const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputCo
     lorCount) { | 
| 264     // FIXME: Support subsets for scanline decodes. | 265     // FIXME: Support subsets for scanline decodes. | 
| 265     if (options.fSubset) { | 266     if (options.fSubset) { | 
| 266         // Subsets are not supported. | 267         // Subsets are not supported. | 
| 267         return kUnimplemented; | 268         return kUnimplemented; | 
| 268     } | 269     } | 
| 269 | 270 | 
| 270     // Reset fSampleX. If it needs to be a value other than 1, it will get modif
     ied by | 271     // Reset fSampleX. If it needs to be a value other than 1, it will get modif
     ied by | 
| 271     // the sampler. | 272     // the sampler. | 
| 272     fSampleX = 1; | 273     fSampleX = 1; | 
|  | 274     fLinesToSkip = 0; | 
|  | 275 | 
| 273     // Create the color table if necessary and prepare the stream for decode | 276     // Create the color table if necessary and prepare the stream for decode | 
| 274     // Note that if it is non-NULL, inputColorCount will be modified | 277     // Note that if it is non-NULL, inputColorCount will be modified | 
| 275     if (!this->createColorTable(inputColorCount)) { | 278     if (!this->createColorTable(inputColorCount)) { | 
| 276         SkCodecPrintf("Error: could not create color table.\n"); | 279         SkCodecPrintf("Error: could not create color table.\n"); | 
| 277         return SkCodec::kInvalidInput; | 280         return SkCodec::kInvalidInput; | 
| 278     } | 281     } | 
| 279 | 282 | 
| 280     // Copy the color table to the client if necessary | 283     // Copy the color table to the client if necessary | 
| 281     copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount)
     ; | 284     copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount)
     ; | 
| 282 | 285 | 
| 283     // Initialize a buffer for encoded RLE data | 286     // Initialize a buffer for encoded RLE data | 
|  | 287     fRLEBytes = fOrigRLEBytes; | 
| 284     if (!this->initializeStreamBuffer()) { | 288     if (!this->initializeStreamBuffer()) { | 
| 285         SkCodecPrintf("Error: cannot initialize stream buffer.\n"); | 289         SkCodecPrintf("Error: cannot initialize stream buffer.\n"); | 
| 286         return SkCodec::kInvalidConversion; | 290         return SkCodec::kInvalidConversion; | 
| 287     } | 291     } | 
| 288 | 292 | 
| 289     return SkCodec::kSuccess; | 293     return SkCodec::kSuccess; | 
| 290 } | 294 } | 
| 291 | 295 | 
| 292 /* | 296 /* | 
| 293  * Performs the bitmap decoding for RLE input format | 297  * Performs the bitmap decoding for RLE input format | 
| 294  * RLE decoding is performed all at once, rather than a one row at a time | 298  * RLE decoding is performed all at once, rather than a one row at a time | 
| 295  */ | 299  */ | 
| 296 int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
     ytes, | 300 int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
     ytes, | 
| 297         const Options& opts) { | 301         const Options& opts) { | 
| 298     // Set RLE flags | 302     // Set RLE flags | 
| 299     static const uint8_t RLE_ESCAPE = 0; | 303     static const uint8_t RLE_ESCAPE = 0; | 
| 300     static const uint8_t RLE_EOL = 0; | 304     static const uint8_t RLE_EOL = 0; | 
| 301     static const uint8_t RLE_EOF = 1; | 305     static const uint8_t RLE_EOF = 1; | 
| 302     static const uint8_t RLE_DELTA = 2; | 306     static const uint8_t RLE_DELTA = 2; | 
| 303 | 307 | 
| 304     // Set constant values |  | 
| 305     const int width = this->getInfo().width(); | 308     const int width = this->getInfo().width(); | 
| 306     const int height = info.height(); | 309     int height = info.height(); | 
| 307 | 310 | 
| 308     // Account for sampling. | 311     // Account for sampling. | 
| 309     SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), hei
     ght); | 312     SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), hei
     ght); | 
| 310 | 313 | 
| 311     // Destination parameters |  | 
| 312     int x = 0; |  | 
| 313     int y = 0; |  | 
| 314 |  | 
| 315     // Set the background as transparent.  Then, if the RLE code skips pixels, | 314     // Set the background as transparent.  Then, if the RLE code skips pixels, | 
| 316     // the skipped pixels will be transparent. | 315     // the skipped pixels will be transparent. | 
| 317     // Because of the need for transparent pixels, kN32 is the only color | 316     // Because of the need for transparent pixels, kN32 is the only color | 
| 318     // type that makes sense for the destination format. | 317     // type that makes sense for the destination format. | 
| 319     SkASSERT(kN32_SkColorType == dstInfo.colorType()); | 318     SkASSERT(kN32_SkColorType == dstInfo.colorType()); | 
| 320     SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroIn
     itialized); | 319     SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroIn
     itialized); | 
| 321 | 320 | 
|  | 321     // Adjust the height and the dst if the previous call to decodeRows() left u
     s | 
|  | 322     // with lines that need to be skipped. | 
|  | 323     if (height > fLinesToSkip) { | 
|  | 324         height -= fLinesToSkip; | 
|  | 325         dst = SkTAddOffset<void>(dst, fLinesToSkip * dstRowBytes); | 
|  | 326         fLinesToSkip = 0; | 
|  | 327     } else { | 
|  | 328         fLinesToSkip -= height; | 
|  | 329         return height; | 
|  | 330     } | 
|  | 331 | 
|  | 332     // Destination parameters | 
|  | 333     int x = 0; | 
|  | 334     int y = 0; | 
|  | 335 | 
| 322     while (true) { | 336     while (true) { | 
| 323         // If we have reached a row that is beyond the requested height, we have | 337         // If we have reached a row that is beyond the requested height, we have | 
| 324         // succeeded. | 338         // succeeded. | 
| 325         if (y >= height) { | 339         if (y >= height) { | 
| 326             // It would be better to check for the EOF marker before indicating | 340             // It would be better to check for the EOF marker before indicating | 
| 327             // success, but we may be performing a scanline decode, which | 341             // success, but we may be performing a scanline decode, which | 
| 328             // would require us to stop before decoding the full height. | 342             // would require us to stop before decoding the full height. | 
| 329             return height; | 343             return height; | 
| 330         } | 344         } | 
| 331 | 345 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 359                         SkCodecPrintf("Warning: might be incomplete RLE input.\n
     "); | 373                         SkCodecPrintf("Warning: might be incomplete RLE input.\n
     "); | 
| 360                         if (this->checkForMoreData() < 2) { | 374                         if (this->checkForMoreData() < 2) { | 
| 361                             return y; | 375                             return y; | 
| 362                         } | 376                         } | 
| 363                     } | 377                     } | 
| 364                     // Modify x and y | 378                     // Modify x and y | 
| 365                     const uint8_t dx = fStreamBuffer.get()[fCurrRLEByte++]; | 379                     const uint8_t dx = fStreamBuffer.get()[fCurrRLEByte++]; | 
| 366                     const uint8_t dy = fStreamBuffer.get()[fCurrRLEByte++]; | 380                     const uint8_t dy = fStreamBuffer.get()[fCurrRLEByte++]; | 
| 367                     x += dx; | 381                     x += dx; | 
| 368                     y += dy; | 382                     y += dy; | 
| 369                     if (x > width || y > height) { | 383                     if (x > width) { | 
| 370                         SkCodecPrintf("Warning: invalid RLE input.\n"); | 384                         SkCodecPrintf("Warning: invalid RLE input.\n"); | 
| 371                         return y - dy; | 385                         return y - dy; | 
|  | 386                     } else if (y > height) { | 
|  | 387                         fLinesToSkip = y - height; | 
|  | 388                         return height; | 
| 372                     } | 389                     } | 
| 373                     break; | 390                     break; | 
| 374                 } | 391                 } | 
| 375                 default: { | 392                 default: { | 
| 376                     // If task does not match any of the above signals, it | 393                     // If task does not match any of the above signals, it | 
| 377                     // indicates that we have a sequence of non-RLE pixels. | 394                     // indicates that we have a sequence of non-RLE pixels. | 
| 378                     // Furthermore, the value of task is equal to the number | 395                     // Furthermore, the value of task is equal to the number | 
| 379                     // of pixels to interpret. | 396                     // of pixels to interpret. | 
| 380                     uint8_t numPixels = task; | 397                     uint8_t numPixels = task; | 
| 381                     const size_t rowBytes = compute_row_bytes(numPixels, | 398                     const size_t rowBytes = compute_row_bytes(numPixels, | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 508         fSampler.reset(new SkBmpRLESampler(this)); | 525         fSampler.reset(new SkBmpRLESampler(this)); | 
| 509     } | 526     } | 
| 510 | 527 | 
| 511     return fSampler; | 528     return fSampler; | 
| 512 } | 529 } | 
| 513 | 530 | 
| 514 int SkBmpRLECodec::setSampleX(int sampleX){ | 531 int SkBmpRLECodec::setSampleX(int sampleX){ | 
| 515     fSampleX = sampleX; | 532     fSampleX = sampleX; | 
| 516     return get_scaled_dimension(this->getInfo().width(), sampleX); | 533     return get_scaled_dimension(this->getInfo().width(), sampleX); | 
| 517 } | 534 } | 
| OLD | NEW | 
|---|