inter-view tweaks, add clip preview, fix for dupl proxy vicon refs, fix track drag...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / filetga.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "asset.h"
23 #include "bcsignals.h"
24 #include "edit.h"
25 #include "filetga.h"
26 #include "language.h"
27 #include "mwindow.inc"
28 #include "vframe.h"
29 #include "mainerror.h"
30
31 #include <string.h>
32 #include <unistd.h>
33
34 /* Known image types. */
35 #define TGA_TYPE_MAPPED      1
36 #define TGA_TYPE_COLOR       2
37 #define TGA_TYPE_GRAY        3
38
39 /* Only known compression is RLE */
40 #define TGA_COMP_NONE        0
41 #define TGA_COMP_RLE         1
42
43
44 FileTGA::FileTGA(Asset *asset, File *file)
45  : FileList(asset, file, "TGALIST", ".tga", FILE_TGA, FILE_TGA_LIST)
46 {
47         temp = 0;
48 }
49
50 FileTGA::~FileTGA()
51 {
52         if(temp) delete temp;
53 }
54
55 int FileTGA::check_sig(Asset *asset)
56 {
57
58
59 // Test file extension
60         int result = 0;
61         char *ext = strrchr(asset->path, '.');
62
63         if(ext)
64         {
65
66                 if(!strncasecmp(ext, ".tga", 4)) result = 1;
67
68         }
69
70
71
72 // Test for list
73         if(!result)
74         {
75                 FILE *stream;
76                 if(!(stream = fopen(asset->path, "rb")))
77                 {
78 // file not found
79                         result = 0;
80                 }
81                 else
82                 {
83                         char test[16];
84                         (void)fread(test, 16, 1, stream);
85                         fclose(stream);
86                         if(test[0] == 'T' && test[1] == 'G' && test[2] == 'A' &&
87                                 test[3] == 'L' && test[4] == 'I' && test[5] == 'S' &&
88                                 test[6] == 'T')
89                         {
90                                 result = 1;
91                         }
92
93                 }
94         }
95
96
97         return result;
98 }
99
100 void FileTGA::get_parameters(BC_WindowBase *parent_window,
101         Asset *asset, BC_WindowBase* &format_window,
102         int audio_options, int video_options, EDL *edl)
103 {
104         if(video_options)
105         {
106                 TGAConfigVideo *window = new TGAConfigVideo(parent_window, asset);
107                 format_window = window;
108                 window->create_objects();
109                 window->run_window();
110                 delete window;
111         }
112 }
113
114 #if 0
115 N_("RGB compressed")
116 N_("RGBA compressed")
117 N_("RGB uncompressed")
118 N_("RGBA uncompressed")
119 #endif
120
121 #define TGA_RGB_RLE "rle "
122 #define TGA_RGBA_RLE "rlea"
123 #define TGA_RGB "raw "
124 #define TGA_RGBA "rawa"
125
126 #define TGA_RGB_RLE_NAME "RGB compressed"
127 #define TGA_RGBA_RLE_NAME "RGBA compressed"
128 #define TGA_RGB_NAME "RGB uncompressed"
129 #define TGA_RGBA_NAME "RGBA uncompressed"
130
131 const char* FileTGA::compression_to_str(const char *compression)
132 {
133         if(!strcasecmp(compression, TGA_RGB_RLE)) return _(TGA_RGB_RLE_NAME);
134         if(!strcasecmp(compression, TGA_RGBA_RLE)) return _(TGA_RGBA_RLE_NAME);
135         if(!strcasecmp(compression, TGA_RGB)) return _(TGA_RGB_NAME);
136         if(!strcasecmp(compression, TGA_RGBA)) return _(TGA_RGBA_NAME);
137         return TGA_RGB_NAME;
138 }
139
140 const char* FileTGA::str_to_compression(const char *string)
141 {
142         if(!strcasecmp(compression_to_str(TGA_RGB_RLE), string)) return TGA_RGB_RLE;
143         if(!strcasecmp(compression_to_str(TGA_RGBA_RLE), string)) return TGA_RGBA_RLE;
144         if(!strcasecmp(compression_to_str(TGA_RGB), string)) return TGA_RGB;
145         if(!strcasecmp(compression_to_str(TGA_RGBA), string)) return TGA_RGBA;
146         return TGA_RGB;
147 }
148
149 int FileTGA::can_copy_from(Asset *asset, int64_t position)
150 {
151         if(asset->format == FILE_TGA_LIST ||
152                 asset->format == FILE_TGA)
153                 return 1;
154
155         return 0;
156 }
157
158
159 int  FileTGA::colormodel_supported(int colormodel)
160 {
161         return colormodel;
162 }
163
164 int FileTGA::get_best_colormodel(Asset *asset, int driver)
165 {
166         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE) ||
167                 !strcasecmp(asset->vcodec, TGA_RGB)) return BC_RGB888;
168         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE) ||
169                 !strcasecmp(asset->vcodec, TGA_RGBA)) return BC_RGBA8888;
170         return BC_RGB888;
171 }
172
173 int FileTGA::read_frame(VFrame *frame, VFrame *data)
174 {
175         read_tga(asset, frame, data, temp);
176         return 0;
177 }
178
179 int FileTGA::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
180 {
181         TGAUnit *tga_unit = (TGAUnit*)unit;
182
183         write_tga(asset, frame, data, tga_unit->temp);
184         return 0;
185 }
186
187 FrameWriterUnit* FileTGA::new_writer_unit(FrameWriter *writer)
188 {
189         return new TGAUnit(this, writer);
190 }
191
192 int64_t FileTGA::get_memory_usage()
193 {
194         int64_t result = FileList::get_memory_usage();
195         if(temp) result += temp->get_data_size();
196         return result;
197 }
198
199
200
201
202
203
204
205
206 #define FOOTERSIZE 26
207 #define HEADERSIZE 18
208 int FileTGA::read_frame_header(char *path)
209 {
210         int result = 0;
211
212 //printf("FileTGA::read_frame_header 1\n");
213         FILE *stream;
214
215         if(!(stream = fopen(path, "rb")))
216         {
217                 eprintf(_("Error while opening \"%s\" for reading. \n%m\n"), asset->path);
218                 return 1;
219         }
220
221         unsigned char header[HEADERSIZE];
222         (void)fread(header, HEADERSIZE, 1, stream);
223         fclose(stream);
224
225         asset->width = header[12] | (header[13] << 8);
226         asset->height = header[14] | (header[15] << 8);
227         int bpp = header[16];
228         int rle = header[2] & 0x8;
229         switch(bpp)
230         {
231                 case 32:
232                         if(rle)
233                                 strcpy(asset->vcodec, TGA_RGBA_RLE);
234                         else
235                                 strcpy(asset->vcodec, TGA_RGBA);
236                         break;
237                 case 24:
238                         if(rle)
239                                 strcpy(asset->vcodec, TGA_RGB_RLE);
240                         else
241                                 strcpy(asset->vcodec, TGA_RGB);
242                         break;
243         }
244 //printf("FileTGA::read_frame_header 2 %d %d\n", asset->width, asset->height);
245
246         return result;
247 }
248
249 void FileTGA::read_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
250 {
251 // Read header
252         int64_t file_offset = 0;
253
254 //      unsigned char *footer = data->get_data() +
255 //              data->get_compressed_size() - FOOTERSIZE;
256         unsigned char *header = data->get_data();
257         file_offset += HEADERSIZE;
258
259         int image_type = 0;
260         int image_compression = 0;
261         switch(header[2])
262         {
263                 case 1:
264                         image_type = TGA_TYPE_MAPPED;
265                         image_compression = TGA_COMP_NONE;
266                         break;
267                 case 2:
268                         image_type = TGA_TYPE_COLOR;
269                         image_compression = TGA_COMP_NONE;
270                         break;
271                 case 3:
272                         image_type = TGA_TYPE_GRAY;
273                         image_compression = TGA_COMP_NONE;
274                         break;
275                 case 9:
276                         image_type = TGA_TYPE_MAPPED;
277                         image_compression = TGA_COMP_RLE;
278                         break;
279                 case 10:
280                         image_type = TGA_TYPE_COLOR;
281                         image_compression = TGA_COMP_RLE;
282                         break;
283                 case 11:
284                         image_type = TGA_TYPE_GRAY;
285                         image_compression = TGA_COMP_RLE;
286                         break;
287         }
288
289         int idlength = header[0];
290         int colormaptype = header[1];
291         //int colormapindex = header[3] + header[4] * 256;
292         int colormaplength = header[5] + header[6] * 256;
293         int colormapsize = header[7];
294         //int xorigin = header[8] + header[9] * 256;
295         //int yorigin = header[10] + header[11] * 256;
296         int width = header[12] + header[13] * 256;
297         int height = header[14] + header[15] * 256;
298         int bpp = header[16];
299         int bytes = (bpp + 7) / 8;
300         int alphabits = header[17] & 0x0f;
301         int fliphoriz = (header[17] & 0x10) ? 1 : 0;
302         int flipvert = (header[17] & 0x20) ? 0 : 1;
303         int data_size = data->get_compressed_size();
304
305         if(idlength) file_offset += idlength;
306
307 // Get colormap
308         unsigned char *tga_cmap;
309         unsigned char colormap[4 * 256];
310
311         if(colormaptype == 1)
312         {
313                 int cmap_bytes = (colormapsize + 7) / 8;
314                 tga_cmap = data->get_data() + file_offset;
315                 file_offset += colormaplength * cmap_bytes;
316
317                 switch(colormapsize)
318                 {
319                         case 32:
320                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 1);
321                                 break;
322                         case 24:
323                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 0);
324                                 break;
325                         case 16:
326                                 upsample(colormap, tga_cmap, colormaplength, cmap_bytes);
327                                 break;
328                 }
329         }
330
331         int source_cmodel = BC_RGB888;
332         switch(bpp)
333         {
334                 case 32:
335                         source_cmodel = BC_RGBA8888;
336                         break;
337                 case 24:
338                         source_cmodel = BC_RGB888;
339                         break;
340         }
341
342 // Read image
343         VFrame *output_frame;
344         if(frame->get_color_model() == source_cmodel)
345         {
346                 output_frame = frame;
347         }
348         else
349         {
350                 if(temp && temp->get_color_model() != source_cmodel)
351                 {
352                         delete temp;
353                         temp = 0;
354                 }
355
356                 if(!temp)
357                 {
358                         temp = new VFrame(width, height, source_cmodel, 0);
359                 }
360                 output_frame = temp;
361         }
362
363         if(flipvert)
364         {
365                 for(int i = height - 1; i >= 0; i--)
366                 {
367                         read_line(output_frame->get_rows()[i],
368                                 data->get_data(),
369                                 file_offset,
370                                 image_type,
371                                 bpp,
372                                 image_compression,
373                                 bytes,
374                                 width,
375                                 fliphoriz,
376                                 alphabits,
377                                 data_size);
378                 }
379         }
380         else
381         {
382                 for(int i = 0; i < height; i++)
383                 {
384                         read_line(output_frame->get_rows()[i],
385                                 data->get_data(),
386                                 file_offset,
387                                 image_type,
388                                 bpp,
389                                 image_compression,
390                                 bytes,
391                                 width,
392                                 fliphoriz,
393                                 alphabits,
394                                 data_size);
395                 }
396         }
397
398         if(output_frame != frame)
399         {
400                 BC_CModels::transfer(frame->get_rows(),
401                         output_frame->get_rows(),
402                         frame->get_y(),
403                         frame->get_u(),
404                         frame->get_v(),
405                         output_frame->get_y(),
406                         output_frame->get_u(),
407                         output_frame->get_v(),
408                         0,
409                         0,
410                         width,
411                         height,
412                         0,
413                         0,
414                         frame->get_w(),
415                         frame->get_h(),
416                         output_frame->get_color_model(),
417                         frame->get_color_model(),
418                         0,
419                         width,
420                         frame->get_w());
421         }
422 }
423
424 void FileTGA::write_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
425 {
426         unsigned char header[18];
427         //unsigned char footer[26];
428         int64_t file_offset = 0;
429         int out_bpp = 0;
430         int rle = 0;
431         int dest_cmodel = BC_RGB888;
432
433 //printf("FileTGA::write_tga 1\n");
434
435         header[0] = 0;
436         header[1] = 0;
437         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE))
438         {
439                 header[2] = 10;
440                 out_bpp = 4;
441                 rle = 1;
442                 header[16] = 32; /* bpp */
443                 header[17] = 0x28; /* alpha + orientation */
444                 dest_cmodel = BC_RGBA8888;
445         }
446         else
447         if(!strcasecmp(asset->vcodec, TGA_RGBA))
448         {
449                 header[2] = 2;
450                 out_bpp = 4;
451                 rle = 0;
452                 header[16] = 32; /* bpp */
453                 header[17] = 0x28; /* alpha + orientation */
454                 dest_cmodel = BC_RGBA8888;
455         }
456         else
457         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE))
458         {
459                 header[2] = 10;
460                 out_bpp = 3;
461                 rle = 1;
462                 header[16] = 24; /* bpp */
463                 header[17] = 0x20; /* alpha + orientation */
464                 dest_cmodel = BC_RGB888;
465         }
466         else
467         {
468                 header[2] = 2;
469                 out_bpp = 3;
470                 rle = 0;
471                 header[16] = 24; /* bpp */
472                 header[17] = 0x20; /* alpha + orientation */
473                 dest_cmodel = BC_RGB888;
474         }
475         header[3] = header[4] = header[5] = header[6] = header[7] = 0;
476 //printf("FileTGA::write_tga 1\n");
477
478         VFrame *input_frame;
479         if(frame->get_color_model() == dest_cmodel)
480         {
481                 input_frame = frame;
482         }
483         else
484         {
485                 if(temp && temp->get_color_model() != dest_cmodel)
486                 {
487                         delete temp;
488                         temp = 0;
489                 }
490
491                 if(!temp)
492                 {
493                         temp = new VFrame(0, -1, frame->get_w(), frame->get_h(), dest_cmodel, -1);
494                 }
495                 input_frame = temp;
496
497                 BC_CModels::transfer(input_frame->get_rows(),
498                         frame->get_rows(),
499                         input_frame->get_y(),
500                         input_frame->get_u(),
501                         input_frame->get_v(),
502                         frame->get_y(),
503                         frame->get_u(),
504                         frame->get_v(),
505                         0,
506                         0,
507                         frame->get_w(),
508                         frame->get_h(),
509                         0,
510                         0,
511                         frame->get_w(),
512                         frame->get_h(),
513                         frame->get_color_model(),
514                         input_frame->get_color_model(),
515                         0,
516                         frame->get_w(),
517                         frame->get_w());
518         }
519 //printf("FileTGA::write_tga 1\n");
520
521 // xorigin
522 // yorigin
523         header[8]  = header[9]  = 0;
524         header[10] = header[11] = 0;
525
526         header[12] = input_frame->get_w() % 256;
527         header[13] = input_frame->get_w() / 256;
528
529         header[14] = input_frame->get_h() % 256;
530         header[15] = input_frame->get_h() / 256;
531 //printf("FileTGA::write_tga 1\n");
532
533         write_data(header, data, file_offset, sizeof(header));
534 //printf("FileTGA::write_tga 1\n");
535
536         unsigned char *output = new unsigned char[out_bpp * input_frame->get_w()];
537 //printf("FileTGA::write_tga 1\n");
538         for(int i = 0; i < input_frame->get_h(); i++)
539         {
540 //printf("FileTGA::write_tga 2\n");
541                 bgr2rgb(output, input_frame->get_rows()[i], input_frame->get_w(), out_bpp, (out_bpp == 4));
542 //printf("FileTGA::write_tga 3\n");
543
544                 if(rle)
545                 {
546 //printf("FileTGA::write_tga 4\n");
547                         rle_write(output,
548                                 input_frame->get_w(),
549                                 out_bpp,
550                                 data,
551                                 file_offset);
552 //printf("FileTGA::write_tga 5\n");
553                 }
554                 else
555                 {
556 //printf("FileTGA::write_tga 6\n");
557                         write_data(output,
558                                 data,
559                                 file_offset,
560                                 input_frame->get_w() * out_bpp);
561 //printf("FileTGA::write_tga 7\n");
562                 }
563         }
564 //printf("FileTGA::write_tga 8\n");
565         delete [] output;
566 //printf("FileTGA::write_tga 9\n");
567 }
568
569 void FileTGA::write_data(unsigned char *buffer,
570         VFrame *data,
571         int64_t &file_offset,
572         int64_t len)
573 {
574 //printf("FileTGA::write_data 1 %d\n", len);
575         if(data->get_compressed_allocated() <= data->get_compressed_size() + len)
576         {
577                 data->allocate_compressed_data((data->get_compressed_size() + len) * 2);
578         }
579 //printf("FileTGA::write_data 1 %d\n", len);
580
581         bcopy(buffer, data->get_data() + file_offset, len);
582 //printf("FileTGA::write_data 1 %d\n", len);
583         file_offset += len;
584 //printf("FileTGA::write_data 1 %d\n", len);
585         data->set_compressed_size(file_offset);
586 //printf("FileTGA::write_data 2 %d\n", len);
587 }
588
589 void FileTGA::read_line(unsigned char *row,
590         unsigned char *data,
591         int64_t &file_offset,
592         int image_type,
593         int bpp,
594         int image_compression,
595         int bytes,
596         int width,
597         int fliphoriz,
598         int alphabits,
599         int data_size)
600 {
601         if(file_offset >= data_size) return;
602         if(image_compression == TGA_COMP_RLE)
603         {
604                 rle_read(row,
605                         data,
606                         file_offset,
607                         bytes,
608                         width);
609         }
610         else
611         {
612                 if(file_offset + bytes * width <= data_size)
613                         bcopy(data + file_offset, row, bytes * width);
614                 file_offset += bytes * width;
615         }
616
617         if(fliphoriz)
618         {
619                 flip_line(row, bytes, width);
620         }
621
622         if(image_type == TGA_TYPE_COLOR)
623         {
624                 if(bpp == 16)
625                 {
626                         upsample(row, row, width, bytes);
627                 }
628                 else
629                 {
630                         bgr2rgb(row, row, width, bytes, alphabits);
631                 }
632         }
633         else
634         {
635                 ;
636         }
637 }
638
639 void FileTGA::flip_line(unsigned char *row, int bytes, int width)
640 {
641         unsigned char temp;
642         unsigned char *alt;
643         int x, s;
644
645         alt = row + (bytes * (width - 1));
646
647         for (x = 0; x * 2 <= width; x++)
648     {
649         for(s = 0; s < bytes; ++s)
650                 {
651                         temp = row[s];
652                         row[s] = alt[s];
653                         alt[s] = temp;
654                 }
655
656         row += bytes;
657         alt -= bytes;
658     }
659 }
660
661 void FileTGA::rle_read(unsigned char *row,
662         unsigned char *data,
663         int64_t &file_offset,
664         int bytes,
665         int width)
666 {
667         int repeat = 0;
668         int direct = 0;
669         unsigned char sample[4];
670         int head;
671
672         for(int x = 0; x < width; x++)
673         {
674                 if(repeat == 0 && direct == 0)
675                 {
676                         head = data[file_offset++];
677                         if(head == EOF)
678                         {
679                                 return;
680                         }
681                         else
682                         if(head >= 128)
683                         {
684                                 repeat = head - 127;
685                                 bcopy(data + file_offset, sample, bytes);
686                                 file_offset += bytes;
687                         }
688                         else
689                         {
690                                 direct = head + 1;
691                         }
692                 }
693
694                 if(repeat > 0)
695                 {
696                         for(int k = 0; k < bytes; k++)
697                         {
698                                 row[k] = sample[k];
699                         }
700
701                         repeat--;
702                 }
703                 else
704                 {
705                         bcopy(data + file_offset, row, bytes);
706                         file_offset += bytes;
707
708                         direct--;
709                 }
710
711                 row += bytes;
712         }
713 }
714
715 void FileTGA::rle_write(unsigned char *buffer,
716         int width,
717         int bytes,
718         VFrame *frame,
719         int64_t &file_offset)
720 {
721         int repeat = 0;
722         int direct = 0;
723         unsigned char *from = buffer;
724         unsigned char output;
725         int x;
726
727         for(x = 1; x < width; ++x)
728         {
729 /* next pixel is different */
730                 if(memcmp(buffer, buffer + bytes, bytes))
731                 {
732                         if(repeat)
733                         {
734                                 output = 128 + repeat;
735                                 write_data(&output, frame, file_offset, 1);
736                                 write_data(from, frame, file_offset, bytes);
737                                 from = buffer + bytes;
738                                 repeat = 0;
739                                 direct = 0;
740                         }
741                         else
742                         {
743                                 direct++;
744                         }
745                 }
746                 else
747 /* next pixel is the same */
748                 {
749                         if(direct)
750                         {
751                                 output = direct - 1;
752                                 write_data(&output, frame, file_offset, 1);
753                                 write_data(from, frame, file_offset, bytes * direct);
754                                 from = buffer;
755                                 direct = 0;
756                                 repeat = 1;
757                         }
758                         else
759                         {
760                                 repeat++;
761                         }
762                 }
763
764                 if(repeat == 128)
765                 {
766                         output = 255;
767                         write_data(&output, frame, file_offset, 1);
768                         write_data(from, frame, file_offset, bytes);
769                         from = buffer + bytes;
770                         direct = 0;
771                         repeat = 0;
772                 }
773                 else
774                 if(direct == 128)
775                 {
776                         output = 127;
777                         write_data(&output, frame, file_offset, 1);
778                         write_data(from, frame, file_offset, direct * bytes);
779                         from = buffer + bytes;
780                         direct = 0;
781                         repeat = 0;
782                 }
783
784                 buffer += bytes;
785         }
786
787         if(repeat > 0)
788         {
789                 output = 128 + repeat;
790                 write_data(&output, frame, file_offset, 1);
791                 write_data(from, frame, file_offset, bytes);
792         }
793         else
794         {
795                 output = direct;
796                 write_data(&output, frame, file_offset, 1);
797                 write_data(from, frame, file_offset, bytes * (direct + 1));
798         }
799 }
800
801
802 void FileTGA::bgr2rgb(unsigned char *dest,
803          unsigned char *src,
804          int width,
805          int bytes,
806          int alpha)
807 {
808         int x;
809         unsigned char r, g, b;
810
811         if(alpha)
812     {
813         for(x = 0; x < width; x++)
814                 {
815                         r = src[2];
816                         g = src[1];
817                         b = src[0];
818                         *(dest++) = r;
819                         *(dest++) = g;
820                         *(dest++) = b;
821                         *(dest++) = src[3];
822
823                         src += bytes;
824                 }
825     }
826         else
827     {
828         for(x = 0; x < width; x++)
829                 {
830                         r = src[2];
831                         g = src[1];
832                         b = src[0];
833                         *(dest++) = r;
834                         *(dest++) = g;
835                         *(dest++) = b;
836
837                         src += bytes;
838                 }
839     }
840 }
841
842 void FileTGA::upsample(unsigned char *dest,
843           unsigned char *src,
844           int width,
845           int bytes)
846 {
847         int x;
848
849         dest += (width - 1) * 3;
850         src += (width - 1) * bytes;
851         for(x = width - 1; x >= 0; x--)
852     {
853         dest[0] =  ((src[1] << 1) & 0xf8);
854         dest[0] += (dest[0] >> 5);
855
856         dest[1] =  ((src[0] & 0xe0) >> 2) + ((src[1] & 0x03) << 6);
857         dest[1] += (dest[1] >> 5);
858
859         dest[2] =  ((src[0] << 3) & 0xf8);
860         dest[2] += (dest[2] >> 5);
861
862         dest -= 3;
863         src -= bytes;
864     }
865 }
866
867
868
869
870
871
872
873
874
875 TGAUnit::TGAUnit(FileTGA *file, FrameWriter *writer)
876  : FrameWriterUnit(writer)
877 {
878         temp = 0;
879         this->file = file;
880 }
881
882 TGAUnit::~TGAUnit()
883 {
884         if(temp) delete temp;
885 }
886
887
888
889
890
891
892
893
894
895
896
897
898
899 TGAConfigVideo::TGAConfigVideo(BC_WindowBase *gui, Asset *asset)
900  : BC_Window(_(PROGRAM_NAME ": Video Compression"),
901         gui->get_abs_cursor_x(1),
902         gui->get_abs_cursor_y(1),
903         400,
904         100)
905 {
906         this->gui = gui;
907         this->asset = asset;
908
909         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB_RLE)));
910         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA_RLE)));
911         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB)));
912         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA)));
913 }
914
915 TGAConfigVideo::~TGAConfigVideo()
916 {
917         compression_items.remove_all_objects();
918 }
919
920 void TGAConfigVideo::create_objects()
921 {
922         lock_window("TGAConfigVideo::create_objects");
923         int x = 10, y = 10;
924
925         add_subwindow(new BC_Title(x, y, _("Compression:")));
926         TGACompression *textbox = new TGACompression(this,
927                 x + 110,
928                 y,
929                 asset,
930                 &compression_items);
931         textbox->create_objects();
932         add_subwindow(new BC_OKButton(this));
933         show_window(1);
934         unlock_window();
935 }
936
937 int TGAConfigVideo::close_event()
938 {
939         set_done(0);
940         return 1;
941 }
942
943
944 TGACompression::TGACompression(TGAConfigVideo *gui,
945         int x,
946         int y,
947         Asset *asset,
948         ArrayList<BC_ListBoxItem*> *compression_items)
949  : BC_PopupTextBox(gui,
950         compression_items,
951         FileTGA::compression_to_str(gui->asset->vcodec),
952         x,
953         y,
954         200,
955         200)
956 {
957         this->asset = asset;
958 }
959 int TGACompression::handle_event()
960 {
961         strcpy(asset->vcodec, FileTGA::str_to_compression(get_text()));
962         return 1;
963 }