BrawlCrate v0.41
Wii File Editor
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
BrawlLib.Imaging.TGA Class Reference

Static Public Member Functions

static unsafe Bitmap FromFile (string path)
 
static unsafe void ToStream (Bitmap bmp, FileStream stream)
 
static void ToFile (Bitmap bmp, string path)
 

Member Function Documentation

◆ FromFile()

static unsafe Bitmap BrawlLib.Imaging.TGA.FromFile ( string  path)
inlinestatic
172 {
173 using (FileMap view = FileMap.FromFile(path, FileMapProtect.Read)
174 ) // FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
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 {
222 pParser = (ref VoidPtr x) =>
223 {
224 Color c = (Color) (*(ARGBPixel*) x);
225 x += 4;
226 return c;
227 };
228 }
229 else if (mapBpp == 24)
230 {
231 pParser = (ref VoidPtr x) =>
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 {
335 VoidPtr imgDst = (VoidPtr) data.Scan0 + data.Stride * dY;
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
Definition: VoidPtr.cs:9

◆ ToFile()

static void BrawlLib.Imaging.TGA.ToFile ( Bitmap  bmp,
string  path 
)
inlinestatic
517 {
518 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 8,
519 FileOptions.RandomAccess))
520 {
521 ToStream(bmp, stream);
522 }
523 }
static unsafe void ToStream(Bitmap bmp, FileStream stream)
Definition: TGAImage.cs:358

◆ ToStream()

static unsafe void BrawlLib.Imaging.TGA.ToStream ( Bitmap  bmp,
FileStream  stream 
)
inlinestatic
359 {
360 int w = bmp.Width, h = bmp.Height;
361
362 TGAHeader header = new TGAHeader();
363 TGAFooter footer = new TGAFooter(0, 0);
364
365 PaletteEncoder pEnc = null;
366 ColorParser cEnc = null;
367 ColorPalette pal = null;
368
369 header.imageSpecification.width = (ushort) w;
370 header.imageSpecification.height = (ushort) h;
371 header.imageType = TGAImageType.UncompressedTrueColor;
372 switch (bmp.PixelFormat)
373 {
374 case PixelFormat.Format4bppIndexed:
375 case PixelFormat.Format8bppIndexed:
376 {
377 pal = bmp.Palette;
378
379 header.colorMapType = 1;
380 header.imageType = TGAImageType.UncompressedColorMapped;
381 header.colorMapSpecification.length = (ushort) pal.Entries.Length;
382 header.colorMapSpecification.entrySize = 24;
383 header.imageSpecification.pixelDepth = 8;
384
385 pEnc = (ref VoidPtr ptr, Color c) =>
386 {
387 *(RGBPixel*) ptr = (RGBPixel) c;
388 ptr += 3;
389 };
390
391 if (bmp.PixelFormat == PixelFormat.Format4bppIndexed)
392 {
393 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
394 {
395 ((byte*) dPtr)[dIndex] = (sIndex & 1) == 0
396 ? (byte) (((byte*) sPtr)[sIndex >> 1] >> 4)
397 : (byte) (((byte*) sPtr)[sIndex >> 1] & 0xF);
398 };
399 }
400 else
401 {
402 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
403 {
404 ((byte*) dPtr)[dIndex] = ((byte*) sPtr)[sIndex];
405 };
406 }
407
408 break;
409 }
410
411 case PixelFormat.Format32bppRgb:
412 case PixelFormat.Format32bppArgb:
413 {
414 header.imageSpecification.pixelDepth = 32;
415 header.imageSpecification.AlphaBits =
416 bmp.PixelFormat == PixelFormat.Format32bppArgb ? (byte) 8 : (byte) 0;
417
418 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
419 {
420 ((ARGBPixel*) dPtr)[dIndex] = ((ARGBPixel*) sPtr)[sIndex];
421 };
422 break;
423 }
424
425 case PixelFormat.Format24bppRgb:
426 {
427 header.imageSpecification.pixelDepth = 24;
428
429 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
430 {
431 ((RGBPixel*) dPtr)[dIndex] = ((RGBPixel*) sPtr)[sIndex];
432 };
433 break;
434 }
435
436 case PixelFormat.Format16bppRgb555:
437 {
438 header.imageSpecification.pixelDepth = 15;
439 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
440 {
441 ((RGB555Pixel*) dPtr)[dIndex] = ((RGB555Pixel*) sPtr)[sIndex];
442 };
443 break;
444 }
445
446 case PixelFormat.Format16bppArgb1555:
447 {
448 header.imageSpecification.pixelDepth = 16;
449 header.imageSpecification.AlphaBits = 1;
450 cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
451 {
452 ((RGB555Pixel*) dPtr)[dIndex] = ((RGB555Pixel*) sPtr)[sIndex];
453 };
454 break;
455 }
456
457 default:
458 throw new FormatException("Input pixel format unsupported.");
459 }
460
461 int mapLen = header.colorMapSpecification.DataLength;
462 int dataLen = header.imageSpecification.DataLength;
463
464 int totalLen = TGAHeader.Size + mapLen + dataLen + TGAFooter.Size;
465 stream.SetLength(totalLen);
466
467 BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, bmp.PixelFormat);
468 //using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 0x1000, FileOptions.RandomAccess))
469 using (FileMap view = FileMap.FromStream(stream)
470 ) // stream.MapView(0, (uint)totalLen, FileMapProtect.ReadWrite))
471 {
472 //Create header
473 TGAHeader* pHeader = (TGAHeader*) view.Address;
474 *pHeader = header;
475
476 //Write id
477
478 //Write color map
479 if (pal != null)
480 {
481 VoidPtr pMap = pHeader->ColorMapData;
482 for (int i = 0; i < pal.Entries.Length; i++)
483 {
484 pEnc(ref pMap, pal.Entries[i]);
485 }
486 }
487
488 //Write color data
489 int dstStride = (pHeader->imageSpecification.pixelDepth * w).Align(8) / 8;
490 int origin = (int) pHeader->imageSpecification.ImageOrigin;
491 int xStep = (origin & 1) == 0 ? 1 : -1;
492 int yStep = (origin & 2) != 0 ? 1 : -1;
493 byte* imgDst = pHeader->ImageData;
494 for (int sY = yStep == 1 ? 0 : h - 1, dY = 0; dY < h; sY += yStep, dY++)
495 {
496 VoidPtr imgSrc = (VoidPtr) data.Scan0 + data.Stride * sY;
497
498 //Do RLE encoding
499
500 for (int sX = xStep == 1 ? 0 : w - 1, dX = 0; dX < w; sX += xStep, dX++)
501 {
502 cEnc(imgSrc, sX, imgDst, dX);
503 }
504
505 imgDst += dstStride;
506 }
507
508 //Write footer
509 TGAFooter* pFooter = (TGAFooter*) (pHeader->ImageData + pHeader->imageSpecification.DataLength);
510 *pFooter = footer;
511 }
512
513 bmp.UnlockBits(data);
514 }
static FileMap FromStream(FileStream stream)
Definition: FileMap.cs:117

The documentation for this class was generated from the following file: