/[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 1260 - (show annotations)
Sat Feb 14 20:26:49 2015 UTC (4 years, 7 months ago) by dbug
File size: 18154 byte(s)
PictConv 0.21
- Added support for 32bit picture, to handle things like masking/opacity in the picture formats
- The -a1 mode will generate bytes with null value for blocks of 6 pixels with transparent alpha values (only active in monochrome or AIC conversion modes)
- Added the -f7 conversion mode for Oric pictures using the AIC coloring method.

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*4;
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_ConvertTo32Bits(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 *ptr_byte++=rgb.m_alpha;
222 }
223 }
224 }
225
226 }
227
228 void ImageContainer::WriteColor(const RgbColor& rgb,int x,int y)
229 {
230 if (m_pBitmap)
231 {
232 if (x<0) return;
233 if (y<0) return;
234
235 int dx=FreeImage_GetWidth(m_pBitmap);
236 int dy=FreeImage_GetHeight(m_pBitmap);
237
238 if (x>=dx) return;
239 if (y>=dy) return;
240
241 BYTE *ptr_byte=FreeImage_GetBitsRowCol(m_pBitmap,x,y);
242
243 *ptr_byte++=rgb.m_blue;
244 *ptr_byte++=rgb.m_green;
245 *ptr_byte++=rgb.m_red;
246 *ptr_byte++=rgb.m_alpha;
247 }
248 }
249
250 RgbColor ImageContainer::ReadColor(int x,int y) const
251 {
252 RgbColor rgb;
253 if (m_pBitmap && (x>=0) && (y>=0))
254 {
255 int dx=FreeImage_GetWidth(m_pBitmap);
256 int dy=FreeImage_GetHeight(m_pBitmap);
257
258 if ( (x<dx) && (y<dy) )
259 {
260 BYTE *ptr_byte=FreeImage_GetBitsRowCol(m_pBitmap,x,y);
261
262 rgb.m_blue =*ptr_byte++;
263 rgb.m_green =*ptr_byte++;
264 rgb.m_red =*ptr_byte++;
265 rgb.m_alpha =*ptr_byte++;
266 }
267 }
268 return rgb;
269 }
270
271
272 bool ImageContainer::ConvertToGrayScale()
273 {
274 int dx=FreeImage_GetWidth(m_pBitmap);
275 int dy=FreeImage_GetHeight(m_pBitmap);
276
277 for (int y=0;y<dy;y++)
278 {
279 for (int x=0;x<dx;x++)
280 {
281 RgbColor rgb=ReadColor(x,y);
282 rgb.m_red =(rgb.m_red+rgb.m_green+rgb.m_blue)/3;
283 rgb.m_green=rgb.m_red;
284 rgb.m_blue =rgb.m_red;
285 WriteColor(rgb,x,y);
286 }
287 }
288 return true;
289 }
290
291
292 #include "shifter_color.h"
293
294 bool ImageContainer::ReduceColorDepth(const AtariClut* pClut)
295 {
296 int dx=FreeImage_GetWidth(m_pBitmap);
297 int dy=FreeImage_GetHeight(m_pBitmap);
298
299 for (int y=0;y<dy;y++)
300 {
301 for (int x=0;x<dx;x++)
302 {
303 RgbColor rgb=ReadColor(x,y);
304 ShifterColor shifterColor(rgb);
305 rgb=shifterColor.GetRgb();
306 WriteColor(rgb,x,y);
307 }
308 }
309
310 // Then convert to 16 colors
311 RGBQUAD* pReservedPalette=0;
312 std::vector<RGBQUAD> reservedPalette;
313 if (pClut)
314 {
315 pClut->GetColors(reservedPalette);
316 if (!reservedPalette.empty())
317 {
318 pReservedPalette=&reservedPalette[0];
319 }
320 }
321
322 FIBITMAP *dib8 = FreeImage_ColorQuantizeEx(m_pBitmap,FIQ_NNQUANT,16,reservedPalette.size(),pReservedPalette);
323 FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(dib8);
324 FreeImage_Unload(dib8);
325 FreeImage_Unload(m_pBitmap);
326 m_pBitmap=dib32;
327 return true;
328 }
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 *dib32 = FreeImage_ConvertTo32Bits(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(dib32,x,0);
386 rgb.m_blue =*ptr_byte++;
387 rgb.m_green =*ptr_byte++;
388 rgb.m_red =*ptr_byte++;
389 rgb.m_alpha =*ptr_byte++;
390 colorMap.insert(rgb);
391 }
392 //_BREAK_IF_(colorMap.size()>16);
393 }
394 FreeImage_Paste(m_pBitmap,dib32,0,y,256); // Combine mode
395 FreeImage_Unload(dib8);
396 FreeImage_Unload(dib32);
397 FreeImage_Unload(lineCopy);
398 }
399 return true;
400 }
401
402
403
404 bool ImageContainer::CreateFromImage(const ImageContainer& otherImage,unsigned int x,unsigned int y,unsigned int width,unsigned int height)
405 {
406 if (!otherImage.m_pBitmap)
407 {
408 assert(otherImage.m_pBitmap);
409 return false;
410 }
411
412 FIBITMAP* pBitmap=FreeImage_Copy(otherImage.m_pBitmap,x,y,x+width,y+height);
413 if (!pBitmap)
414 {
415 return false;
416 }
417 Clear();
418 m_pBitmap=pBitmap;
419 return true;
420 }
421
422
423
424 int ImageContainer::FindBlocks(std::string& block_data) const
425 {
426 //
427 // Phase one: Find a pixel that is not of the color of the background
428 //
429 ImageContainer image_copy(*this);
430
431 std::stringstream out_x0;
432 std::stringstream out_y0;
433 std::stringstream out_width;
434 std::stringstream out_height;
435
436 out_x0 << "_FontTableX0";
437 out_y0 << "_FontTableY0";
438 out_width << "_FontTableWidth";
439 out_height << "_FontTableHeight";
440
441 RgbColor backgroundColor=image_copy.ReadColor(0,0);
442
443 unsigned int picture_width=GetWidth();
444 unsigned int picture_heigth=GetHeight();
445
446 unsigned int first_x,first_y;
447 unsigned int sprite_id=0;
448
449 for (first_y=0;first_y<200;first_y++)
450 {
451 for (first_x=0;first_x<240;first_x++)
452 {
453 RgbColor pixelColor=image_copy.ReadColor(first_x,first_y);
454
455 if (pixelColor!=backgroundColor)
456 {
457 //
458 // We've got one !!!
459 //
460 //printf("Found sprite %d at (%d,%d)\n",sprite_id,first_x,first_y);
461
462 unsigned int min_x=first_x;
463 unsigned int min_y=first_y;
464 unsigned int max_x=first_x;
465 unsigned int max_y=first_y;
466
467 // Find the width
468 while (((max_x+1)<picture_width) && (image_copy.ReadColor(max_x+1,min_y)!=backgroundColor))
469 {
470 max_x++;
471 }
472
473 // Find the heigth
474 while (((max_y+1)<picture_heigth) && (image_copy.ReadColor(min_x,max_y+1)!=backgroundColor))
475 {
476 max_y++;
477 }
478
479 unsigned int width =(max_x-min_x)+1;
480 unsigned int heigth=(max_y-min_y)+1;
481
482 // Erase the block
483 image_copy.FillRectangle(backgroundColor,min_x,min_y,width,heigth);
484
485 if ((sprite_id&15)==0)
486 {
487 // Every 16 characters, back to the start with a new .byt line
488 out_x0 << "\r\n\t.byt ";
489 out_y0 << "\r\n\t.byt ";
490 out_width << "\r\n\t.byt ";
491 out_height << "\r\n\t.byt ";
492 }
493 else
494 {
495 out_x0 << ",";
496 out_y0 << ",";
497 out_width << ",";
498 out_height << ",";
499 }
500
501 out_x0 << min_x;
502 out_y0 << min_y;
503 out_width << width;
504 out_height << heigth;
505
506 //printf("\tBounding box: (%d,%d)-(%d,%d)\n",min_x,min_y,max_x,max_y);
507
508 //getch();
509
510 // Increment sprite ID
511 sprite_id++;
512 }
513 }
514 }
515 block_data+=out_x0.str();
516 block_data+="\r\n";
517 block_data+=out_y0.str();
518 block_data+="\r\n";
519 block_data+=out_width.str();
520 block_data+="\r\n";
521 block_data+=out_height.str();
522 block_data+="\r\n";
523 return true;
524 }
525
526
527 /*
528 FREEIMAGE_LIB;
529 1>------ Build started: Project: PictConv, Configuration: Debug Win32 ------
530 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetScanLine referenced in function "unsigned char * __cdecl FreeImage_GetBitsRowCol(struct FIBITMAP *,int,int)" (?FreeImage_GetBitsRowCol@@YAPAEPAUFIBITMAP@@HH@Z)
531 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetHeight referenced in function "unsigned char * __cdecl FreeImage_GetBitsRowCol(struct FIBITMAP *,int,int)" (?FreeImage_GetBitsRowCol@@YAPAEPAUFIBITMAP@@HH@Z)
532 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Clone referenced in function "public: __thiscall ImageContainer::ImageContainer(class ImageContainer const &)" (??0ImageContainer@@QAE@ABV0@@Z)
533 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Unload referenced in function "public: void __thiscall ImageContainer::Clear(void)" (?Clear@ImageContainer@@QAEXXZ)
534 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Allocate referenced in function "public: bool __thiscall ImageContainer::Allocate(unsigned int,unsigned int,unsigned int)" (?Allocate@ImageContainer@@QAE_NIII@Z)
535 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetWidth referenced in function "public: unsigned int __thiscall ImageContainer::GetWidth(void)const " (?GetWidth@ImageContainer@@QBEIXZ)
536 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetBPP referenced in function "public: unsigned int __thiscall ImageContainer::GetDpp(void)const " (?GetDpp@ImageContainer@@QBEIXZ)
537 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetColorsUsed referenced in function "public: unsigned int __thiscall ImageContainer::GetPaletteSize(void)const " (?GetPaletteSize@ImageContainer@@QBEIXZ)
538 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_ConvertTo24Bits referenced in function "public: bool __thiscall ImageContainer::LoadPicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?LoadPicture@ImageContainer@@QAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
539 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Load referenced in function "public: bool __thiscall ImageContainer::LoadPicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?LoadPicture@ImageContainer@@QAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
540 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_FIFSupportsReading referenced in function "public: bool __thiscall ImageContainer::LoadPicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?LoadPicture@ImageContainer@@QAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
541 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetFIFFromFilename referenced in function "public: bool __thiscall ImageContainer::LoadPicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?LoadPicture@ImageContainer@@QAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
542 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_GetFileType referenced in function "public: bool __thiscall ImageContainer::LoadPicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?LoadPicture@ImageContainer@@QAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
543 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Save referenced in function "public: bool __thiscall ImageContainer::SavePicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " (?SavePicture@ImageContainer@@QBE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
544 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_FIFSupportsWriting referenced in function "public: bool __thiscall ImageContainer::SavePicture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " (?SavePicture@ImageContainer@@QBE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
545 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_ColorQuantizeEx referenced in function "public: bool __thiscall ImageContainer::ReduceColorDepth(class AtariClut const *)" (?ReduceColorDepth@ImageContainer@@QAE_NPBVAtariClut@@@Z)
546 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Paste referenced in function "public: bool __thiscall ImageContainer::ReduceColorDepthPerScanline(class std::map<int,class AtariClut,struct std::less<int>,class std::allocator<struct std::pair<int const ,class AtariClut> > > const *)" (?ReduceColorDepthPerScanline@ImageContainer@@QAE_NPBV?$map@HVAtariClut@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHVAtariClut@@@std@@@3@@std@@@Z)
547 1>image.obj : error LNK2019: unresolved external symbol _FreeImage_Copy referenced in function "public: bool __thiscall ImageContainer::ReduceColorDepthPerScanline(class std::map<int,class AtariClut,struct std::less<int>,class std::allocator<struct std::pair<int const ,class AtariClut> > > const *)" (?ReduceColorDepthPerScanline@ImageContainer@@QAE_NPBV?$map@HVAtariClut@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHVAtariClut@@@std@@@3@@std@@@Z)
548 1>pictconv.obj : error LNK2019: unresolved external symbol _FreeImage_DeInitialise referenced in function _main
549 1>pictconv.obj : error LNK2019: unresolved external symbol _FreeImage_Initialise referenced in function _main
550 */
551
552
553
554
555

  ViewVC Help
Powered by ViewVC 1.1.26