Home | History | Annotate | Download | only in utils
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #ifndef SkBitmapTransformer_DEFINED
     10 #define SkBitmapTransformer_DEFINED
     11 
     12 #include "SkBitmap.h"
     13 
     14 /**
     15  * Class that can copy pixel data out of an SkBitmap, transforming it
     16  * into the appropriate PixelFormat.
     17  *
     18  * As noted in https://codereview.appspot.com/6849119/#msg6 and
     19  * https://codereview.appspot.com/6900047 , at some point we might want
     20  * to make this more general purpose:
     21  * - support more PixelFormats
     22  * - use existing SkCanvas::Config8888 enum instead of new PixelFormat enum
     23  * - add method to copy pixel data for a single row, instead of the whole bitmap
     24  * - add methods to copy pixel data INTO an SkBitmap
     25  *
     26  * That would allow us to replace SkCopyConfig8888ToBitmap() in
     27  * src/core/SkConfig8888.h , as well as the transformations used by
     28  * src/images/SkImageDecoder_libpng.cpp , with this common code.
     29  *
     30  * But for now, we want something more narrowly targeted, just
     31  * supplying what is needed by SkBitmapChecksummer.
     32  */
     33 class SkBitmapTransformer {
     34 public:
     35     enum PixelFormat {
     36         // 32 bits per pixel, ARGB byte order, with the alpha-channel
     37         // value premultiplied into the R/G/B channel values.
     38         kARGB_8888_Premul_PixelFormat,
     39 
     40         // marks the end of the list
     41         kLast_PixelFormat = kARGB_8888_Premul_PixelFormat,
     42     };
     43 
     44     /**
     45      * Creates an SkBitmapTransformer instance that can transform between
     46      * the given bitmap and a pixel buffer with given pixelFormat.
     47      *
     48      * Call IsValid() before using, to confirm that this particular
     49      * bitmap/pixelFormat combination is supported!
     50      */
     51     SkBitmapTransformer(const SkBitmap& bitmap, PixelFormat pixelFormat) :
     52         fBitmap(bitmap), fPixelFormat(pixelFormat) {}
     53 
     54     /**
     55      * Returns true iff we can convert between fBitmap and fPixelFormat.
     56      * If this returns false, the return values of any other methods will
     57      * be meaningless!
     58      *
     59      * @param logReason whether to log the reason why this combination
     60      *                  is unsupported (only applies in debug mode)
     61      */
     62     bool isValid(bool logReason=false) const;
     63 
     64     /**
     65      * Returns the number of bytes needed to store a single row of the
     66      * bitmap's pixels if converted to pixelFormat.
     67      */
     68     size_t bytesNeededPerRow() const {
     69         // This is hard-coded for the single supported PixelFormat.
     70         return fBitmap.width() * 4;
     71     }
     72 
     73     /**
     74      * Returns the number of bytes needed to store the entire bitmap
     75      * if converted to pixelFormat, ASSUMING that it is written
     76      * out as a single contiguous blob of pixels (no leftover bytes
     77      * at the end of each row).
     78      */
     79     size_t bytesNeededTotal() const {
     80         return this->bytesNeededPerRow() * fBitmap.height();
     81     }
     82 
     83     /**
     84      * Writes the entire bitmap into dstBuffer, using the already-specified
     85      * pixelFormat. Returns true if successful.
     86      *
     87      * dstBufferSize is the maximum allowable bytes to write into dstBuffer;
     88      * if that is not large enough to hold the entire bitmap, then this
     89      * will fail immediately and return false.
     90      * We force the caller to pass this in to avoid buffer overruns in
     91      * unanticipated cases.
     92      *
     93      * All pixels for all rows will be written into dstBuffer as a
     94      * single contiguous blob (no skipped pixels at the end of each
     95      * row).
     96      */
     97     bool copyBitmapToPixelBuffer (void *dstBuffer, size_t dstBufferSize) const;
     98 
     99 private:
    100     const SkBitmap& fBitmap;
    101     const PixelFormat fPixelFormat;
    102 };
    103 
    104 #endif
    105