aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp
new file mode 100644
index 0000000..4a87eeb
--- /dev/null
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterTGA.cpp
@@ -0,0 +1,147 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CImageWriterTGA.h"
6
7#ifdef _IRR_COMPILE_WITH_TGA_WRITER_
8
9#include "CImageLoaderTGA.h"
10#include "IWriteFile.h"
11#include "CColorConverter.h"
12#include "irrString.h"
13
14namespace irr
15{
16namespace video
17{
18
19IImageWriter* createImageWriterTGA()
20{
21 return new CImageWriterTGA;
22}
23
24CImageWriterTGA::CImageWriterTGA()
25{
26#ifdef _DEBUG
27 setDebugName("CImageWriterTGA");
28#endif
29}
30
31bool CImageWriterTGA::isAWriteableFileExtension(const io::path& filename) const
32{
33 return core::hasFileExtension ( filename, "tga" );
34}
35
36bool CImageWriterTGA::writeImage(io::IWriteFile *file, IImage *image,u32 param) const
37{
38 STGAHeader imageHeader;
39 imageHeader.IdLength = 0;
40 imageHeader.ColorMapType = 0;
41 imageHeader.ImageType = 2;
42 imageHeader.FirstEntryIndex[0] = 0;
43 imageHeader.FirstEntryIndex[1] = 0;
44 imageHeader.ColorMapLength = 0;
45 imageHeader.ColorMapEntrySize = 0;
46 imageHeader.XOrigin[0] = 0;
47 imageHeader.XOrigin[1] = 0;
48 imageHeader.YOrigin[0] = 0;
49 imageHeader.YOrigin[1] = 0;
50 imageHeader.ImageWidth = image->getDimension().Width;
51 imageHeader.ImageHeight = image->getDimension().Height;
52
53 // top left of image is the top. the image loader needs to
54 // be fixed to only swap/flip
55 imageHeader.ImageDescriptor = (1 << 5);
56
57 // chances are good we'll need to swizzle data, so i'm going
58 // to convert and write one scan line at a time. it's also
59 // a bit cleaner this way
60 void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0;
61 switch(image->getColorFormat())
62 {
63 case ECF_A8R8G8B8:
64 CColorConverter_convertFORMATtoFORMAT
65 = CColorConverter::convert_A8R8G8B8toA8R8G8B8;
66 imageHeader.PixelDepth = 32;
67 imageHeader.ImageDescriptor |= 8;
68 break;
69 case ECF_A1R5G5B5:
70 CColorConverter_convertFORMATtoFORMAT
71 = CColorConverter::convert_A1R5G5B5toA1R5G5B5;
72 imageHeader.PixelDepth = 16;
73 imageHeader.ImageDescriptor |= 1;
74 break;
75 case ECF_R5G6B5:
76 CColorConverter_convertFORMATtoFORMAT
77 = CColorConverter::convert_R5G6B5toA1R5G5B5;
78 imageHeader.PixelDepth = 16;
79 imageHeader.ImageDescriptor |= 1;
80 break;
81 case ECF_R8G8B8:
82 CColorConverter_convertFORMATtoFORMAT
83 = CColorConverter::convert_R8G8B8toR8G8B8;
84 imageHeader.PixelDepth = 24;
85 imageHeader.ImageDescriptor |= 0;
86 break;
87#ifndef _DEBUG
88 default:
89 break;
90#endif
91 }
92
93 // couldn't find a color converter
94 if (!CColorConverter_convertFORMATtoFORMAT)
95 return false;
96
97 if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader))
98 return false;
99
100 u8* scan_lines = (u8*)image->lock();
101 if (!scan_lines)
102 return false;
103
104 // size of one pixel in bytes
105 u32 pixel_size = image->getBytesPerPixel();
106
107 // length of one row of the source image in bytes
108 u32 row_stride = (pixel_size * imageHeader.ImageWidth);
109
110 // length of one output row in bytes
111 s32 row_size = ((imageHeader.PixelDepth / 8) * imageHeader.ImageWidth);
112
113 // allocate a row do translate data into
114 u8* row_pointer = new u8[row_size];
115
116 u32 y;
117 for (y = 0; y < imageHeader.ImageHeight; ++y)
118 {
119 // source, length [pixels], destination
120 if (image->getColorFormat()==ECF_R8G8B8)
121 CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.ImageWidth, 1, 0, 0, true);
122 else
123 CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.ImageWidth, row_pointer);
124 if (file->write(row_pointer, row_size) != row_size)
125 break;
126 }
127
128 delete [] row_pointer;
129
130 image->unlock();
131
132 STGAFooter imageFooter;
133 imageFooter.ExtensionOffset = 0;
134 imageFooter.DeveloperOffset = 0;
135 strncpy(imageFooter.Signature, "TRUEVISION-XFILE.", 18);
136
137 if (file->write(&imageFooter, sizeof(imageFooter)) < (s32)sizeof(imageFooter))
138 return false;
139
140 return imageHeader.ImageHeight <= y;
141}
142
143} // namespace video
144} // namespace irr
145
146#endif
147