| |
| /* |
| * Copyright 2012 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkBitmapTransformer_DEFINED |
| #define SkBitmapTransformer_DEFINED |
| |
| #include "SkBitmap.h" |
| |
| /** |
| * Class that can copy pixel data out of an SkBitmap, transforming it |
| * into the appropriate PixelFormat. |
| * |
| * As noted in https://codereview.appspot.com/6849119/#msg6 and |
| * https://codereview.appspot.com/6900047 , at some point we might want |
| * to make this more general purpose: |
| * - support more PixelFormats |
| * - use existing SkCanvas::Config8888 enum instead of new PixelFormat enum |
| * - add method to copy pixel data for a single row, instead of the whole bitmap |
| * - add methods to copy pixel data INTO an SkBitmap |
| * |
| * That would allow us to replace SkCopyConfig8888ToBitmap() in |
| * src/core/SkConfig8888.h , as well as the transformations used by |
| * src/images/SkImageDecoder_libpng.cpp , with this common code. |
| * |
| * But for now, we want something more narrowly targeted, just |
| * supplying what is needed by SkBitmapChecksummer. |
| */ |
| class SkBitmapTransformer { |
| public: |
| enum PixelFormat { |
| // 32 bits per pixel, ARGB byte order, with the alpha-channel |
| // value premultiplied into the R/G/B channel values. |
| kARGB_8888_Premul_PixelFormat, |
| |
| // marks the end of the list |
| kLast_PixelFormat = kARGB_8888_Premul_PixelFormat, |
| }; |
| |
| /** |
| * Creates an SkBitmapTransformer instance that can transform between |
| * the given bitmap and a pixel buffer with given pixelFormat. |
| * |
| * Call IsValid() before using, to confirm that this particular |
| * bitmap/pixelFormat combination is supported! |
| */ |
| SkBitmapTransformer(const SkBitmap& bitmap, PixelFormat pixelFormat) : |
| fBitmap(bitmap), fPixelFormat(pixelFormat) {} |
| |
| /** |
| * Returns true iff we can convert between fBitmap and fPixelFormat. |
| * If this returns false, the return values of any other methods will |
| * be meaningless! |
| * |
| * @param logReason whether to log the reason why this combination |
| * is unsupported (only applies in debug mode) |
| */ |
| bool isValid(bool logReason=false) const; |
| |
| /** |
| * Returns the number of bytes needed to store a single row of the |
| * bitmap's pixels if converted to pixelFormat. |
| */ |
| size_t bytesNeededPerRow() const { |
| // This is hard-coded for the single supported PixelFormat. |
| return fBitmap.width() * 4; |
| } |
| |
| /** |
| * Returns the number of bytes needed to store the entire bitmap |
| * if converted to pixelFormat, ASSUMING that it is written |
| * out as a single contiguous blob of pixels (no leftover bytes |
| * at the end of each row). |
| */ |
| size_t bytesNeededTotal() const { |
| return this->bytesNeededPerRow() * fBitmap.height(); |
| } |
| |
| /** |
| * Writes the entire bitmap into dstBuffer, using the already-specified |
| * pixelFormat. Returns true if successful. |
| * |
| * dstBufferSize is the maximum allowable bytes to write into dstBuffer; |
| * if that is not large enough to hold the entire bitmap, then this |
| * will fail immediately and return false. |
| * We force the caller to pass this in to avoid buffer overruns in |
| * unanticipated cases. |
| * |
| * All pixels for all rows will be written into dstBuffer as a |
| * single contiguous blob (no skipped pixels at the end of each |
| * row). |
| */ |
| bool copyBitmapToPixelBuffer (void *dstBuffer, size_t dstBufferSize) const; |
| |
| private: |
| const SkBitmap& fBitmap; |
| const PixelFormat fPixelFormat; |
| }; |
| |
| #endif |