1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file contains the declaration of functions to help with images.
#ifndef O3D_CORE_CROSS_IMAGE_UTILS_H_
#define O3D_CORE_CROSS_IMAGE_UTILS_H_
#include "base/cross/bits.h"
#include "core/cross/types.h"
#include "core/cross/texture_base.h"
namespace o3d {
namespace image {
// We will fail to load images that are bigger than 4kx4k to avoid security
// risks. GPUs don't usually support bigger sizes anyway.
// The biggest bitmap buffer size with these dimensions is:
// 4k x 4k x 4xsizeof(float) x6 x4/3 (x6 for cube maps, x4/3 for mipmaps)
// That makes 2GB, representable in an unsigned int, so we will avoid wraps.
const unsigned int kMaxImageDimension = 4096u;
enum ImageFileType {
UNKNOWN,
TGA,
JPEG,
PNG,
DDS,
};
unsigned int GetNumComponentsForFormat(Texture::Format format);
inline bool IsPOT(unsigned width, unsigned height) {
return ((width & (width - 1)) == 0) && ((height & (height - 1)) == 0);
}
inline bool CheckImageDimensions(unsigned int width, unsigned int height) {
return width <= kMaxImageDimension && height <= kMaxImageDimension;
}
// Returns whether or not we can make mips.
bool CanMakeMips(Texture::Format format);
// Gets the number of mip-maps required for a full chain starting at
// width x height.
inline unsigned int ComputeMipMapCount(
unsigned int width, unsigned int height) {
return 1 + base::bits::Log2Floor(std::max(width, height));
}
// Gets the smallest power-of-two value that is at least as high as
// dimension. This is the POT dimension used in ScaleUpToPOT.
inline unsigned int ComputePOTSize(unsigned int dimension) {
return 1 << base::bits::Log2Ceiling(dimension);
}
// Computes one dimension of a mip.
inline unsigned ComputeMipDimension(int level, unsigned dimension) {
unsigned v = dimension >> level;
return v > 0 ? v : 1u;
}
// Computes the size of the buffer containing a mip-map chain, given its base
// width, height, format and number of mip-map levels.
size_t ComputeMipChainSize(unsigned int base_width,
unsigned int base_height,
Texture::Format format,
unsigned int num_mipmaps);
inline int ComputePitch(Texture::Format format, unsigned width) {
if (Texture::IsCompressedFormat(format)) {
unsigned blocks_across = (width + 3u) / 4u;
unsigned bytes_per_block = format == Texture::DXT1 ? 8u : 16u;
return bytes_per_block * blocks_across;
} else {
return static_cast<int>(ComputeMipChainSize(width, 1u, format, 1u));
}
}
// Computes the pitch for a bitmap.
// NOTE: For textures you must get the pitch from the OS.
inline int ComputeMipPitch(Texture::Format format,
int level,
unsigned width) {
return ComputePitch(format, ComputeMipDimension(level, width));
}
// Computes the number of bytes of a bitmap pixel buffer.
size_t ComputeBufferSize(unsigned int width,
unsigned int height,
Texture::Format format);
// Crop part of an image from src, scale it to an arbitrary size
// and paste in dest image. Utility function for all DrawImage
// function in bitmap and textures. Scale operation is based on
// Lanczos resampling.
// Note: this doesn't work for DXTC, or floating-point images.
//
// Parameters:
// src: source image which would be copied from.
// src_x: x-coordinate of the starting pixel in the src image.
// src_y: y-coordinate of the starting pixel in the src image.
// src_width: width of the part in src image to be croped.
// src_height: height of the part in src image to be croped.
// src_img_width: width of the src image.
// src_img_height: height of the src image.
// dest: dest image which would be copied to.
// dest_x: x-coordinate of the starting pixel in the dest image.
// dest_y: y-coordinate of the starting pixel in the dest image.
// dest_width: width of the part in dest image to be pasted to.
// dest_height: height of the part in dest image to be pasted to.
// dest_img_width: width of the dest image.
// dest_img_height: height of the src image.
// component: size of each pixel in terms of array element.
// Returns:
// true if crop and scale succeeds.
void LanczosScale(const uint8* src,
int src_x, int src_y,
int src_width, int src_height,
int src_img_width, int src_img_height,
uint8* dest, int dest_pitch,
int dest_x, int dest_y,
int dest_width, int dest_height,
int dest_img_width, int dest_img_height,
int component);
// Detects the type of image file based on the filename.
ImageFileType GetFileTypeFromFilename(const char *filename);
//
// Detects the type of image file based on the mime-type.
ImageFileType GetFileTypeFromMimeType(const char *mime_type);
// Adds filler alpha byte (0xff) after every pixel. Assumes buffer was
// allocated with enough storage)
// can convert RGB -> RGBA, BGR -> BGRA, etc.
void XYZToXYZA(uint8 *image_data, int pixel_count);
// Swaps Red and Blue components in the image.
void RGBAToBGRA(uint8 *image_data, int pixel_count);
// Generates a mip-map for 1 level.
// NOTE: this doesn't work for DXTC, or floating-point images.
//
// Parameters:
// src_width: the width of the source image.
// src_height: the height of the source image.
// format: the format of the data.
// src_data: the data containing the src image.
// src_pitch: If the format is uncompressed this is the number of bytes
// per row of pixels. If compressed this value is unused.
// dst_data: memory for a mip one level smaller then the source.
// dst_pitch: If the format is uncompressed this is the number of bytes
// per row of pixels. If compressed this value is unused.
bool GenerateMipmap(unsigned int src_width,
unsigned int src_height,
Texture::Format format,
const uint8 *src_data,
int src_pitch,
uint8 *dst_data,
int dst_pitch);
// Scales an image up to power-of-two textures, using point filtering.
// NOTE: this doesn't work for DXTC, or floating-point images.
//
// Parameters:
// width: the non-power-of-two width of the original image.
// height: the non-power-of-two height of the original image.
// format: the format of the data.
// src: the data containing the source data of the original image.
// dst: a buffer with enough space for the power-of-two version. Pixels are
// written from the end to the beginning so dst can be the same buffer
// as src.
// dst_pitch: Number of bytes across 1 row of pixels.
bool ScaleUpToPOT(unsigned int width,
unsigned int height,
Texture::Format format,
const uint8 *src,
uint8 *dst,
int dst_pitch);
// Scales an image to an arbitrary size, using point filtering.
// NOTE: this doesn't work for DXTC, or floating-point images.
//
// Parameters:
// src_width: the width of the original image.
// src_height: the height of the original image.
// format: the format of the data.
// src: the data containing the source data of the original image.
// dst_width: the width of the target image.
// dst_height: the height of the target image.
// dst: a buffer with enough space for the target version. Pixels are
// written from the end to the beginning so dst can be the same buffer
// as src if the transformation is an upscaling.
// dst_pitch: Number of bytes across 1 row of pixels.
bool Scale(unsigned int src_width,
unsigned int src_height,
Texture::Format format,
const uint8 *src,
unsigned int dst_width,
unsigned int dst_height,
uint8 *dst,
int dst_pitch);
// adjust start points and boundaries when using DrawImage data
// in bitmap and textures.
// Parameters:
// src_x: x-coordinate of the starting pixel in the source image.
// src_y: y-coordinate of the starting pixel in the source image.
// src_width: width of the source image to draw.
// src_height: height of the source image to draw.
// src_bmp_width: original width of source bitmap.
// src_bmp_height: original height of source bitmap.
// dest_x: x-coordinate of the starting pixel in the dest image.
// dest_y: y-coordinate of the starting pixel in the dest image.
// dest_width: width of the dest image to draw.
// dest_height: height of the dest image to draw.
// dest_bmp_width: original width of dest bitmap.
// dest_bmp_height: original height of dest bitmap.
// Returns:
// false if src or dest rectangle is out of boundaries.
bool AdjustDrawImageBoundary(int* src_x, int* src_y,
int* src_width, int* src_height,
int src_bmp_width, int src_bmp_height,
int* dest_x, int* dest_y,
int* dest_width, int* dest_height,
int dest_bmp_width, int dest_bmp_height);
} // namespace image
} // namespace o3d
#endif // O3D_CORE_CROSS_IMAGE_UTILS_H_
|