172 {
174 )
175 {
176 TGAHeader* header = (TGAHeader*) view.
Address;
177
178 int w = header->imageSpecification.width, h = header->imageSpecification.height;
179 int entryBpp = header->imageSpecification.pixelDepth;
180 int alphaBits = header->imageSpecification.AlphaBits;
181
182 ColorPalette palette = null;
183 PixelFormat format;
184 ColorParser cParser;
185 switch (header->imageType & (TGAImageType) 0x3)
186 {
187 case TGAImageType.UncompressedColorMapped:
188 {
189 int mapBpp = header->colorMapSpecification.entrySize;
190 if (entryBpp == 4)
191 {
192 format = PixelFormat.Format4bppIndexed;
193 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
194 {
195 byte val = ((byte*) sPtr)[sIndex >> 1], val2 = ((byte*) dPtr)[dIndex >> 1];
196 val = (sIndex & 1) == 0 ? (byte) (val >> 4) : (byte) (val & 0xF);
197 ((byte*) dPtr)[dIndex >> 1] = (dIndex & 1) == 0
198 ? (byte) ((val2 & 0xF) | (val << 4))
199 : (byte) ((val2 & 0xF0) | val);
200 };
201 }
202 else if (entryBpp == 8)
203 {
204 format = PixelFormat.Format8bppIndexed;
205 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
206 {
207 ((byte*) dPtr)[dIndex] = ((byte*) sPtr)[sIndex];
208 };
209 }
210 else
211 {
212 throw new InvalidDataException("Invalid TGA color map format.");
213 }
214
215 int firstIndex = header->colorMapSpecification.firstEntryIndex;
216 int palSize = firstIndex + header->colorMapSpecification.length;
218
219 PaletteParser pParser;
220 if (mapBpp == 32)
221 {
223 {
224 Color c = (Color) (*(ARGBPixel*) x);
225 x += 4;
226 return c;
227 };
228 }
229 else if (mapBpp == 24)
230 {
232 {
233 Color c = (Color) (*(RGBPixel*) x);
234 x += 3;
235 return c;
236 };
237 }
238 else
239 {
240 throw new InvalidDataException("Invalid TGA color map format.");
241 }
242
243 VoidPtr palData = header->ColorMapData;
244 for (int i = firstIndex; i < palSize; i++)
245 {
246 palette.Entries[i] = pParser(ref palData);
247 }
248
249 break;
250 }
251
252 case TGAImageType.UncompressedTrueColor:
253 {
254 if (entryBpp == 15 || entryBpp == 16 && alphaBits == 0)
255 {
256 format = PixelFormat.Format16bppRgb555;
257 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
258 {
259 ((RGB555Pixel*) dPtr)[dIndex] = ((RGB555Pixel*) sPtr)[sIndex];
260 };
261 }
262 else if (entryBpp == 16)
263 {
264 format = PixelFormat.Format16bppArgb1555;
265 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
266 {
267 ((RGB555Pixel*) dPtr)[dIndex] = ((RGB555Pixel*) sPtr)[sIndex];
268 };
269 }
270 else if (entryBpp == 24)
271 {
272 format = PixelFormat.Format24bppRgb;
273 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
274 {
275 ((RGBPixel*) dPtr)[dIndex] = ((RGBPixel*) sPtr)[sIndex];
276 };
277 }
278 else if (entryBpp == 32)
279 {
280 format = alphaBits == 8 ? PixelFormat.Format32bppArgb : PixelFormat.Format32bppRgb;
281 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
282 {
283 ((ARGBPixel*) dPtr)[dIndex] = ((ARGBPixel*) sPtr)[sIndex];
284 };
285 }
286 else
287 {
288 throw new InvalidDataException("Unknown TGA file format.");
289 }
290
291 break;
292 }
293
294 case TGAImageType.UncompressedGreyscale:
295 {
296 if (entryBpp == 8)
297 {
298 format = PixelFormat.Format24bppRgb;
299 cParser = delegate(
VoidPtr sPtr,
int sIndex,
VoidPtr dPtr,
int dIndex)
300 {
301 ((RGBPixel*) dPtr)[dIndex] = RGBPixel.FromIntensity(((byte*) sPtr)[sIndex]);
302 };
303 }
304 else
305 {
306 throw new InvalidDataException("Unknown TGA file format.");
307 }
308
309 break;
310 }
311
312 default: throw new InvalidDataException("Unknown TGA file format.");
313 }
314
315 Bitmap bmp = new Bitmap(w, h, format);
316 if (palette != null)
317 {
318 bmp.Palette = palette;
319 }
320
321 BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);
322
323 bool rle = ((int) header->imageType & 0x8) != 0;
324 int srcStride = (entryBpp * w).Align(8) / 8;
325 int rleBufferLen = rle ? srcStride : 0;
326
327 byte* buffer = stackalloc byte[rleBufferLen];
328
329 int origin = (int) header->imageSpecification.ImageOrigin;
330 int xStep = (origin & 1) == 0 ? 1 : -1;
331 int yStep = (origin & 2) != 0 ? 1 : -1;
332 byte* imgSrc = header->ImageData;
333 for (int dY = yStep == 1 ? 0 : h - 1, sY = 0; sY < h; dY += yStep, sY++)
334 {
336
337 if (rle)
338 {
339 imgSrc += DecodeRLE(imgSrc, buffer, srcStride, entryBpp);
340 }
341
342 for (int dX = xStep == 1 ? 0 : w - 1, sX = 0; sX < w; dX += xStep, sX++)
343 {
344 cParser(rle ? buffer : imgSrc, sX, imgDst, dX);
345 }
346
347 if (!rle)
348 {
349 imgSrc += srcStride;
350 }
351 }
352
353 bmp.UnlockBits(data);
354 return bmp;
355 }
356 }
Definition: ColorPaletteExtension.cs:20
static ColorPalette CreatePalette(ColorPaletteFlags flags, int entries)
Definition: ColorPaletteExtension.cs:21
Definition: FileMap.cs:10
VoidPtr Address
Definition: FileMap.cs:16
static FileMap FromFile(string path)
Definition: FileMap.cs:48
ColorPaletteFlags
Definition: ColorPaletteExtension.cs:12
FileMapProtect
Definition: FileMap.cs:175