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 #ifndef SkPixmapPriv_DEFINED
9 #define SkPixmapPriv_DEFINED
10 
11 #include "SkPixmap.h"
12 #include "SkEncodedOrigin.h"
13 #include "SkAutoPixmapStorage.h"
14 
15 class SkPixmapPriv {
16 public:
17     // These flag are applied in this order (swap is applied last)
18     enum OrientFlags {
19         kMirrorX = 1 << 0,
20         kMirrorY = 1 << 1,
21         kSwapXY  = 1 << 2,
22     };
23 
24     static OrientFlags OriginToOrient(SkEncodedOrigin);
25 
26     /**
27      *  Copy the pixels in this pixmap into dst, applying the orientation transformations specified
28      *  by the flags. If the inputs are invalid, this returns false and no copy is made.
29      */
30     static bool Orient(const SkPixmap& dst, const SkPixmap& src, OrientFlags);
31 
32     static bool ShouldSwapWidthHeight(SkEncodedOrigin o);
33     static SkImageInfo SwapWidthHeight(const SkImageInfo& info);
34 
35     /**
36      *  Decode an image and then copy into dst, applying origin.
37      *
38      *  @param dst SkPixmap to write the final image, after
39      *      applying the origin.
40      *  @param origin SkEncodedOrigin to apply to the raw pixels.
41      *  @param decode Function for decoding into a pixmap without
42      *      applying the origin.
43      */
Orient(const SkPixmap & dst,SkEncodedOrigin origin,std::function<bool (const SkPixmap &)> decode)44     static bool Orient(const SkPixmap& dst, SkEncodedOrigin origin,
45             std::function<bool(const SkPixmap&)> decode) {
46         SkAutoPixmapStorage storage;
47         const SkPixmap* tmp = &dst;
48         if (origin != kTopLeft_SkEncodedOrigin) {
49             auto info = dst.info();
50             if (ShouldSwapWidthHeight(origin)) {
51                 info = SwapWidthHeight(info);
52             }
53             if (!storage.tryAlloc(info)) {
54                 return false;
55             }
56             tmp = &storage;
57         }
58         if (!decode(*tmp)) {
59             return false;
60         }
61         if (tmp != &dst) {
62             return Orient(dst, *tmp, OriginToOrient(origin));
63         }
64         return true;
65     }
66 
ResetPixmapKeepInfo(SkPixmap * pm,const void * address,size_t rowBytes)67     static void ResetPixmapKeepInfo(SkPixmap* pm, const void* address, size_t rowBytes) {
68         pm->fRowBytes = rowBytes;
69         pm->fPixels = address;
70     }
71 };
72 
73 #endif
74 
75