r1005: Increase the number of displayed digits for resample audio dialog box
[cinelerra_cv/mob.git] / cinelerra / filetga.C
bloba223039b7b9dfcecb9377903c8100f42c368d38a
1 #include "asset.h"
2 #include "bcsignals.h"
3 #include "edit.h"
4 #include "filetga.h"
5 #include "language.h"
6 #include "mwindow.inc"
7 #include "vframe.h"
8 #include "mainerror.h"
10 #include <string.h>
11 #include <unistd.h>
13 /* Known image types. */
14 #define TGA_TYPE_MAPPED      1
15 #define TGA_TYPE_COLOR       2
16 #define TGA_TYPE_GRAY        3
18 /* Only known compression is RLE */
19 #define TGA_COMP_NONE        0 
20 #define TGA_COMP_RLE         1 
23 FileTGA::FileTGA(Asset *asset, File *file)
24  : FileList(asset, file, "TGALIST", ".tga", FILE_TGA, FILE_TGA_LIST)
26         temp = 0;
29 FileTGA::~FileTGA()
31         if(temp) delete temp;
34 int FileTGA::check_sig(Asset *asset)
38 // Test file extension
39         int result = 0;
40         char *ext = strrchr(asset->path, '.');
42         if(ext)
43         {
45                 if(!strncasecmp(ext, ".tga", 4)) result = 1;
47         }
51 // Test for list
52         if(!result)
53         {
54                 FILE *stream;
55                 if(!(stream = fopen(asset->path, "rb")))
56                 {
57 // file not found
58                         result = 0;
59                 }
60                 else
61                 {
62                         char test[16];
63                         fread(test, 16, 1, stream);
64                         fclose(stream);
65                         if(test[0] == 'T' && test[1] == 'G' && test[2] == 'A' && 
66                                 test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && 
67                                 test[6] == 'T')
68                         {
69                                 result = 1;
70                         }
71                         
72                 }
73         }
76         return result;
79 void FileTGA::get_parameters(BC_WindowBase *parent_window, 
80                 Asset *asset, 
81                 BC_WindowBase* &format_window,
82                 int audio_options,
83                 int video_options)
85         if(video_options)
86         {
87                 TGAConfigVideo *window = new TGAConfigVideo(parent_window, asset);
88                 format_window = window;
89                 window->create_objects();
90                 window->run_window();
91                 delete window;
92         }
95 #if 0
96 N_("RGB compressed")
97 N_("RGBA compressed")
98 N_("RGB uncompressed")
99 N_("RGBA uncompressed")
100 #endif
102 #define TGA_RGB_RLE "rle "
103 #define TGA_RGBA_RLE "rlea"
104 #define TGA_RGB "raw "
105 #define TGA_RGBA "rawa"
107 #define TGA_RGB_RLE_NAME "RGB compressed"
108 #define TGA_RGBA_RLE_NAME "RGBA compressed"
109 #define TGA_RGB_NAME "RGB uncompressed"
110 #define TGA_RGBA_NAME "RGBA uncompressed"
112 char* FileTGA::compression_to_str(char *compression)
114         if(!strcasecmp(compression, TGA_RGB_RLE)) return _(TGA_RGB_RLE_NAME);
115         if(!strcasecmp(compression, TGA_RGBA_RLE)) return _(TGA_RGBA_RLE_NAME);
116         if(!strcasecmp(compression, TGA_RGB)) return _(TGA_RGB_NAME);
117         if(!strcasecmp(compression, TGA_RGBA)) return _(TGA_RGBA_NAME);
118         return TGA_RGB_NAME;
121 char* FileTGA::str_to_compression(char *string)
123         if(!strcasecmp(compression_to_str(TGA_RGB_RLE), string)) return TGA_RGB_RLE;
124         if(!strcasecmp(compression_to_str(TGA_RGBA_RLE), string)) return TGA_RGBA_RLE;
125         if(!strcasecmp(compression_to_str(TGA_RGB), string)) return TGA_RGB;
126         if(!strcasecmp(compression_to_str(TGA_RGBA), string)) return TGA_RGBA;
127         return TGA_RGB;
130 int FileTGA::can_copy_from(Edit *edit, int64_t position)
132         if(edit->asset->format == FILE_TGA_LIST ||
133                 edit->asset->format == FILE_TGA)
134                 return 1;
135         
136         return 0;
140 int  FileTGA::colormodel_supported(int colormodel)
142         return colormodel;
145 int FileTGA::get_best_colormodel(Asset *asset, int driver)
147         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE) || 
148                 !strcasecmp(asset->vcodec, TGA_RGB)) return BC_RGB888;
149         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE) ||
150                 !strcasecmp(asset->vcodec, TGA_RGBA)) return BC_RGBA8888;
151         return BC_RGB888;
154 int FileTGA::read_frame(VFrame *frame, VFrame *data)
156         read_tga(asset, frame, data, temp);
157         return 0;
160 int FileTGA::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
162         TGAUnit *tga_unit = (TGAUnit*)unit;
164         write_tga(asset, frame, data, tga_unit->temp);
165         return 0;
168 FrameWriterUnit* FileTGA::new_writer_unit(FrameWriter *writer)
170         return new TGAUnit(this, writer);
173 int64_t FileTGA::get_memory_usage()
175         int64_t result = FileList::get_memory_usage();
176         if(temp) result += temp->get_data_size();
177         return result;
187 #define FOOTERSIZE 26
188 #define HEADERSIZE 18
189 int FileTGA::read_frame_header(char *path)
191         int result = 0;
193 //printf("FileTGA::read_frame_header 1\n");
194         FILE *stream;
196         if(!(stream = fopen(path, "rb")))
197         {
198                 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
199                 return 1;
200         }
202         unsigned char header[HEADERSIZE];
203         fread(header, HEADERSIZE, 1, stream);
204         fclose(stream);
206         asset->width = header[12] | (header[13] << 8);
207         asset->height = header[14] | (header[15] << 8);
208         int bpp = header[16];
209         int rle = header[2] & 0x8;
210         switch(bpp)
211         {
212                 case 32:
213                         if(rle) 
214                                 strcpy(asset->vcodec, TGA_RGBA_RLE);
215                         else
216                                 strcpy(asset->vcodec, TGA_RGBA);
217                         break;
218                 case 24:
219                         if(rle) 
220                                 strcpy(asset->vcodec, TGA_RGB_RLE);
221                         else
222                                 strcpy(asset->vcodec, TGA_RGB);
223                         break;
224         }
225 //printf("FileTGA::read_frame_header 2 %d %d\n", asset->width, asset->height);
227         return result;
230 void FileTGA::read_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
232 // Read header
233         unsigned char *footer, *header;
234         int input_cmodel;
235         int64_t file_offset = 0;
237         footer = data->get_data() + 
238                 data->get_compressed_size() - 
239                 FOOTERSIZE;
240         header = data->get_data();
241         file_offset += HEADERSIZE;
243         int image_type;
244         int image_compression;
245         switch(header[2])
246         {
247                 case 1:
248                         image_type = TGA_TYPE_MAPPED;
249                         image_compression = TGA_COMP_NONE;
250                         break;
251                 case 2:
252                         image_type = TGA_TYPE_COLOR;
253                         image_compression = TGA_COMP_NONE;
254                         break;
255                 case 3:
256                         image_type = TGA_TYPE_GRAY;
257                         image_compression = TGA_COMP_NONE;
258                         break;
259                 case 9:
260                         image_type = TGA_TYPE_MAPPED;
261                         image_compression = TGA_COMP_RLE;
262                         break;
263                 case 10:
264                         image_type = TGA_TYPE_COLOR;
265                         image_compression = TGA_COMP_RLE;
266                         break;
267                 case 11:
268                         image_type = TGA_TYPE_GRAY;
269                         image_compression = TGA_COMP_RLE;
270                         break;
271                 default:
272                         image_type = 0;
273         }
274         
275         int idlength = header[0];
276         int colormaptype = header[1];
277         int colormapindex = header[3] + header[4] * 256;
278         int colormaplength = header[5] + header[6] * 256;
279         int colormapsize = header[7];
280         int xorigin = header[8] + header[9] * 256;
281         int yorigin = header[10] + header[11] * 256;
282         int width = header[12] + header[13] * 256;
283         int height = header[14] + header[15] * 256;
284         int bpp = header[16];
285         int bytes = (bpp + 7) / 8;
286         int alphabits = header[17] & 0x0f;
287         int fliphoriz = (header[17] & 0x10) ? 1 : 0;
288         int flipvert = (header[17] & 0x20) ? 0 : 1;
289         int data_size = data->get_compressed_size();
291         if(idlength) file_offset += idlength;
293 // Get colormap
294         unsigned char *tga_cmap;
295         unsigned char colormap[4 * 256];
297         if(colormaptype == 1)
298         {
299                 int cmap_bytes = (colormapsize + 7) / 8;
300                 tga_cmap = data->get_data() + file_offset;
301                 file_offset += colormaplength * cmap_bytes;
302                 
303                 switch(colormapsize)
304                 {
305                         case 32:
306                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 1);
307                                 break;
308                         case 24:
309                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 0);
310                                 break;
311                         case 16:
312                                 upsample(colormap, tga_cmap, colormaplength, cmap_bytes);
313                                 break;
314                 }
315         }
317         int source_cmodel = BC_RGB888;
318         switch(bpp)
319         {
320                 case 32:
321                         source_cmodel = BC_RGBA8888;
322                         break;
323                 case 24:
324                         source_cmodel = BC_RGB888;
325                         break;
326         }
328 // Read image
329         VFrame *output_frame;
330         if(frame->get_color_model() == source_cmodel)
331         {
332                 output_frame = frame;
333         }
334         else
335         {
336                 if(temp && temp->get_color_model() != source_cmodel)
337                 {
338                         delete temp;
339                         temp = 0;
340                 }
341                 
342                 if(!temp)
343                 {
344                         temp = new VFrame(0, width, height, source_cmodel);
345                 }
346                 output_frame = temp;
347         }
349         if(flipvert)
350         {
351                 for(int i = height - 1; i >= 0; i--)
352                 {
353                         read_line(output_frame->get_rows()[i], 
354                                 data->get_data(), 
355                                 file_offset,
356                                 image_type,
357                                 bpp,
358                                 image_compression,
359                                 bytes,
360                                 width,
361                                 fliphoriz,
362                                 alphabits,
363                                 data_size);
364                 }
365         }
366         else
367         {
368                 for(int i = 0; i < height; i++)
369                 {
370                         read_line(output_frame->get_rows()[i], 
371                                 data->get_data(), 
372                                 file_offset,
373                                 image_type,
374                                 bpp,
375                                 image_compression,
376                                 bytes,
377                                 width,
378                                 fliphoriz,
379                                 alphabits,
380                                 data_size);
381                 }
382         }
384         if(output_frame != frame)
385         {
386                 cmodel_transfer(frame->get_rows(), 
387                         output_frame->get_rows(),
388                         frame->get_y(),
389                         frame->get_u(),
390                         frame->get_v(),
391                         output_frame->get_y(),
392                         output_frame->get_u(),
393                         output_frame->get_v(),
394                         0, 
395                         0, 
396                         width, 
397                         height,
398                         0, 
399                         0, 
400                         frame->get_w(), 
401                         frame->get_h(),
402                         output_frame->get_color_model(), 
403                         frame->get_color_model(),
404                         0,
405                         width,
406                         frame->get_w());
407         }
410 void FileTGA::write_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
412         unsigned char header[18];
413         unsigned char footer[26];
414         int64_t file_offset = 0;
415         int out_bpp = 0;
416         int rle = 0;
417         int dest_cmodel = BC_RGB888;
419 //printf("FileTGA::write_tga 1\n");
421         header[0] = 0;
422         header[1] = 0;
423         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE))
424         {
425                 header[2] = 10;
426         out_bpp = 4;
427                 rle = 1;
428         header[16] = 32; /* bpp */
429         header[17] = 0x28; /* alpha + orientation */
430                 dest_cmodel = BC_RGBA8888;
431         }
432         else
433         if(!strcasecmp(asset->vcodec, TGA_RGBA))
434         {
435                 header[2] = 2;
436         out_bpp = 4;
437                 rle = 0;
438         header[16] = 32; /* bpp */
439         header[17] = 0x28; /* alpha + orientation */
440                 dest_cmodel = BC_RGBA8888;
441         }
442         else
443         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE))
444         {
445                 header[2] = 10;
446         out_bpp = 3;
447                 rle = 1;
448         header[16] = 24; /* bpp */
449         header[17] = 0x20; /* alpha + orientation */
450                 dest_cmodel = BC_RGB888;
451         }
452         else
453         {
454                 header[2] = 2;
455         out_bpp = 3;
456                 rle = 0;
457         header[16] = 24; /* bpp */
458         header[17] = 0x20; /* alpha + orientation */
459                 dest_cmodel = BC_RGB888;
460         }
461     header[3] = header[4] = header[5] = header[6] = header[7] = 0;
462 //printf("FileTGA::write_tga 1\n");
464         VFrame *input_frame;
465         if(frame->get_color_model() == dest_cmodel)
466         {
467                 input_frame = frame;
468         }
469         else
470         {
471                 if(temp && temp->get_color_model() != dest_cmodel)
472                 {
473                         delete temp;
474                         temp = 0;
475                 }
476                 
477                 if(!temp)
478                 {
479                         temp = new VFrame(0, frame->get_w(), frame->get_h(), dest_cmodel);
480                 }
481                 input_frame = temp;
483                 cmodel_transfer(input_frame->get_rows(), 
484                         frame->get_rows(),
485                         input_frame->get_y(),
486                         input_frame->get_u(),
487                         input_frame->get_v(),
488                         frame->get_y(),
489                         frame->get_u(),
490                         frame->get_v(),
491                         0, 
492                         0, 
493                         frame->get_w(), 
494                         frame->get_h(),
495                         0, 
496                         0, 
497                         frame->get_w(), 
498                         frame->get_h(),
499                         frame->get_color_model(), 
500                         input_frame->get_color_model(),
501                         0,
502                         frame->get_w(),
503                         frame->get_w());
504         }
505 //printf("FileTGA::write_tga 1\n");
507 // xorigin
508 // yorigin
509         header[8]  = header[9]  = 0;
510         header[10] = header[11] = 0;
512         header[12] = input_frame->get_w() % 256;
513         header[13] = input_frame->get_w() / 256;
515         header[14] = input_frame->get_h() % 256;
516         header[15] = input_frame->get_h() / 256;
517 //printf("FileTGA::write_tga 1\n");
518         
519         write_data(header, data, file_offset, sizeof(header));
520 //printf("FileTGA::write_tga 1\n");
522         unsigned char *output = new unsigned char[out_bpp * input_frame->get_w()];
523 //printf("FileTGA::write_tga 1\n");
524         for(int i = 0; i < input_frame->get_h(); i++)
525         {
526 //printf("FileTGA::write_tga 2\n");
527                 bgr2rgb(output, input_frame->get_rows()[i], input_frame->get_w(), out_bpp, (out_bpp == 4));
528 //printf("FileTGA::write_tga 3\n");
529                 
530                 if(rle)
531                 {
532 //printf("FileTGA::write_tga 4\n");
533                         rle_write(output, 
534                                 input_frame->get_w(), 
535                                 out_bpp,
536                                 data,
537                                 file_offset);
538 //printf("FileTGA::write_tga 5\n");
539                 }
540                 else
541                 {
542 //printf("FileTGA::write_tga 6\n");
543                         write_data(output, 
544                                 data, 
545                                 file_offset, 
546                                 input_frame->get_w() * out_bpp);
547 //printf("FileTGA::write_tga 7\n");
548                 }
549         }
550 //printf("FileTGA::write_tga 8\n");
551         delete [] output;
552 //printf("FileTGA::write_tga 9\n");
555 void FileTGA::write_data(unsigned char *buffer, 
556         VFrame *data, 
557         int64_t &file_offset,
558         int64_t len)
560 //printf("FileTGA::write_data 1 %d\n", len);
561         if(data->get_compressed_allocated() <= data->get_compressed_size() + len)
562         {
563                 data->allocate_compressed_data((data->get_compressed_size() + len) * 2);
564         }
565 //printf("FileTGA::write_data 1 %d\n", len);
567         bcopy(buffer, data->get_data() + file_offset, len);
568 //printf("FileTGA::write_data 1 %d\n", len);
569         file_offset += len;
570 //printf("FileTGA::write_data 1 %d\n", len);
571         data->set_compressed_size(file_offset);
572 //printf("FileTGA::write_data 2 %d\n", len);
575 void FileTGA::read_line(unsigned char *row,
576         unsigned char *data,
577         int64_t &file_offset,
578         int image_type,
579         int bpp,
580         int image_compression,
581         int bytes,
582         int width,
583         int fliphoriz,
584         int alphabits,
585         int data_size)
587         if(file_offset >= data_size) return;
588         if(image_compression == TGA_COMP_RLE)
589         {
590                 rle_read(row,
591                         data,
592                         file_offset,
593                         bytes,
594                         width);
595         }
596         else
597         {
598                 if(file_offset + bytes * width <= data_size)
599                         bcopy(data + file_offset, row, bytes * width);
600                 file_offset += bytes * width;
601         }
602         
603         if(fliphoriz)
604         {
605                 flip_line(row, bytes, width);
606         }
607         
608         if(image_type == TGA_TYPE_COLOR)
609         {
610                 if(bpp == 16)
611                 {
612                         upsample(row, row, width, bytes);
613                 }
614                 else
615                 {
616                         bgr2rgb(row, row, width, bytes, alphabits);
617                 }
618         }
619         else
620         {
621                 ;
622         }
625 void FileTGA::flip_line(unsigned char *row, int bytes, int width)
627         unsigned char temp;
628         unsigned char *alt;
629         int x, s;
631         alt = row + (bytes * (width - 1));
633         for (x = 0; x * 2 <= width; x++)
634     {
635         for(s = 0; s < bytes; ++s)
636                 {
637                         temp = row[s];
638                         row[s] = alt[s];
639                         alt[s] = temp;
640                 }
642         row += bytes;
643         alt -= bytes;
644     }
647 void FileTGA::rle_read(unsigned char *row,
648         unsigned char *data,
649         int64_t &file_offset,
650         int bytes,
651         int width)
653         int repeat = 0;
654         int direct = 0;
655         unsigned char sample[4];
656         int head;
658         for(int x = 0; x < width; x++)
659         {
660                 if(repeat == 0 && direct == 0)
661                 {
662                         head = data[file_offset++];
663                         if(head == EOF)
664                         {
665                                 return;
666                         }
667                         else
668                         if(head >= 128)
669                         {
670                                 repeat = head - 127;
671                                 bcopy(data + file_offset, sample, bytes);
672                                 file_offset += bytes;
673                         }
674                         else
675                         {
676                                 direct = head + 1;
677                         }
678                 }
679                 
680                 if(repeat > 0)
681                 {
682                         for(int k = 0; k < bytes; k++)
683                         {
684                                 row[k] = sample[k];
685                         }
686                         
687                         repeat--;
688                 }
689                 else
690                 {
691                         bcopy(data + file_offset, row, bytes);
692                         file_offset += bytes;
693                         
694                         direct--;
695                 }
696                 
697                 row += bytes;
698         }
701 void FileTGA::rle_write(unsigned char *buffer, 
702         int width, 
703         int bytes, 
704         VFrame *frame, 
705         int64_t &file_offset)
707         int repeat = 0;
708         int direct = 0;
709         unsigned char *from = buffer;
710         unsigned char output;
711         int x;
712         
713         for(x = 1; x < width; ++x)
714         {
715 /* next pixel is different */
716                 if(memcmp(buffer, buffer + bytes, bytes))
717                 {
718                         if(repeat)
719                         {
720                                 output = 128 + repeat;
721                                 write_data(&output, frame, file_offset, 1);
722                                 write_data(from, frame, file_offset, bytes);
723                                 from = buffer + bytes;
724                                 repeat = 0;
725                                 direct = 0;
726                         }
727                         else
728                         {
729                                 direct++;
730                         }
731                 }
732                 else
733 /* next pixel is the same */
734                 {
735                         if(direct)
736                         {
737                                 output = direct - 1;
738                                 write_data(&output, frame, file_offset, 1);
739                                 write_data(from, frame, file_offset, bytes * direct);
740                                 from = buffer;
741                                 direct = 0;
742                                 repeat = 1;
743                         }
744                         else
745                         {
746                                 repeat++;
747                         }
748                 }
749                 
750                 if(repeat == 128)
751                 {
752                         output = 255;
753                         write_data(&output, frame, file_offset, 1);
754                         write_data(from, frame, file_offset, bytes);
755                         from = buffer + bytes;
756                         direct = 0;
757                         repeat = 0;
758                 }
759                 else
760                 if(direct == 128)
761                 {
762                         output = 127;
763                         write_data(&output, frame, file_offset, 1);
764                         write_data(from, frame, file_offset, direct * bytes);
765                         from = buffer + bytes;
766                         direct = 0;
767                         repeat = 0;
768                 }
769                 
770                 buffer += bytes;
771         }
772         
773         if(repeat > 0)
774         {
775                 output = 128 + repeat;
776                 write_data(&output, frame, file_offset, 1);
777                 write_data(from, frame, file_offset, bytes);
778         }
779         else
780         {
781                 output = direct;
782                 write_data(&output, frame, file_offset, 1);
783                 write_data(from, frame, file_offset, bytes * (direct + 1));
784         }
788 void FileTGA::bgr2rgb(unsigned char *dest,
789          unsigned char *src,
790          int width,
791          int bytes,
792          int alpha)
794         int x;
795         unsigned char r, g, b;
797         if(alpha)
798     {
799         for(x = 0; x < width; x++)
800                 {
801                         r = src[2];
802                         g = src[1];
803                         b = src[0];
804                         *(dest++) = r;
805                         *(dest++) = g;
806                         *(dest++) = b;
807                         *(dest++) = src[3];
809                         src += bytes;
810                 }
811     }
812         else
813     {
814         for(x = 0; x < width; x++)
815                 {
816                         r = src[2];
817                         g = src[1];
818                         b = src[0];
819                         *(dest++) = r;
820                         *(dest++) = g;
821                         *(dest++) = b;
823                         src += bytes;
824                 }
825     }
828 void FileTGA::upsample(unsigned char *dest,
829           unsigned char *src,
830           int width,
831           int bytes)
833         int x;
835         dest += (width - 1) * 3;
836         src += (width - 1) * bytes;
837         for(x = width - 1; x >= 0; x--)
838     {
839         dest[0] =  ((src[1] << 1) & 0xf8);
840         dest[0] += (dest[0] >> 5);
842         dest[1] =  ((src[0] & 0xe0) >> 2) + ((src[1] & 0x03) << 6);
843         dest[1] += (dest[1] >> 5);
845         dest[2] =  ((src[0] << 3) & 0xf8);
846         dest[2] += (dest[2] >> 5);
848         dest -= 3;
849         src -= bytes;
850     }
861 TGAUnit::TGAUnit(FileTGA *file, FrameWriter *writer)
862  : FrameWriterUnit(writer)
864         temp = 0;
865         this->file = file;
868 TGAUnit::~TGAUnit()
870         if(temp) delete temp;
885 TGAConfigVideo::TGAConfigVideo(BC_WindowBase *gui, Asset *asset)
886  : BC_Window(PROGRAM_NAME ": Video Compression",
887         gui->get_abs_cursor_x(1),
888         gui->get_abs_cursor_y(1),
889         400,
890         100)
892         this->gui = gui;
893         this->asset = asset;
895         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB_RLE)));
896         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA_RLE)));
897         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB)));
898         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA)));
901 TGAConfigVideo::~TGAConfigVideo()
903         compression_items.remove_all_objects();
906 int TGAConfigVideo::create_objects()
908         int x = 10, y = 10;
910         add_subwindow(new BC_Title(x, y, _("Compression:")));
911         TGACompression *textbox = new TGACompression(this, 
912                 x + 110, 
913                 y, 
914                 asset, 
915                 &compression_items);
916         textbox->create_objects();
917         add_subwindow(new BC_OKButton(this));
918         return 0;
921 int TGAConfigVideo::close_event()
923         set_done(0);
924         return 1;
928 TGACompression::TGACompression(TGAConfigVideo *gui,
929         int x, 
930         int y, 
931         Asset *asset, 
932         ArrayList<BC_ListBoxItem*> *compression_items)
933  : BC_PopupTextBox(gui,
934         compression_items,
935         FileTGA::compression_to_str(gui->asset->vcodec),
936         x, 
937         y, 
938         200,
939         200)
941         this->asset = asset;
943 int TGACompression::handle_event()
945         strcpy(asset->vcodec, FileTGA::str_to_compression(get_text()));
946         return 1;