Line data Source code
1 0 : /*
2 :
3 : OOPixMap.c
4 :
5 :
6 : Copyright (C) 2010-2013 Jens Ayton
7 :
8 : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : of this software and associated documentation files (the "Software"), to deal
10 : in the Software without restriction, including without limitation the rights
11 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : copies of the Software, and to permit persons to whom the Software is
13 : furnished to do so, subject to the following conditions:
14 :
15 : The above copyright notice and this permission notice shall be included in all
16 : copies or substantial portions of the Software.
17 :
18 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 : SOFTWARE.
25 :
26 : */
27 :
28 : #import "OOPixMap.h"
29 :
30 :
31 0 : const OOPixMap kOONullPixMap =
32 : {
33 : .pixels = NULL,
34 : .width = 0,
35 : .height = 0,
36 : .format = kOOPixMapInvalidFormat,
37 : .rowBytes = 0,
38 : .bufferSize = 0
39 : };
40 :
41 :
42 0 : BOOL OOIsValidPixMap(OOPixMap pixMap)
43 : {
44 : return pixMap.pixels != NULL &&
45 : pixMap.width > 0 &&
46 : pixMap.height > 0 &&
47 : OOIsValidPixMapFormat(pixMap.format) &&
48 : pixMap.rowBytes >= pixMap.width * OOPixMapBytesPerPixelForFormat(pixMap.format) &&
49 : pixMap.bufferSize >= pixMap.rowBytes * pixMap.height;
50 : }
51 :
52 :
53 0 : OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
54 : {
55 : if (rowBytes == 0) rowBytes = width * OOPixMapBytesPerPixelForFormat(format);
56 : if (bufferSize == 0) bufferSize = rowBytes * height;
57 :
58 : OOPixMap result =
59 : {
60 : .pixels = pixels,
61 : .width = width,
62 : .height = height,
63 : .format = format,
64 : .rowBytes = rowBytes,
65 : .bufferSize = bufferSize
66 : };
67 :
68 : if (OOIsValidPixMap(result)) return result;
69 : else return kOONullPixMap;
70 : }
71 :
72 :
73 0 : OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
74 : {
75 : // Create pixmap struct with dummy pixel pointer to test validity.
76 : OOPixMap pixMap = OOMakePixMap((void *)-1, width, height, format, rowBytes, bufferSize);
77 : if (EXPECT_NOT(!OOIsValidPixMap(pixMap))) return kOONullPixMap;
78 :
79 : pixMap.pixels = malloc(pixMap.bufferSize);
80 : if (EXPECT_NOT(pixMap.pixels == NULL)) return kOONullPixMap;
81 :
82 : return pixMap;
83 : }
84 :
85 :
86 0 : void OOFreePixMap(OOPixMap *ioPixMap)
87 : {
88 : if (EXPECT_NOT(ioPixMap == NULL)) return;
89 :
90 : free(ioPixMap->pixels);
91 : *ioPixMap = kOONullPixMap;
92 : }
93 :
94 :
95 0 : OOPixMap OODuplicatePixMap(OOPixMap srcPixMap, size_t desiredSize)
96 : {
97 : if (EXPECT_NOT(!OOIsValidPixMap(srcPixMap))) return kOONullPixMap;
98 :
99 : size_t minSize = OOMinimumPixMapBufferSize(srcPixMap);
100 : if (desiredSize < minSize) desiredSize = minSize;
101 :
102 : OOPixMap result = OOAllocatePixMap(srcPixMap.width, srcPixMap.width, srcPixMap.format, srcPixMap.rowBytes, desiredSize);
103 : if (EXPECT_NOT(!OOIsValidPixMap(result))) return kOONullPixMap;
104 :
105 : memcpy(result.pixels, srcPixMap.pixels, minSize);
106 : return result;
107 : }
108 :
109 :
110 0 : BOOL OOResizePixMap(OOPixMap *ioPixMap, size_t desiredSize)
111 : {
112 : if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap))) return NO;
113 : if (desiredSize == ioPixMap->bufferSize) return YES;
114 : if (desiredSize < OOMinimumPixMapBufferSize(*ioPixMap)) return NO;
115 :
116 : void *newPixels = realloc(ioPixMap->pixels, desiredSize);
117 : if (newPixels != NULL)
118 : {
119 : ioPixMap->pixels = newPixels;
120 : ioPixMap->bufferSize = desiredSize;
121 : return YES;
122 : }
123 : else
124 : {
125 : return NO;
126 : }
127 : }
128 :
129 :
130 0 : BOOL OOExpandPixMap(OOPixMap *ioPixMap, size_t desiredSize)
131 : {
132 : if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap))) return NO;
133 : if (desiredSize <= ioPixMap->bufferSize) return YES;
134 :
135 : return OOResizePixMap(ioPixMap, desiredSize);
136 : }
137 :
138 :
139 : #ifndef NDEBUG
140 :
141 : #import "Universe.h"
142 : #import "MyOpenGLView.h"
143 :
144 :
145 0 : void OODumpPixMap(OOPixMap pixMap, NSString *name)
146 : {
147 : if (!OOIsValidPixMap(pixMap)) return;
148 :
149 : MyOpenGLView *gameView = [UNIVERSE gameView];
150 :
151 : switch (pixMap.format)
152 : {
153 :
154 : case kOOPixMapInvalidFormat:
155 : break;
156 :
157 : case kOOPixMapGrayscale:
158 : [gameView dumpGrayToFileNamed:name
159 : bytes:pixMap.pixels
160 : width:pixMap.width
161 : height:pixMap.height
162 : rowBytes:pixMap.rowBytes];
163 : break;
164 :
165 : case kOOPixMapGrayscaleAlpha:
166 : [gameView dumpGrayAlphaToFileNamed:name
167 : bytes:pixMap.pixels
168 : width:pixMap.width
169 : height:pixMap.height
170 : rowBytes:pixMap.rowBytes];
171 : break;
172 :
173 : case kOOPixMapRGBA:
174 : [gameView dumpRGBAToRGBFileNamed:[name stringByAppendingString:@" rgb"]
175 : andGrayFileNamed:[name stringByAppendingString:@" alpha"]
176 : bytes:pixMap.pixels
177 : width:pixMap.width
178 : height:pixMap.height
179 : rowBytes:pixMap.rowBytes];
180 : break;
181 : }
182 : }
183 : #endif
184 :
185 :
186 0 : BOOL OOIsValidPixMapFormat(OOPixMapFormat format)
187 : {
188 : switch (format)
189 : {
190 : case kOOPixMapInvalidFormat: return NO;
191 : case kOOPixMapGrayscale:
192 : case kOOPixMapGrayscaleAlpha:
193 : case kOOPixMapRGBA:
194 : return YES;
195 : }
196 :
197 : return NO;
198 : }
199 :
200 :
201 : #ifndef NDEBUG
202 0 : unsigned short OOPixMapBytesPerPixelForFormat(OOPixMapFormat format)
203 : {
204 : switch (format)
205 : {
206 : case kOOPixMapInvalidFormat: return 0;
207 : case kOOPixMapGrayscale: return 1;
208 : case kOOPixMapGrayscaleAlpha: return 2;
209 : case kOOPixMapRGBA: return 4;
210 : }
211 :
212 : return -1;
213 : }
214 : #endif
215 :
216 :
217 0 : NSString *OOPixMapFormatName(OOPixMapFormat format)
218 : {
219 : switch (format)
220 : {
221 : case kOOPixMapInvalidFormat: return @"invalid";
222 : case kOOPixMapGrayscale: return @"grayscale";
223 : case kOOPixMapGrayscaleAlpha: return @"grayscale+alpha";
224 : case kOOPixMapRGBA: return @"RGBA";
225 : }
226 :
227 : return [NSString stringWithFormat:@"invalid<%i>", (int)format];
228 : }
229 :
230 :
231 :
232 0 : BOOL OOPixMapFormatHasAlpha(OOPixMapFormat format)
233 : {
234 : switch (format)
235 : {
236 : case kOOPixMapInvalidFormat: return NO;
237 : case kOOPixMapGrayscale: return NO;
238 : case kOOPixMapGrayscaleAlpha: return YES;
239 : case kOOPixMapRGBA: return YES;
240 : }
241 :
242 : return NO;
243 : }
|