xoreos  0.0.5
util.h
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #ifndef GRAPHICS_IMAGES_UTIL_H
26 #define GRAPHICS_IMAGES_UTIL_H
27 
28 #include <cassert>
29 #include <cstring>
30 
31 #include "src/common/types.h"
32 #include "src/common/scopedptr.h"
33 #include "src/common/util.h"
34 #include "src/common/maths.h"
35 #include "src/common/error.h"
36 
37 #include "src/graphics/types.h"
38 
39 namespace Graphics {
40 
43 static inline uint32 getDataSize(PixelFormatRaw format, int32 width, int32 height) {
44  if ((width < 0) || (width >= 0x8000) || (height < 0) || (height >= 0x8000))
45  throw Common::Exception("Invalid dimensions %dx%d", width, height);
46 
47  switch (format) {
48  case kPixelFormatRGB8:
49  return width * height * 3;
50 
51  case kPixelFormatRGBA8:
52  return width * height * 4;
53 
54  case kPixelFormatRGB5A1:
55  case kPixelFormatRGB5:
56  return width * height * 2;
57 
58  case kPixelFormatDXT1:
59  return MAX<uint32>( 8, ((width + 3) / 4) * ((height + 3) / 4) * 8);
60 
61  case kPixelFormatDXT3:
62  case kPixelFormatDXT5:
63  return MAX<uint32>(16, ((width + 3) / 4) * ((height + 3) / 4) * 16);
64 
65  default:
66  break;
67  }
68 
69  throw Common::Exception("Invalid pixel format %u", (uint) format);
70 }
71 
73 static inline bool hasValidDimensions(PixelFormatRaw format, int32 width, int32 height) {
74  if ((width < 0) || (width >= 0x8000) || (height < 0) || (height >= 0x8000))
75  return false;
76 
77  switch (format) {
78  case kPixelFormatRGB8:
79  case kPixelFormatRGBA8:
80  case kPixelFormatRGB5A1:
81  case kPixelFormatRGB5:
82  case kPixelFormatDXT1:
83  case kPixelFormatDXT3:
84  case kPixelFormatDXT5:
85  return true;
86 
87  default:
88  break;
89  }
90 
91  return false;
92 }
93 
95 static inline void flipHorizontally(byte *data, int width, int height, int bpp) {
96  if ((width <= 0) || (height <= 0) || (bpp <= 0))
97  return;
98 
99  const size_t halfWidth = width / 2;
100  const size_t pitch = bpp * width;
101 
102  Common::ScopedArray<byte> buffer(new byte[bpp]);
103 
104  while (height-- > 0) {
105  byte *dataStart = data;
106  byte *dataEnd = data + pitch - bpp;
107 
108  for (size_t j = 0; j < halfWidth; j++) {
109  memcpy(buffer.get(), dataStart , bpp);
110  memcpy(dataStart , dataEnd , bpp);
111  memcpy(dataEnd , buffer.get(), bpp);
112 
113  dataStart += bpp;
114  dataEnd -= bpp;
115  }
116 
117  data += pitch;
118  }
119 }
120 
122 static inline void flipVertically(byte *data, int width, int height, int bpp) {
123  if ((width <= 0) || (height <= 0) || (bpp <= 0))
124  return;
125 
126  const size_t pitch = bpp * width;
127 
128  byte *dataStart = data;
129  byte *dataEnd = data + (pitch * height) - pitch;
130 
131  Common::ScopedArray<byte> buffer(new byte[pitch]);
132 
133  size_t halfHeight = height / 2;
134  while (halfHeight--) {
135  memcpy(buffer.get(), dataStart , pitch);
136  memcpy(dataStart , dataEnd , pitch);
137  memcpy(dataEnd , buffer.get(), pitch);
138 
139  dataStart += pitch;
140  dataEnd -= pitch;
141  }
142 }
143 
145 static inline void rotate90(byte *data, int width, int height, int bpp, int steps) {
146  if ((width <= 0) || (height <= 0) || (bpp <= 0))
147  return;
148 
149  assert(width == height);
150 
151  while (steps-- > 0) {
152  const size_t n = width;
153 
154  const size_t w = n / 2;
155  const size_t h = (n + 1) / 2;
156 
157  for (size_t x = 0; x < w; x++) {
158  for (size_t y = 0; y < h; y++) {
159  const size_t d0 = ( y * n + x ) * bpp;
160  const size_t d1 = ((n - 1 - x) * n + y ) * bpp;
161  const size_t d2 = ((n - 1 - y) * n + (n - 1 - x)) * bpp;
162  const size_t d3 = ( x * n + (n - 1 - y)) * bpp;
163 
164  for (size_t p = 0; p < (size_t) bpp; p++) {
165  const byte tmp = data[d0 + p];
166 
167  data[d0 + p] = data[d1 + p];
168  data[d1 + p] = data[d2 + p];
169  data[d2 + p] = data[d3 + p];
170  data[d3 + p] = tmp;
171  }
172  }
173  }
174 
175  }
176 }
177 
179 static inline uint32 deSwizzleOffset(uint32 x, uint32 y, uint32 width, uint32 height) {
180  width = Common::intLog2(width);
181  height = Common::intLog2(height);
182 
183  uint32 offset = 0;
184  uint32 shiftCount = 0;
185 
186  while (width | height) {
187  if (width) {
188  offset |= (x & 0x01) << shiftCount;
189 
190  x >>= 1;
191 
192  shiftCount++;
193  width--;
194  }
195 
196  if (height) {
197  offset |= (y & 0x01) << shiftCount;
198 
199  y >>= 1;
200 
201  shiftCount++;
202  height--;
203  }
204  }
205 
206  return offset;
207 }
208 
209 } // End of namespace Graphics
210 
211 #endif // GRAPHICS_IMAGES_UTIL_H
static int intLog2(uint32 v)
Definition: maths.h:83
static bool hasValidDimensions(PixelFormatRaw format, int32 width, int32 height)
Are these image dimensions valid for this format?
Definition: util.h:73
Mathematical helpers.
Basic graphics types.
PixelFormatRaw
Definition: types.h:55
A simple scoped smart pointer template.
Basic exceptions to throw.
static uint32 deSwizzleOffset(uint32 x, uint32 y, uint32 width, uint32 height)
De-"swizzle" a texture pixel offset.
Definition: util.h:179
static void flipHorizontally(byte *data, int width, int height, int bpp)
Flip an image horizontally.
Definition: util.h:95
static void rotate90(byte *data, int width, int height, int bpp, int steps)
Rotate a square image in 90° steps, clock-wise.
Definition: util.h:145
Utility templates and functions.
Low-level type definitions to handle fixed width types portably.
StackException Exception
Definition: error.h:59
static uint32 getDataSize(PixelFormatRaw format, int32 width, int32 height)
Return the number of bytes necessary to hold an image of these dimensions and in this format...
Definition: util.h:43
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
uint32_t uint32
Definition: types.h:204
static void flipVertically(byte *data, int width, int height, int bpp)
Flip an image vertically.
Definition: util.h:122
uint8 byte
Definition: types.h:209
unsigned int uint
Definition: types.h:211
int32_t int32
Definition: types.h:203