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 "SkBmpRLECodec.h"
9#include "SkCodecPriv.h"
10#include "SkColorPriv.h"
11#include "SkStream.h"
12
13/*
14 * Creates an instance of the decoder
15 * Called only by NewFromStream
16 */
17SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream,
18                             uint16_t bitsPerPixel, uint32_t numColors,
19                             uint32_t bytesPerColor, uint32_t offset,
20                             SkCodec::SkScanlineOrder rowOrder)
21    : INHERITED(info, stream, bitsPerPixel, rowOrder)
22    , fColorTable(nullptr)
23    , fNumColors(numColors)
24    , fBytesPerColor(bytesPerColor)
25    , fOffset(offset)
26    , fBytesBuffered(0)
27    , fCurrRLEByte(0)
28    , fSampleX(1)
29{}
30
31/*
32 * Initiates the bitmap decode
33 */
34SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
35                                           void* dst, size_t dstRowBytes,
36                                           const Options& opts,
37                                           SkPMColor* inputColorPtr,
38                                           int* inputColorCount,
39                                           int* rowsDecoded) {
40    if (opts.fSubset) {
41        // Subsets are not supported.
42        return kUnimplemented;
43    }
44    if (!conversion_possible(dstInfo, this->getInfo())) {
45        SkCodecPrintf("Error: cannot convert input type to output type.\n");
46        return kInvalidConversion;
47    }
48
49    Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
50    if (kSuccess != result) {
51        return result;
52    }
53
54    // Perform the decode
55    int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
56    if (rows != dstInfo.height()) {
57        // We set rowsDecoded equal to the height because the background has already
58        // been filled.  RLE encodings sometimes skip pixels, so we always start by
59        // filling the background.
60        *rowsDecoded = dstInfo.height();
61        return kIncompleteInput;
62    }
63
64    return kSuccess;
65}
66
67/*
68 * Process the color table for the bmp input
69 */
70 bool SkBmpRLECodec::createColorTable(int* numColors) {
71    // Allocate memory for color table
72    uint32_t colorBytes = 0;
73    SkPMColor colorTable[256];
74    if (this->bitsPerPixel() <= 8) {
75        // Inform the caller of the number of colors
76        uint32_t maxColors = 1 << this->bitsPerPixel();
77        if (nullptr != numColors) {
78            // We set the number of colors to maxColors in order to ensure
79            // safe memory accesses.  Otherwise, an invalid pixel could
80            // access memory outside of our color table array.
81            *numColors = maxColors;
82        }
83        // Don't bother reading more than maxColors.
84        const uint32_t numColorsToRead =
85            fNumColors == 0 ? maxColors : SkTMin(fNumColors, maxColors);
86
87        // Read the color table from the stream
88        colorBytes = numColorsToRead * fBytesPerColor;
89        SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]);
90        if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
91            SkCodecPrintf("Error: unable to read color table.\n");
92            return false;
93        }
94
95        // Fill in the color table
96        uint32_t i = 0;
97        for (; i < numColorsToRead; i++) {
98            uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
99            uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
100            uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
101            colorTable[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
102        }
103
104        // To avoid segmentation faults on bad pixel data, fill the end of the
105        // color table with black.  This is the same the behavior as the
106        // chromium decoder.
107        for (; i < maxColors; i++) {
108            colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
109        }
110
111        // Set the color table
112        fColorTable.reset(new SkColorTable(colorTable, maxColors));
113    }
114
115    // Check that we have not read past the pixel array offset
116    if(fOffset < colorBytes) {
117        // This may occur on OS 2.1 and other old versions where the color
118        // table defaults to max size, and the bmp tries to use a smaller
119        // color table.  This is invalid, and our decision is to indicate
120        // an error, rather than try to guess the intended size of the
121        // color table.
122        SkCodecPrintf("Error: pixel data offset less than color table size.\n");
123        return false;
124    }
125
126    // After reading the color table, skip to the start of the pixel array
127    if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
128        SkCodecPrintf("Error: unable to skip to image data.\n");
129        return false;
130    }
131
132    // Return true on success
133    return true;
134}
135
136bool SkBmpRLECodec::initializeStreamBuffer() {
137    fBytesBuffered = this->stream()->read(fStreamBuffer, kBufferSize);
138    if (fBytesBuffered == 0) {
139        SkCodecPrintf("Error: could not read RLE image data.\n");
140        return false;
141    }
142    fCurrRLEByte = 0;
143    return true;
144}
145
146/*
147 * @return the number of bytes remaining in the stream buffer after
148 *         attempting to read more bytes from the stream
149 */
150size_t SkBmpRLECodec::checkForMoreData() {
151    const size_t remainingBytes = fBytesBuffered - fCurrRLEByte;
152    uint8_t* buffer = fStreamBuffer;
153
154    // We will be reusing the same buffer, starting over from the beginning.
155    // Move any remaining bytes to the start of the buffer.
156    // We use memmove() instead of memcpy() because there is risk that the dst
157    // and src memory will overlap in corrupt images.
158    memmove(buffer, SkTAddOffset<uint8_t>(buffer, fCurrRLEByte), remainingBytes);
159
160    // Adjust the buffer ptr to the start of the unfilled data.
161    buffer += remainingBytes;
162
163    // Try to read additional bytes from the stream.  There are fCurrRLEByte
164    // bytes of additional space remaining in the buffer, assuming that we
165    // have already copied remainingBytes to the start of the buffer.
166    size_t additionalBytes = this->stream()->read(buffer, fCurrRLEByte);
167
168    // Update counters and return the number of bytes we currently have
169    // available.  We are at the start of the buffer again.
170    fCurrRLEByte = 0;
171    fBytesBuffered = remainingBytes + additionalBytes;
172    return fBytesBuffered;
173}
174
175/*
176 * Set an RLE pixel using the color table
177 */
178void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes,
179                             const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
180                             uint8_t index) {
181    if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
182        // Set the row
183        uint32_t row = this->getDstRow(y, dstInfo.height());
184
185        // Set the pixel based on destination color type
186        const int dstX = get_dst_coord(x, fSampleX);
187        switch (dstInfo.colorType()) {
188            case kN32_SkColorType: {
189                SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes);
190                dstRow[dstX] = fColorTable->operator[](index);
191                break;
192            }
193            case kRGB_565_SkColorType: {
194                uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
195                dstRow[dstX] = SkPixel32ToPixel16(fColorTable->operator[](index));
196                break;
197            }
198            default:
199                // This case should not be reached.  We should catch an invalid
200                // color type when we check that the conversion is possible.
201                SkASSERT(false);
202                break;
203        }
204    }
205}
206
207/*
208 * Set an RLE pixel from R, G, B values
209 */
210void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
211                                const SkImageInfo& dstInfo, uint32_t x,
212                                uint32_t y, uint8_t red, uint8_t green,
213                                uint8_t blue) {
214    if (dst && is_coord_necessary(x, fSampleX, dstInfo.width())) {
215        // Set the row
216        uint32_t row = this->getDstRow(y, dstInfo.height());
217
218        // Set the pixel based on destination color type
219        const int dstX = get_dst_coord(x, fSampleX);
220        switch (dstInfo.colorType()) {
221            case kN32_SkColorType: {
222                SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes);
223                dstRow[dstX] = SkPackARGB32NoCheck(0xFF, red, green, blue);
224                break;
225            }
226            case kRGB_565_SkColorType: {
227                uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
228                dstRow[dstX] = SkPack888ToRGB16(red, green, blue);
229                break;
230            }
231            default:
232                // This case should not be reached.  We should catch an invalid
233                // color type when we check that the conversion is possible.
234                SkASSERT(false);
235                break;
236        }
237    }
238}
239
240SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo,
241        const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
242    // FIXME: Support subsets for scanline decodes.
243    if (options.fSubset) {
244        // Subsets are not supported.
245        return kUnimplemented;
246    }
247
248    // Reset fSampleX. If it needs to be a value other than 1, it will get modified by
249    // the sampler.
250    fSampleX = 1;
251    fLinesToSkip = 0;
252
253    // Create the color table if necessary and prepare the stream for decode
254    // Note that if it is non-NULL, inputColorCount will be modified
255    if (!this->createColorTable(inputColorCount)) {
256        SkCodecPrintf("Error: could not create color table.\n");
257        return SkCodec::kInvalidInput;
258    }
259
260    // Copy the color table to the client if necessary
261    copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount);
262
263    // Initialize a buffer for encoded RLE data
264    if (!this->initializeStreamBuffer()) {
265        SkCodecPrintf("Error: cannot initialize stream buffer.\n");
266        return SkCodec::kInvalidInput;
267    }
268
269    return SkCodec::kSuccess;
270}
271
272/*
273 * Performs the bitmap decoding for RLE input format
274 * RLE decoding is performed all at once, rather than a one row at a time
275 */
276int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowBytes,
277        const Options& opts) {
278    // Set RLE flags
279    static const uint8_t RLE_ESCAPE = 0;
280    static const uint8_t RLE_EOL = 0;
281    static const uint8_t RLE_EOF = 1;
282    static const uint8_t RLE_DELTA = 2;
283
284    const int width = this->getInfo().width();
285    int height = info.height();
286
287    // Account for sampling.
288    SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), height);
289
290    // Set the background as transparent.  Then, if the RLE code skips pixels,
291    // the skipped pixels will be transparent.
292    // Because of the need for transparent pixels, kN32 is the only color
293    // type that makes sense for the destination format.
294    SkASSERT(kN32_SkColorType == dstInfo.colorType());
295    if (dst) {
296        SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
297    }
298
299    // Adjust the height and the dst if the previous call to decodeRows() left us
300    // with lines that need to be skipped.
301    if (height > fLinesToSkip) {
302        height -= fLinesToSkip;
303        dst = SkTAddOffset<void>(dst, fLinesToSkip * dstRowBytes);
304        fLinesToSkip = 0;
305    } else {
306        fLinesToSkip -= height;
307        return height;
308    }
309
310    // Destination parameters
311    int x = 0;
312    int y = 0;
313
314    while (true) {
315        // If we have reached a row that is beyond the requested height, we have
316        // succeeded.
317        if (y >= height) {
318            // It would be better to check for the EOF marker before indicating
319            // success, but we may be performing a scanline decode, which
320            // would require us to stop before decoding the full height.
321            return height;
322        }
323
324        // Every entry takes at least two bytes
325        if ((int) fBytesBuffered - fCurrRLEByte < 2) {
326            if (this->checkForMoreData() < 2) {
327                return y;
328            }
329        }
330
331        // Read the next two bytes.  These bytes have different meanings
332        // depending on their values.  In the first interpretation, the first
333        // byte is an escape flag and the second byte indicates what special
334        // task to perform.
335        const uint8_t flag = fStreamBuffer[fCurrRLEByte++];
336        const uint8_t task = fStreamBuffer[fCurrRLEByte++];
337
338        // Perform decoding
339        if (RLE_ESCAPE == flag) {
340            switch (task) {
341                case RLE_EOL:
342                    x = 0;
343                    y++;
344                    break;
345                case RLE_EOF:
346                    return height;
347                case RLE_DELTA: {
348                    // Two bytes are needed to specify delta
349                    if ((int) fBytesBuffered - fCurrRLEByte < 2) {
350                        if (this->checkForMoreData() < 2) {
351                            return y;
352                        }
353                    }
354                    // Modify x and y
355                    const uint8_t dx = fStreamBuffer[fCurrRLEByte++];
356                    const uint8_t dy = fStreamBuffer[fCurrRLEByte++];
357                    x += dx;
358                    y += dy;
359                    if (x > width) {
360                        SkCodecPrintf("Warning: invalid RLE input.\n");
361                        return y - dy;
362                    } else if (y > height) {
363                        fLinesToSkip = y - height;
364                        return height;
365                    }
366                    break;
367                }
368                default: {
369                    // If task does not match any of the above signals, it
370                    // indicates that we have a sequence of non-RLE pixels.
371                    // Furthermore, the value of task is equal to the number
372                    // of pixels to interpret.
373                    uint8_t numPixels = task;
374                    const size_t rowBytes = compute_row_bytes(numPixels,
375                            this->bitsPerPixel());
376                    // Abort if setting numPixels moves us off the edge of the
377                    // image.
378                    if (x + numPixels > width) {
379                        SkCodecPrintf("Warning: invalid RLE input.\n");
380                        return y;
381                    }
382
383                    // Also abort if there are not enough bytes
384                    // remaining in the stream to set numPixels.
385
386                    // At most, alignedRowBytes can be 255 (max uint8_t) *
387                    // 3 (max bytes per pixel) + 1 (aligned) = 766. If
388                    // fStreamBuffer was smaller than this,
389                    // checkForMoreData would never succeed for some bmps.
390                    static_assert(255 * 3 + 1 < kBufferSize,
391                                  "kBufferSize needs to be larger!");
392                    const size_t alignedRowBytes = SkAlign2(rowBytes);
393                    if ((int) fBytesBuffered - fCurrRLEByte < alignedRowBytes) {
394                        SkASSERT(alignedRowBytes < kBufferSize);
395                        if (this->checkForMoreData() < alignedRowBytes) {
396                            return y;
397                        }
398                    }
399                    // Set numPixels number of pixels
400                    while (numPixels > 0) {
401                        switch(this->bitsPerPixel()) {
402                            case 4: {
403                                SkASSERT(fCurrRLEByte < fBytesBuffered);
404                                uint8_t val = fStreamBuffer[fCurrRLEByte++];
405                                setPixel(dst, dstRowBytes, dstInfo, x++,
406                                        y, val >> 4);
407                                numPixels--;
408                                if (numPixels != 0) {
409                                    setPixel(dst, dstRowBytes, dstInfo,
410                                            x++, y, val & 0xF);
411                                    numPixels--;
412                                }
413                                break;
414                            }
415                            case 8:
416                                SkASSERT(fCurrRLEByte < fBytesBuffered);
417                                setPixel(dst, dstRowBytes, dstInfo, x++,
418                                        y, fStreamBuffer[fCurrRLEByte++]);
419                                numPixels--;
420                                break;
421                            case 24: {
422                                SkASSERT(fCurrRLEByte + 2 < fBytesBuffered);
423                                uint8_t blue = fStreamBuffer[fCurrRLEByte++];
424                                uint8_t green = fStreamBuffer[fCurrRLEByte++];
425                                uint8_t red = fStreamBuffer[fCurrRLEByte++];
426                                setRGBPixel(dst, dstRowBytes, dstInfo,
427                                            x++, y, red, green, blue);
428                                numPixels--;
429                            }
430                            default:
431                                SkASSERT(false);
432                                return y;
433                        }
434                    }
435                    // Skip a byte if necessary to maintain alignment
436                    if (!SkIsAlign2(rowBytes)) {
437                        fCurrRLEByte++;
438                    }
439                    break;
440                }
441            }
442        } else {
443            // If the first byte read is not a flag, it indicates the number of
444            // pixels to set in RLE mode.
445            const uint8_t numPixels = flag;
446            const int endX = SkTMin<int>(x + numPixels, width);
447
448            if (24 == this->bitsPerPixel()) {
449                // In RLE24, the second byte read is part of the pixel color.
450                // There are two more required bytes to finish encoding the
451                // color.
452                if ((int) fBytesBuffered - fCurrRLEByte < 2) {
453                    if (this->checkForMoreData() < 2) {
454                        return y;
455                    }
456                }
457
458                // Fill the pixels up to endX with the specified color
459                uint8_t blue = task;
460                uint8_t green = fStreamBuffer[fCurrRLEByte++];
461                uint8_t red = fStreamBuffer[fCurrRLEByte++];
462                while (x < endX) {
463                    setRGBPixel(dst, dstRowBytes, dstInfo, x++, y, red, green, blue);
464                }
465            } else {
466                // In RLE8 or RLE4, the second byte read gives the index in the
467                // color table to look up the pixel color.
468                // RLE8 has one color index that gets repeated
469                // RLE4 has two color indexes in the upper and lower 4 bits of
470                // the bytes, which are alternated
471                uint8_t indices[2] = { task, task };
472                if (4 == this->bitsPerPixel()) {
473                    indices[0] >>= 4;
474                    indices[1] &= 0xf;
475                }
476
477                // Set the indicated number of pixels
478                for (int which = 0; x < endX; x++) {
479                    setPixel(dst, dstRowBytes, dstInfo, x, y, indices[which]);
480                    which = !which;
481                }
482            }
483        }
484    }
485}
486
487bool SkBmpRLECodec::skipRows(int count) {
488    const SkImageInfo rowInfo = SkImageInfo::Make(this->getInfo().width(), count, kN32_SkColorType,
489            kUnpremul_SkAlphaType);
490
491    return count == this->decodeRows(rowInfo, nullptr, 0, this->options());
492}
493
494// FIXME: Make SkBmpRLECodec have no knowledge of sampling.
495//        Or it should do all sampling natively.
496//        It currently is a hybrid that needs to know what SkScaledCodec is doing.
497class SkBmpRLESampler : public SkSampler {
498public:
499    SkBmpRLESampler(SkBmpRLECodec* codec)
500        : fCodec(codec)
501    {
502        SkASSERT(fCodec);
503    }
504
505private:
506    int onSetSampleX(int sampleX) override {
507        return fCodec->setSampleX(sampleX);
508    }
509
510    // Unowned pointer. fCodec will delete this class in its destructor.
511    SkBmpRLECodec* fCodec;
512};
513
514SkSampler* SkBmpRLECodec::getSampler(bool /*createIfNecessary*/) {
515    // We will always create an SkBmpRLESampler if one is requested.
516    // This allows clients to always use the SkBmpRLESampler's
517    // version of fill(), which does nothing since RLE decodes have
518    // already filled pixel memory.  This seems fine, since creating
519    // an SkBmpRLESampler is pretty inexpensive.
520    if (!fSampler) {
521        fSampler.reset(new SkBmpRLESampler(this));
522    }
523
524    return fSampler;
525}
526
527int SkBmpRLECodec::setSampleX(int sampleX){
528    fSampleX = sampleX;
529    return get_scaled_dimension(this->getInfo().width(), sampleX);
530}
531