1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
3  * Copyright 2009-2014 Pierre Ossman for Cendio AB
4  *
5  * This is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This software is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this software; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18  * USA.
19  */
20 //
21 // PixelFormat - structure to represent a pixel format.  Also has useful
22 // methods for reading & writing to streams, etc. Conversion to and from
23 // other formats are also handled by this class. We have three different
24 // representations that we refer to:
25 //
26 // a) Pixels - Unsigned native integers in the format specified by this
27 //             PixelFormat object.
28 // b) Buffer - Same thing as pixels, but in the appropriate byte stream
29 //             format. This involves endian conversion and padding.
30 // c) RGB - A byte stream of 8 bit red, green and blue elements, in that
31 //          order.
32 //
33 
34 #ifndef __RFB_PIXELFORMAT_H__
35 #define __RFB_PIXELFORMAT_H__
36 
37 #include <rfb/Pixel.h>
38 
39 namespace rdr { class InStream; class OutStream; }
40 
41 namespace rfb {
42 
43   class PixelFormat {
44   public:
45     PixelFormat(int b, int d, bool e, bool t,
46                 int rm, int gm, int bm, int rs, int gs, int bs);
47     PixelFormat();
48 
49     // Checks if the formats have identical buffer representation.
50     // They might still have different pixel representation, endianness
51     // or true colour state.
52     bool equal(const PixelFormat& other) const;
53 
54     void read(rdr::InStream* is);
55     void write(rdr::OutStream* os) const;
56 
57     bool is888(void) const;
58     bool isBigEndian(void) const;
59     bool isLittleEndian(void) const;
60 
61     inline Pixel pixelFromBuffer(const rdr::U8* buffer) const;
62     inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const;
63 
64     inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue) const;
65     inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue) const;
66 
67     void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const;
68     void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
69                        int w, int stride, int h) const;
70 
71     inline void rgbFromPixel(Pixel pix, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
72     inline void rgbFromPixel(Pixel pix, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const;
73 
74     void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const;
75     void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
76                        int w, int stride, int h) const;
77 
78     Pixel pixelFromPixel(const PixelFormat &srcPF, Pixel src) const;
79 
80     void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
81                           const rdr::U8* src, int pixels) const;
82     void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
83                           const rdr::U8* src, int w, int h,
84                           int dstStride, int srcStride) const;
85 
86     void print(char* str, int len) const;
87     bool parse(const char* str);
88 
89   protected:
90     void updateState(void);
91     bool isSane(void);
92 
93   private:
94     // Preprocessor generated, optimised methods
95 
96     void directBufferFromBufferFrom888(rdr::U8* dst, const PixelFormat &srcPF,
97                                        const rdr::U8* src, int w, int h,
98                                        int dstStride, int srcStride) const;
99     void directBufferFromBufferFrom888(rdr::U16* dst, const PixelFormat &srcPF,
100                                        const rdr::U8* src, int w, int h,
101                                        int dstStride, int srcStride) const;
102     void directBufferFromBufferFrom888(rdr::U32* dst, const PixelFormat &srcPF,
103                                        const rdr::U8* src, int w, int h,
104                                        int dstStride, int srcStride) const;
105 
106     void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
107                                      const rdr::U8* src, int w, int h,
108                                      int dstStride, int srcStride) const;
109     void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
110                                      const rdr::U16* src, int w, int h,
111                                      int dstStride, int srcStride) const;
112     void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
113                                      const rdr::U32* src, int w, int h,
114                                      int dstStride, int srcStride) const;
115 
116   public:
117     int bpp;
118     int depth;
119 
120     // This only tracks if the client thinks it is in colour map mode.
121     // In practice we are always in true colour mode.
122     bool trueColour;
123 
124   protected:
125     bool bigEndian;
126     int redMax;
127     int greenMax;
128     int blueMax;
129     int redShift;
130     int greenShift;
131     int blueShift;
132 
133   protected:
134     /* Pre-computed values to keep algorithms simple */
135     int redBits, greenBits, blueBits;
136     int maxBits, minBits;
137     bool endianMismatch;
138 
139     static rdr::U8 upconvTable[256*8];
140     static rdr::U8 downconvTable[256*8];
141 
142     class Init;
143     friend class Init;
144     static Init _init;
145 
146     /* Only for testing this class */
147     friend void makePixel(const rfb::PixelFormat &, rdr::U8 *);
148     friend bool verifyPixel(const rfb::PixelFormat &,
149                             const rfb::PixelFormat &,
150                             const rdr::U8 *);
151   };
152 }
153 
154 #include <rfb/PixelFormat.inl>
155 
156 #endif
157