/[projet1]/public/pc/tools/osdk/main/pictconv/sources/image.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/pictconv/sources/image.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 880 - (show annotations)
Tue Sep 25 23:40:17 2012 UTC (7 years, 1 month ago) by mmu_man
File size: 11719 byte(s)
Fix includes

* Remove unneeded includes or use standard ones in place of windows ones
* Fix case of FreeImage.h includes

1
2
3 #include <assert.h>
4 #include <stdio.h>
5 #include <set>
6 #include <sstream>
7
8 #include "common.h"
9
10 #include "FreeImage.h"
11
12 #include "defines.h"
13 #include "getpixel.h"
14
15 #include "hires.h"
16 #include "image.h"
17
18 #include "atari_converter.h" // For 'AtariClut', but I need a good abstraction for that
19
20
21 unsigned char* FreeImage_GetBitsRowCol(FIBITMAP *dib,int x,int y)
22 {
23 unsigned int dy=FreeImage_GetHeight(dib);
24 unsigned char *ptr_byte=FreeImage_GetScanLine(dib,dy-y-1);
25 ptr_byte+=x*3;
26 return ptr_byte;
27 }
28
29
30 // ============================================================================
31 //
32 // ImageContainer
33 //
34 // ============================================================================
35
36 ImageContainer::ImageContainer() :
37 m_pBitmap(0)
38 {
39 }
40
41 ImageContainer::ImageContainer(const ImageContainer& otherImage) :
42 m_pBitmap(0)
43 {
44 if (otherImage.m_pBitmap && (&otherImage!=this))
45 {
46 m_pBitmap=FreeImage_Clone(otherImage.m_pBitmap);
47 }
48 }
49
50 ImageContainer::~ImageContainer()
51 {
52 Clear();
53 }
54
55
56 void ImageContainer::Clear()
57 {
58 if (m_pBitmap)
59 {
60 FreeImage_Unload(m_pBitmap);
61 }
62 }
63
64 bool ImageContainer::Allocate(unsigned int width,unsigned int height,unsigned int bpp)
65 {
66 // Free eventual data
67 Clear();
68
69 m_pBitmap=FreeImage_Allocate(width,height,bpp);
70 if (m_pBitmap)
71 {
72 return true;
73 }
74 return false;
75 }
76
77
78
79 unsigned int ImageContainer::GetWidth() const
80 {
81 if (m_pBitmap)
82 {
83 return FreeImage_GetWidth(m_pBitmap);
84 }
85 return 0;
86 }
87
88
89 unsigned int ImageContainer::GetHeight() const
90 {
91 if (m_pBitmap)
92 {
93 return FreeImage_GetHeight(m_pBitmap);
94 }
95 return 0;
96 }
97
98 unsigned int ImageContainer::GetDpp() const
99 {
100 if (m_pBitmap)
101 {
102 return FreeImage_GetBPP(m_pBitmap);
103 }
104 return 0;
105 }
106
107 unsigned int ImageContainer::GetPaletteSize() const
108 {
109 if (m_pBitmap)
110 {
111 return FreeImage_GetColorsUsed(m_pBitmap);
112 }
113 return 0;
114 }
115
116
117 bool ImageContainer::LoadPicture(const std::string& fileName)
118 {
119 // Free any previous existing picture - if any
120 Clear();
121
122 FIBITMAP *dib = NULL;
123
124 // check the file signature and deduce its format
125 // (the second argument is currently not used by FreeImage)
126 FREE_IMAGE_FORMAT fif=FreeImage_GetFileType(fileName.c_str(),0);
127 if (fif==FIF_UNKNOWN)
128 {
129 // no signature ?
130 // try to guess the file format from the file extension
131 fif=FreeImage_GetFIFFromFilename(fileName.c_str());
132 }
133 // check that the plugin has reading capabilities ...
134 if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
135 {
136 // ok, let's load the file
137 dib=FreeImage_Load(fif,fileName.c_str(),FIT_BITMAP);
138 if (!dib)
139 {
140 printf("\r\n Unable to load specified picture.");
141 //exit(1);
142 return false;
143 }
144
145 FIBITMAP *converted_dib=FreeImage_ConvertTo24Bits(dib);
146 FreeImage_Unload(dib);
147 dib=converted_dib;
148 if (!dib)
149 {
150 printf("\r\n Unable to convert the picture data to a suitable format.");
151 //exit(1);
152 return false;
153 }
154 }
155 else
156 {
157 printf("\r\n Unsupported load file format.");
158 //exit(1);
159 return false;
160 }
161 m_pBitmap=dib;
162 return true;
163 }
164
165
166 bool ImageContainer::SavePicture(const std::string& fileName) const
167 {
168 if (!m_pBitmap)
169 {
170 return false;
171 }
172 FREE_IMAGE_FORMAT fif=FreeImage_GetFIFFromFilename(fileName.c_str());
173 if ((fif==FIF_UNKNOWN) || (!FreeImage_FIFSupportsWriting(fif)))
174 {
175 printf("\r\n Unsupported save file format.");
176 //exit(1);
177 return false;
178 }
179
180 BOOL bSuccess=FreeImage_Save(fif,m_pBitmap,fileName.c_str(),0);
181 if (!bSuccess)
182 {
183 printf("\r\n Unable to save '%s'.",fileName.c_str());
184 //exit(1);
185 return false;
186 }
187 return true;
188 }
189
190 void ImageContainer::FillRectangle(const RgbColor& rgb,unsigned int x0,unsigned int y0,unsigned int width,unsigned int heigth)
191 {
192 if (m_pBitmap)
193 {
194 unsigned int dx=FreeImage_GetWidth(m_pBitmap);
195 unsigned int dy=FreeImage_GetHeight(m_pBitmap);
196
197 if (x0<0) return;
198 if (y0<0) return;
199
200 if (x0>=dx) return;
201 if (y0>=dy) return;
202
203 unsigned int x1=(x0+width)-1;
204 unsigned int y1=(y0+heigth)-1;
205
206 if (x1<0) return;
207 if (y1<0) return;
208
209 if (x1>=dx) return;
210 if (y1>=dy) return;
211
212 for (unsigned int y=y0;y<=y1;y++)
213 {
214 for (unsigned int x=x0;x<=x1;x++)
215 {
216 BYTE *ptr_byte=FreeImage_GetBitsRowCol(m_pBitmap,x,y);
217
218 *ptr_byte++=rgb.m_blue;
219 *ptr_byte++=rgb.m_green;
220 *ptr_byte++=rgb.m_red;
221 }
222 }
223 }
224
225 }
226
227 void ImageContainer::WriteColor(const RgbColor& rgb,int x,int y)
228 {
229 if (m_pBitmap)
230 {
231 if (x<0) return;
232 if (y<0) return;
233
234 int dx=FreeImage_GetWidth(m_pBitmap);
235 int dy=FreeImage_GetHeight(m_pBitmap);
236
237 if (x>=dx) return;
238 if (y>=dy) return;
239
240 BYTE *ptr_byte=FreeImage_GetBitsRowCol(m_pBitmap,x,y);
241
242 *ptr_byte++=rgb.m_blue;
243 *ptr_byte++=rgb.m_green;
244 *ptr_byte++=rgb.m_red;
245 }
246 }
247
248 RgbColor ImageContainer::ReadColor(int x,int y) const
249 {
250 RgbColor rgb;
251 if (m_pBitmap && (x>=0) && (y>=0))
252 {
253 int dx=FreeImage_GetWidth(m_pBitmap);
254 int dy=FreeImage_GetHeight(m_pBitmap);
255
256 if ( (x<dx) && (y<dy) )
257 {
258 BYTE *ptr_byte=FreeImage_GetBitsRowCol(m_pBitmap,x,y);
259
260 //unsigned rm=FreeImage_GetRedMask(m_pBitmap);
261 //unsigned gm=FreeImage_GetGreenMask(m_pBitmap);
262 //unsigned bm=FreeImage_GetBlueMask(m_pBitmap);
263
264 rgb.m_blue =*ptr_byte++;
265 rgb.m_green =*ptr_byte++;
266 rgb.m_red =*ptr_byte++;
267 }
268 }
269 return rgb;
270 }
271
272
273 bool ImageContainer::ConvertToGrayScale()
274 {
275 int dx=FreeImage_GetWidth(m_pBitmap);
276 int dy=FreeImage_GetHeight(m_pBitmap);
277
278 for (int y=0;y<dy;y++)
279 {
280 for (int x=0;x<dx;x++)
281 {
282 RgbColor rgb=ReadColor(x,y);
283 rgb.m_red=(rgb.m_red+rgb.m_green+rgb.m_blue)/3;
284 rgb.m_green=rgb.m_red;
285 rgb.m_blue =rgb.m_red;
286 WriteColor(rgb,x,y);
287 }
288 }
289 return true;
290 }
291
292
293 #include "shifter_color.h"
294
295 bool ImageContainer::ReduceColorDepth(const AtariClut* pClut)
296 {
297 int dx=FreeImage_GetWidth(m_pBitmap);
298 int dy=FreeImage_GetHeight(m_pBitmap);
299
300 for (int y=0;y<dy;y++)
301 {
302 for (int x=0;x<dx;x++)
303 {
304 RgbColor rgb=ReadColor(x,y);
305 ShifterColor shifterColor(rgb);
306 rgb=shifterColor.GetRgb();
307 WriteColor(rgb,x,y);
308 }
309 }
310
311 // Then convert to 16 colors
312 RGBQUAD* pReservedPalette=0;
313 std::vector<RGBQUAD> reservedPalette;
314 if (pClut)
315 {
316 pClut->GetColors(reservedPalette);
317 if (!reservedPalette.empty())
318 {
319 pReservedPalette=&reservedPalette[0];
320 }
321 }
322
323 FIBITMAP *dib8 = FreeImage_ColorQuantizeEx(m_pBitmap,FIQ_NNQUANT,16,reservedPalette.size(),pReservedPalette);
324 FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib8);
325 FreeImage_Unload(dib8);
326 FreeImage_Unload(m_pBitmap);
327 m_pBitmap=dib24;
328 return true;
329 }
330
331 bool ImageContainer::ReduceColorDepthPerScanline(const std::map<int,AtariClut>* pCluts)
332 {
333 unsigned int dx=FreeImage_GetWidth(m_pBitmap);
334 unsigned int dy=FreeImage_GetHeight(m_pBitmap);
335
336 for (unsigned int y=0;y<dy;y++)
337 {
338 //_BREAK_IF_(y==5);
339
340 // Convert the current line
341 for (unsigned int x=0;x<dx;x++)
342 {
343 RgbColor rgb=ReadColor(x,y);
344 ShifterColor shifterColor(rgb);
345 rgb=shifterColor.GetRgb();
346 WriteColor(rgb,x,y);
347 }
348
349 // Then convert to 16 colors
350 RGBQUAD* pReservedPalette=0;
351 std::vector<RGBQUAD> reservedPalette;
352 if (pCluts)
353 {
354 std::map<int,AtariClut>::const_iterator it=pCluts->find(y);
355 if (it!=pCluts->end())
356 {
357 const AtariClut& clut=it->second;
358
359 clut.GetColors(reservedPalette);
360 if (!reservedPalette.empty())
361 {
362 pReservedPalette=&reservedPalette[0];
363 }
364 }
365 }
366
367 // Quantize the current line to 16 colors (Atari multi-palette image)
368 FIBITMAP *lineCopy = FreeImage_Copy(m_pBitmap,0,y,dx,y+1);
369 assert(FreeImage_GetWidth(lineCopy)==dx);
370 assert(FreeImage_GetHeight(lineCopy)==1);
371
372 // Then convert to 16 colors
373 FREE_IMAGE_QUANTIZE quantize;
374 if (pReservedPalette) quantize=FIQ_NNQUANT; // FIQ_WUQUANT is better than FIQ_NNQUANT in this particular setup... but it fails handling correctly the reserved palettes...
375 else quantize=FIQ_WUQUANT; // FIQ_WUQUANT is better than FIQ_NNQUANT in this particular setup...
376
377 FIBITMAP *dib8 = FreeImage_ColorQuantizeEx(lineCopy,quantize,16,reservedPalette.size(),pReservedPalette);
378 FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib8);
379 {
380 // Check that we have 16 colors max... starting to doubt it
381 std::set<RgbColor> colorMap;
382 for (unsigned int x=0;x<dx;x++)
383 {
384 RgbColor rgb;
385 BYTE *ptr_byte=FreeImage_GetBitsRowCol(dib24,x,0);
386 rgb.m_blue =*ptr_byte++;
387 rgb.m_green =*ptr_byte++;
388 rgb.m_red =*ptr_byte++;
389 colorMap.insert(rgb);
390 }
391 //_BREAK_IF_(colorMap.size()>16);
392 }
393 FreeImage_Paste(m_pBitmap,dib24,0,y,256); // Combine mode
394 FreeImage_Unload(dib8);
395 FreeImage_Unload(dib24);
396 FreeImage_Unload(lineCopy);
397 }
398 return true;
399 }
400
401
402 bool ImageContainer::CreateFromImage(const ImageContainer& otherImage,unsigned int x,unsigned int y,unsigned int width,unsigned int height)
403 {
404 if (!otherImage.m_pBitmap)
405 {
406 assert(otherImage.m_pBitmap);
407 return false;
408 }
409
410 FIBITMAP* pBitmap=FreeImage_Copy(otherImage.m_pBitmap,x,y,x+width,y+height);
411 if (!pBitmap)
412 {
413 return false;
414 }
415 Clear();
416 m_pBitmap=pBitmap;
417 return true;
418 }
419
420
421
422
423
424
425 int ImageContainer::FindBlocks(std::string& block_data) const
426 {
427 //
428 // Phase one: Find a pixel that is not of the color of the background
429 //
430 ImageContainer image_copy(*this);
431
432 std::stringstream out_x0;
433 std::stringstream out_y0;
434 std::stringstream out_width;
435 std::stringstream out_height;
436
437 out_x0 << "_FontTableX0";
438 out_y0 << "_FontTableY0";
439 out_width << "_FontTableWidth";
440 out_height << "_FontTableHeight";
441
442 RgbColor backgroundColor=image_copy.ReadColor(0,0);
443
444 unsigned int picture_width=GetWidth();
445 unsigned int picture_heigth=GetHeight();
446
447 unsigned int first_x,first_y;
448 unsigned int sprite_id=0;
449
450 for (first_y=0;first_y<200;first_y++)
451 {
452 for (first_x=0;first_x<240;first_x++)
453 {
454 RgbColor pixelColor=image_copy.ReadColor(first_x,first_y);
455
456 if (pixelColor!=backgroundColor)
457 {
458 //
459 // We've got one !!!
460 //
461 //printf("Found sprite %d at (%d,%d)\n",sprite_id,first_x,first_y);
462
463 unsigned int min_x=first_x;
464 unsigned int min_y=first_y;
465 unsigned int max_x=first_x;
466 unsigned int max_y=first_y;
467
468 // Find the width
469 while (((max_x+1)<picture_width) && (image_copy.ReadColor(max_x+1,min_y)!=backgroundColor))
470 {
471 max_x++;
472 }
473
474 // Find the heigth
475 while (((max_y+1)<picture_heigth) && (image_copy.ReadColor(min_x,max_y+1)!=backgroundColor))
476 {
477 max_y++;
478 }
479
480 unsigned int width =(max_x-min_x)+1;
481 unsigned int heigth=(max_y-min_y)+1;
482
483 // Erase the block
484 image_copy.FillRectangle(backgroundColor,min_x,min_y,width,heigth);
485
486 if ((sprite_id&15)==0)
487 {
488 // Every 16 characters, back to the start with a new .byt line
489 out_x0 << "\r\n\t.byt ";
490 out_y0 << "\r\n\t.byt ";
491 out_width << "\r\n\t.byt ";
492 out_height << "\r\n\t.byt ";
493 }
494 else
495 {
496 out_x0 << ",";
497 out_y0 << ",";
498 out_width << ",";
499 out_height << ",";
500 }
501
502 out_x0 << min_x;
503 out_y0 << min_y;
504 out_width << width;
505 out_height << heigth;
506
507 //printf("\tBounding box: (%d,%d)-(%d,%d)\n",min_x,min_y,max_x,max_y);
508
509 //getch();
510
511 // Increment sprite ID
512 sprite_id++;
513 }
514 }
515 }
516 block_data+=out_x0.str();
517 block_data+="\r\n";
518 block_data+=out_y0.str();
519 block_data+="\r\n";
520 block_data+=out_width.str();
521 block_data+="\r\n";
522 block_data+=out_height.str();
523 block_data+="\r\n";
524 return true;
525 }
526
527
528

  ViewVC Help
Powered by ViewVC 1.1.26