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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1374 - (show annotations)
Mon Jul 11 14:39:36 2016 UTC (3 years, 8 months ago) by dbug
File size: 22684 byte(s)
- Fixed a problem in the color reduction code failing on a 32bit source image
1
2 #define _CRT_SECURE_NO_WARNINGS
3
4 #include <assert.h>
5 #include <string.h>
6 #include <stdio.h>
7
8 #include <iostream>
9
10 #include "common.h"
11
12 #include "defines.h"
13 #include "getpixel.h"
14
15 #include "atari_converter.h"
16 #include "shifter_color.h"
17
18 #include "image.h"
19
20 #include "FreeImage.h"
21
22 //#define ENABLE_PALETTE_TRACKING
23
24
25 // ============================================================================
26 //
27 // AtariClut
28 //
29 // ============================================================================
30
31 int AtariClut::convert_pixel_shifter(const ShifterColor& color)
32 {
33 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
34 std::map<ShifterColor,int>::iterator it=m_clut_color_to_index.find(color);
35 if (it==m_clut_color_to_index.end())
36 {
37 // Not found - need to search the first free slot...
38 //int index=m_clut_color_to_index.size();
39 for (int index=0;index<16;index++)
40 {
41 std::map<int,ShifterColor>::iterator it=m_clut_index_to_color.find(index);
42 if (it==m_clut_index_to_color.end())
43 {
44 //assert(index<16);
45 m_clut_color_to_index[color]=index;
46 m_clut_index_to_color[index]=color;
47 assert(m_clut_color_to_index[m_clut_index_to_color[index]]==index);
48 assert(m_clut_index_to_color[m_clut_color_to_index[color]]==color);
49 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
50 return index;
51 }
52 }
53 // Color not found, we have a problem... like we have more than 16 colors Oo
54 assert(0);
55 return 0; // assert ?
56 }
57 else
58 {
59 // Return existing index
60 return it->second;
61 }
62 }
63
64 int AtariClut::convert_pixel_shifter(const RgbColor& rgb)
65 {
66 ShifterColor color(rgb);
67 return convert_pixel_shifter(color);
68 }
69
70 void AtariClut::SetColor(const ShifterColor& color,int index)
71 {
72 assert(index<16);
73 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
74
75 m_clut_color_to_index[color]=index;
76 m_clut_index_to_color[index]=color;
77 }
78
79 void AtariClut::SetColor(const RgbColor& rgb,int index)
80 {
81 ShifterColor color(rgb);
82 SetColor(color,index);
83 }
84
85
86
87 // The idea is to reorder the colors in a way that limits the differences
88 // from one clut to another. An obvious fix is to make the identical colors
89 // stay on the same index.
90 void AtariClut::Reorder(AtariClut& baseClut)
91 {
92 #if 1
93 AtariClut newClut;
94 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
95
96 // Code that computes the error between colors and choose the closest one
97 std::map<int,ShifterColor>::iterator it=baseClut.m_clut_index_to_color.begin();
98 while (it!=baseClut.m_clut_index_to_color.end())
99 {
100 ShifterColor baseColor=it->second;
101
102 std::map<int,ShifterColor>::iterator foundIt=m_clut_index_to_color.end();
103 int foundDifference=0;
104
105 std::map<int,ShifterColor>::iterator searchIt=m_clut_index_to_color.begin();
106 while (searchIt!=m_clut_index_to_color.end())
107 {
108 ShifterColor searchColor=searchIt->second;
109
110 int difference=baseColor.ComputeDifference(searchColor);
111 if ((foundIt==m_clut_index_to_color.end()) || (difference<=foundDifference))
112 {
113 foundIt =searchIt;
114 foundDifference =difference;
115 }
116 ++searchIt;
117 }
118
119 if (foundIt!=m_clut_index_to_color.end())
120 {
121 // Found a match
122 ShifterColor foundColor=foundIt->second;
123 newClut.convert_pixel_shifter(foundColor);
124
125 std::map<ShifterColor,int>::iterator deleteIt=m_clut_color_to_index.find(foundColor);
126 assert(deleteIt!=m_clut_color_to_index.end());
127
128 m_clut_index_to_color.erase(foundIt);
129 m_clut_color_to_index.erase(deleteIt);
130 }
131
132 ++it;
133 }
134 m_clut_index_to_color.swap(newClut.m_clut_index_to_color);
135 m_clut_color_to_index.swap(newClut.m_clut_color_to_index);
136 #else
137 // Code that performs exact match
138 std::map<ShifterColor,int>::iterator it=baseClut.m_clut_color_to_index.begin();
139 while (it!=baseClut.m_clut_color_to_index.end())
140 {
141 ShifterColor baseColor=(*it).first;
142 int baseIndex=(*it).second;
143
144 std::map<ShifterColor,int>::iterator findIt=m_clut_color_to_index.find(baseColor);
145 if (findIt!=m_clut_color_to_index.end())
146 {
147 // Found a match
148 int foundIndex=findIt->second;
149 if (foundIndex!=baseIndex)
150 {
151 // Different indexes in the palette, we need to swap
152 ShifterColor swappedColor=m_clut_index_to_color[baseIndex];
153 m_clut_index_to_color[foundIndex]=swappedColor;
154 m_clut_color_to_index[swappedColor] =foundIndex;
155
156 m_clut_index_to_color[baseIndex]=baseColor;
157 m_clut_color_to_index[baseColor]=baseIndex;
158 }
159 }
160 ++it;
161 }
162 #endif
163 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
164 }
165
166 void AtariClut::SaveClut(long handle) const
167 {
168 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
169 unsigned short clut[16];
170 memset(clut,0,sizeof(clut));
171
172 assert(m_clut_color_to_index.size()<=16);
173 std::map<ShifterColor,int>::const_iterator it=m_clut_color_to_index.begin();
174 while (it!=m_clut_color_to_index.end())
175 {
176 int index=it->second;
177 assert(index<16);
178 const ShifterColor& color=it->first;
179 if (index<16)
180 {
181 // Atari ST is a big endian machine
182 clut[index]=color.GetBigEndianValue();
183 }
184 ++it;
185 }
186 write(handle,clut,32);
187 }
188
189
190 void AtariClut::SaveClutAsText(std::string& text) const
191 {
192 assert(m_clut_index_to_color.size()==m_clut_color_to_index.size());
193 unsigned short clut[16];
194 memset(clut,0,sizeof(clut));
195
196 assert(m_clut_color_to_index.size()<=16);
197 std::map<ShifterColor,int>::const_iterator it=m_clut_color_to_index.begin();
198 while (it!=m_clut_color_to_index.end())
199 {
200 int index=it->second;
201 assert(index<16);
202 const ShifterColor& color=it->first;
203 if (index<16)
204 {
205 clut[index]=color.GetValue();
206 }
207 ++it;
208 }
209
210 char buffer[64];
211 for (int index=0;index<16;index++)
212 {
213 if (index!=0)
214 {
215 text+=",";
216 }
217 sprintf(buffer,"$%04x",clut[index]);
218 text+=buffer;
219 }
220 }
221
222
223 void AtariClut::GetColors(std::vector<RGBQUAD>& colors) const
224 {
225 const std::map<ShifterColor,int>& reservedColor=m_clut_color_to_index;
226 assert(m_clut_color_to_index.size()==m_clut_index_to_color.size());
227
228 unsigned int color_count=reservedColor.size();
229 if (color_count)
230 {
231 colors.resize(color_count);
232
233 std::vector<RGBQUAD>::iterator itDest=colors.begin();
234 std::map<ShifterColor,int>::const_iterator itSource=reservedColor.begin();
235 while (itSource!=reservedColor.end())
236 {
237 const ShifterColor& sourceColor=itSource->first;
238 RgbColor rgbColor=sourceColor.GetRgb();
239
240 RGBQUAD& destColor=*itDest;
241 destColor.rgbRed =rgbColor.m_red;
242 destColor.rgbGreen =rgbColor.m_green;
243 destColor.rgbBlue =rgbColor.m_blue;
244
245 ++itSource;
246 ++itDest;
247 }
248 }
249 }
250
251
252 // ============================================================================
253 //
254 // AtariPictureConverter
255 //
256 // ============================================================================
257
258 AtariPictureConverter::AtariPictureConverter() :
259 PictureConverter(MACHINE_ATARIST),
260 m_palette_mode(PALETTE_AUTOMATIC),
261 m_buffer(0),
262 m_flagPalettePerScanline(false)
263 {
264 SetFormat(FORMAT_SINGLE_PALETTE);
265 set_buffer_size(320,200); // Default size
266
267 clear_screen();
268 }
269
270 AtariPictureConverter::~AtariPictureConverter()
271 {
272 delete[] m_buffer;
273 }
274
275
276 bool AtariPictureConverter::SetFormat(int format)
277 {
278 m_format=(FORMAT)format;
279 if (m_format==FORMAT_MONOCHROME)
280 {
281 m_buffer_bitplans=1;
282 }
283 else
284 {
285 m_buffer_bitplans=4;
286 }
287 return m_format<_FORMAT_MAX_;
288 }
289
290
291 void AtariPictureConverter::set_buffer_size(int width,int height)
292 {
293 m_buffer_width =width;
294 m_buffer_height =height;
295 m_buffer_size =m_buffer_height*((width+15)/16)*2*m_buffer_bitplans; // *wordsize*bitplanscount;
296
297 int pictureCount=1;
298 if (m_swapping==SWAPPING_ENABLED)
299 {
300 pictureCount=2;
301 }
302 delete[] m_buffer;
303 m_buffer=new unsigned char[m_buffer_size*pictureCount];
304 }
305
306
307
308 void AtariPictureConverter::clear_screen()
309 {
310 for (unsigned int i=0;i<m_buffer_size;i++)
311 {
312 m_buffer[i]=0;
313 }
314 }
315
316
317 bool AtariPictureConverter::Convert(const ImageContainer& sourcePicture)
318 {
319 ImageContainer convertedPicture(sourcePicture);
320
321 #ifdef ENABLE_PALETTE_TRACKING
322 {
323 // ------- debug start
324 std::string clutAsText;
325 AtariClut& clut=GetClut(0);
326 clut.SaveClutAsText(clutAsText);
327 clutAsText+="\r\n";
328 std::cout << "AtariPictureConverter::Convert:" << clutAsText;
329 // ------- debug end
330 }
331 std::cout << "AtariPictureConverter::Convert:PaletteMode" << m_palette_mode << "\r\n";
332 #endif
333
334 if (m_blockmode!=BLOCKMODE_DISABLED)
335 {
336 std::cout << "-b1 (block mode) not supported on this machine";
337 return false;
338 }
339
340 if (m_format==FORMAT_MULTIPLE_PALETTE)
341 {
342 m_flagPalettePerScanline=true;
343 }
344 else
345 {
346 m_flagPalettePerScanline=false;
347 if (m_palette_mode==PALETTE_FROM_LAST_PIXELS)
348 {
349 // Can's use this mode if only one palette should be exported
350 std::cout << "-p2 (Last pixels of each line of the picture contains the palette) requires -f1 (Multi palette format)";
351 return false;
352 }
353 }
354
355 switch (m_palette_mode)
356 {
357 case PALETTE_AUTOMATIC:
358 // Nothing to do
359 break;
360
361 case PALETTE_FROM_LAST_LINE:
362 {
363 // Cut the first line, and extract the palette
364 ImageContainer lockedPalette;
365 if (!lockedPalette.CreateFromImage(convertedPicture,0,convertedPicture.GetHeight()-2,convertedPicture.GetWidth(),2))
366 {
367 return false;
368 }
369
370 if (!convertedPicture.CreateFromImage(convertedPicture,0,0,convertedPicture.GetWidth(),convertedPicture.GetHeight()-2))
371 {
372 return false;
373 }
374
375 unsigned int clut_start=0;
376 unsigned int clut_end=1;
377 if (m_format==FORMAT_MULTIPLE_PALETTE)
378 {
379 clut_end=convertedPicture.GetHeight();
380 }
381
382 RgbColor ignoreColor=lockedPalette.ReadColor(0,0);
383 for (unsigned int index=0;index<16;index++)
384 {
385 RgbColor rgbColor=lockedPalette.ReadColor(index,1);
386 if (rgbColor!=ignoreColor)
387 {
388 // This color should be locked for this index
389 for (unsigned int line=clut_start;line<clut_end;line++)
390 {
391 AtariClut& clut=GetClut(line);
392 clut.SetColor(rgbColor,index);
393 }
394 }
395 }
396
397 }
398 break;
399
400 case PALETTE_FROM_LAST_PIXELS:
401 {
402 // Cut the first 16 pixels on the left, and extract the palette for each
403 ImageContainer lockedPalette;
404 if (!lockedPalette.CreateFromImage(convertedPicture,convertedPicture.GetWidth()-17,0,17,convertedPicture.GetHeight()))
405 {
406 return false;
407 }
408
409 if (!convertedPicture.CreateFromImage(convertedPicture,0,0,convertedPicture.GetWidth()-17,convertedPicture.GetHeight()))
410 {
411 return false;
412 }
413
414 for (unsigned int line=0;line<lockedPalette.GetHeight();line++)
415 {
416 AtariClut& clut=GetClut(line);
417 RgbColor ignoreColor=lockedPalette.ReadColor(0,0);
418 for (unsigned int index=0;index<16;index++)
419 {
420 RgbColor rgbColor=lockedPalette.ReadColor(1+index,line);
421 if (rgbColor!=ignoreColor)
422 {
423 // This color should be locked for this index
424 clut.SetColor(rgbColor,index);
425 #ifdef ENABLE_PALETTE_TRACKING
426 if (line==0)
427 {
428 std::cout << "AtariPictureConverter::SetColor:" << (int)rgbColor.m_red << (int)rgbColor.m_green << (int)rgbColor.m_blue << "/" << index << "\r\n";
429 }
430 #endif
431 }
432 }
433 #ifdef ENABLE_PALETTE_TRACKING
434
435 {
436 // ------- debug start
437 std::string clutAsText;
438 //AtariClut& clut=GetClut(0);
439 clut.SaveClutAsText(clutAsText);
440 clutAsText+="\r\n";
441 std::cout << "AtariPictureConverter::ConvertLoopForLine:" << line << "=" << clutAsText;
442 // ------- debug end
443 }
444 #endif
445 //_BREAK_IF_((line==5));
446 }
447 }
448 break;
449 }
450
451
452 #ifdef ENABLE_PALETTE_TRACKING
453 {
454 // ------- debug start
455 std::string clutAsText;
456 AtariClut& clut=GetClut(0);
457 clut.SaveClutAsText(clutAsText);
458 clutAsText+="\r\n";
459 std::cout << "AtariPictureConverter::Convert:" << clutAsText;
460 // ------- debug end
461 }
462 #endif
463
464 set_buffer_size(convertedPicture.GetWidth(),convertedPicture.GetHeight());
465
466 clear_screen();
467
468 switch (m_format)
469 {
470 case FORMAT_SINGLE_PALETTE:
471 convertedPicture.ReduceColorDepth(&GetClut(0));
472 convert_shifter(convertedPicture);
473 break;
474
475 case FORMAT_MULTIPLE_PALETTE:
476 m_flagPalettePerScanline=true;
477 convertedPicture.ReduceColorDepthPerScanline(&m_cluts);
478 convert_shifter(convertedPicture);
479 break;
480
481 case FORMAT_MONOCHROME:
482 convertedPicture.ConvertToGrayScale(256);
483 {
484 /*
485 AtariClut clut;
486 clut.SetColor(RgbColor(0,0,0),0);
487 clut.SetColor(RgbColor(128,128,128),1);
488 clut.SetColor(RgbColor(255,255,255),2);
489
490 convertedPicture.ReduceColorDepth(&clut);
491 */
492 }
493 convert_shifter_monochrome(convertedPicture);
494 break;
495
496 default:
497 // Oops
498 return false;
499 break;
500 }
501 return true;
502 }
503
504
505 AtariClut& AtariPictureConverter::GetClut(unsigned int scanline)
506 {
507 if (m_flagPalettePerScanline) return m_cluts[scanline];
508 else return m_cluts[0];
509 }
510
511
512 void AtariPictureConverter::convert_shifter(const ImageContainer& sourcePicture)
513 {
514 //
515 // Perform the Atari ST bitplan conversion
516 // We proceed in three phases for the multi palette pictures, because we want the
517 // colors to stay about the same between one line and another, to avoid horrible
518 // color glitches when moving the pictures horizontally.
519
520 #ifdef ENABLE_PALETTE_TRACKING
521 // ------- debug start
522 std::string clutAsText;
523 AtariClut& clut=GetClut(0);
524 clut.SaveClutAsText(clutAsText);
525 clutAsText+="\r\n";
526 std::cout << "AtariPictureConverter::convert_shifter(start):" << clutAsText;
527 // ------- debug end
528 #endif
529 if (m_flagPalettePerScanline)
530 {
531 // Phase one: Collect palettes
532 {
533 for (unsigned int y=0;y<m_buffer_height;y++)
534 {
535 AtariClut& clut=GetClut(y);
536
537 for (unsigned int x=0;x<m_buffer_width;x++)
538 {
539 //_BREAK_IF_((y==5) && (x==565));
540 RgbColor rgb=sourcePicture.ReadColor(x,y);
541 clut.convert_pixel_shifter(rgb);
542 }
543 }
544 }
545
546 // Phase two: Optimize the palette
547 {
548 /*
549 for (unsigned int y=0;y<m_buffer_height-1;y++)
550 {
551 AtariClut& clut1=GetClut(y);
552 AtariClut& clut2=GetClut(y+1);
553 clut2.Reorder(clut1);
554 }
555 */
556 }
557 }
558
559
560 // Phase three: Generate the atari format bitplan
561 {
562 unsigned char *ptr_hires=(unsigned char*)m_buffer;
563 for (unsigned int y=0;y<m_buffer_height;y++)
564 {
565 //_BREAK_IF_(y==110);
566
567 AtariClut& clut=GetClut(y);
568
569 unsigned int x=0;
570 while (x<m_buffer_width)
571 {
572 unsigned int p0=0;
573 unsigned int p1=0;
574 unsigned int p2=0;
575 unsigned int p3=0;
576
577 for (int bit=0;bit<16;bit++)
578 {
579 p0<<=1;
580 p1<<=1;
581 p2<<=1;
582 p3<<=1;
583 RgbColor rgb=sourcePicture.ReadColor(x,y);
584 int color=clut.convert_pixel_shifter(rgb);
585 if (color&1)
586 {
587 p0|=1;
588 }
589 if (color&2)
590 {
591 p1|=1;
592 }
593 if (color&4)
594 {
595 p2|=1;
596 }
597 if (color&8)
598 {
599 p3|=1;
600 }
601 x++;
602 }
603 *ptr_hires++=static_cast<unsigned char>((p0>>8)&255);
604 *ptr_hires++=static_cast<unsigned char>(p0&255);
605 *ptr_hires++=static_cast<unsigned char>((p1>>8)&255);
606 *ptr_hires++=static_cast<unsigned char>(p1&255);
607 *ptr_hires++=static_cast<unsigned char>((p2>>8)&255);
608 *ptr_hires++=static_cast<unsigned char>(p2&255);
609 *ptr_hires++=static_cast<unsigned char>((p3>>8)&255);
610 *ptr_hires++=static_cast<unsigned char>(p3&255);
611 }
612 }
613 }
614
615 #ifdef ENABLE_PALETTE_TRACKING
616 {
617 // ------- debug start
618 std::string clutAsText;
619 AtariClut& clut=GetClut(0);
620 clut.SaveClutAsText(clutAsText);
621 clutAsText+="\r\n";
622 std::cout << "AtariPictureConverter::convert_shifter(end):" << clutAsText;
623 // ------- debug end
624 }
625 #endif
626 }
627
628
629
630
631 void AtariPictureConverter::convert_shifter_monochrome(const ImageContainer& sourcePicture)
632 {
633 //
634 // The Atari ST monochrome format is relatively simple: 640x400 pixels, 80 bytes per scanline
635 {
636 unsigned char *ptr_hires =GetBufferData(0);
637 unsigned int swapOffset = 0;
638 if (m_swapping==SWAPPING_ENABLED)
639 {
640 swapOffset=m_buffer_width/8;
641 }
642
643 for (unsigned int y=0;y<m_buffer_height;y++)
644 {
645 //_BREAK_IF_(y==110);
646
647 unsigned int x=0;
648 while (x<m_buffer_width)
649 {
650 unsigned short p0=0;
651 unsigned short p0_swap=0;
652
653 for (int bit=0;bit<16;bit++)
654 {
655 p0<<=1;
656 p0_swap<<=1;
657 RgbColor rgb=sourcePicture.ReadColor(x,y);
658 int average=rgb.GetRGBAverage();
659 if (average<85)
660 {
661 // Black
662 p0|=0;
663 p0_swap|=0;
664 }
665 else
666 if (average>=170)
667 {
668 // White
669 p0|=1;
670 p0_swap|=1;
671 }
672 else
673 {
674 // Grey
675 char dither=0;
676 dither=(bit&1)^(y&1);
677 p0|=dither;
678 p0_swap|=dither^1;
679 }
680 x++;
681 }
682 p0=~p0;
683 p0_swap=~p0_swap;
684 if (swapOffset)
685 {
686 ptr_hires[swapOffset+0]=static_cast<unsigned char>((p0_swap>>8)&255);
687 ptr_hires[swapOffset+1]=static_cast<unsigned char>(p0_swap&255);
688 }
689 *ptr_hires++=static_cast<unsigned char>((p0>>8)&255);
690 *ptr_hires++=static_cast<unsigned char>(p0&255);
691 }
692 ptr_hires+=swapOffset;
693 }
694 }
695 }
696
697
698
699 bool AtariPictureConverter::TakeSnapShot(ImageContainer& sourcePicture)
700 {
701 int pictureCount=1;
702 if (m_swapping==SWAPPING_ENABLED)
703 {
704 pictureCount=2;
705 }
706
707 if (!sourcePicture.Allocate(m_buffer_width,m_buffer_height*pictureCount,32))
708 {
709 return false;
710 }
711
712 switch (m_format)
713 {
714 case FORMAT_SINGLE_PALETTE:
715 case FORMAT_MULTIPLE_PALETTE:
716 {
717 #ifdef ENABLE_PALETTE_TRACKING
718 {
719 // ------- debug start
720 std::string clutAsText;
721 AtariClut& clut=GetClut(0);
722 clut.SaveClutAsText(clutAsText);
723 clutAsText+="\r\n";
724 std::cout << "AtariPictureConverter::TakeSnapShot:" << clutAsText;
725 // ------- debug end
726 }
727 #endif
728
729 unsigned short* pShort=(unsigned short*)m_buffer;
730 for (unsigned int y=0;y<m_buffer_height;y++)
731 {
732 AtariClut& clut=GetClut(y);
733
734 for (unsigned int x=0;x<m_buffer_width;x+=16)
735 {
736 unsigned short p0=*pShort++;
737 unsigned short p1=*pShort++;
738 unsigned short p2=*pShort++;
739 unsigned short p3=*pShort++;
740
741 p0=((p0&255)<<8) | (p0>>8);
742 p1=((p1&255)<<8) | (p1>>8);
743 p2=((p2&255)<<8) | (p2>>8);
744 p3=((p3&255)<<8) | (p3>>8);
745
746 for (int xx=0;xx<16;xx++)
747 {
748 int index=(p0&1) | ((p1&1)<<1) | ((p2&1)<<2) | ((p3&1)<<3);
749
750 ShifterColor shifterColor=clut.m_clut_index_to_color[index];
751
752 RgbColor rgb(shifterColor.GetRgb());
753
754 sourcePicture.WriteColor(rgb,x+15-xx,y);
755
756 p0>>=1;
757 p1>>=1;
758 p2>>=1;
759 p3>>=1;
760 }
761 }
762 }
763 }
764 break;
765
766 case FORMAT_MONOCHROME:
767 {
768 for (unsigned int y=0;y<m_buffer_height;y++)
769 {
770 for (int picture=0;picture<pictureCount;++picture)
771 {
772 unsigned short* pShort=(unsigned short*)m_buffer+pictureCount*m_buffer_width;
773 for (unsigned int x=0;x<m_buffer_width;x+=16)
774 {
775 unsigned short p0=*pShort++;
776
777 p0=((p0&255)<<8) | (p0>>8);
778
779 for (int xx=0;xx<16;xx++)
780 {
781 RgbColor rgb;
782 if (p0&1)
783 {
784 rgb.SetColor(0,0,0);
785 }
786 else
787 {
788 rgb.SetColor(255,255,255);
789 }
790
791 sourcePicture.WriteColor(rgb,x+15-xx,y);
792
793 p0>>=1;
794 }
795 }
796 }
797 }
798 }
799 break;
800
801 default:
802 // Oops
803 return false;
804 break;
805 }
806 return true;
807 }
808
809
810
811 void AtariPictureConverter::SaveToFile(long handle,int output_format)
812 {
813 int pictureCount=1;
814 if (m_swapping==SWAPPING_ENABLED)
815 {
816 pictureCount=2;
817 }
818
819 switch (output_format)
820 {
821 case DEVICE_FORMAT_RAWBUFFER_WITH_XYHEADER:
822 {
823 unsigned short x=static_cast<unsigned short>(get_buffer_width());
824 unsigned short y=static_cast<unsigned short>(get_buffer_height());
825
826 write(handle,&x,2);
827 write(handle,&y,2);
828 }
829 break;
830
831 case DEVICE_FORMAT_RAWBUFFER_WITH_PALETTE:
832 {
833 std::string clutAsText;
834 if (m_flagPalettePerScanline)
835 {
836 assert(m_cluts.size()==get_buffer_height());
837 std::map<int,AtariClut>::iterator it=m_cluts.begin();
838 while (it!=m_cluts.end())
839 {
840 AtariClut& clut=it->second;
841 clut.SaveClut(handle);
842 clut.SaveClutAsText(clutAsText);
843 clutAsText+="\r\n";
844 ++it;
845 }
846 }
847 else
848 {
849 AtariClut& clut=m_cluts[0];
850 clut.SaveClut(handle);
851 clut.SaveClutAsText(clutAsText);
852 }
853 clutAsText+="\r\n";
854 }
855 break;
856
857 case DEVICE_FORMAT_RAWBUFFER:
858 // No header for raw
859 break;
860 }
861 for (int picture=0;picture<pictureCount;picture++)
862 {
863 write(handle,GetBufferData(picture),GetBufferSize());
864 }
865 }

  ViewVC Help
Powered by ViewVC 1.1.26