• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
SkBitmapTransformer(const SkBitmap & bitmap,PixelFormat pixelFormat)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      */
bytesNeededPerRow()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      */
bytesNeededTotal()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