r663: This commit was generated by cvs2svn to compensate for changes in r662,
[cinelerra_cv.git] / cinelerra / filetga.C
blob74f08977cfc05cb2354b9d6c70d976ba46ff61d8
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"
9 #include <string.h>
10 #include <unistd.h>
12 /* Known image types. */
13 #define TGA_TYPE_MAPPED      1
14 #define TGA_TYPE_COLOR       2
15 #define TGA_TYPE_GRAY        3
17 /* Only known compression is RLE */
18 #define TGA_COMP_NONE        0 
19 #define TGA_COMP_RLE         1 
22 FileTGA::FileTGA(Asset *asset, File *file)
23  : FileList(asset, file, "TGALIST", ".tga", FILE_TGA, FILE_TGA_LIST)
25         temp = 0;
28 FileTGA::~FileTGA()
30         if(temp) delete temp;
33 int FileTGA::check_sig(Asset *asset)
36 SET_TRACE
37 // Test file extension
38         int result = 0;
39         char *ext = strrchr(asset->path, '.');
40 SET_TRACE
41         if(ext)
42         {
43 SET_TRACE
44                 if(!strncasecmp(ext, ".tga", 4)) result = 1;
45 SET_TRACE
46         }
48 SET_TRACE
50 // Test for list
51         if(!result)
52         {
53                 FILE *stream;
54                 if(!(stream = fopen(asset->path, "rb")))
55                 {
56 // file not found
57                         result = 0;
58                 }
59                 else
60                 {
61                         char test[16];
62                         fread(test, 16, 1, stream);
63                         fclose(stream);
64                         if(test[0] == 'T' && test[1] == 'G' && test[2] == 'A' && 
65                                 test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && 
66                                 test[6] == 'T')
67                         {
68                                 result = 1;
69                         }
70                         
71                 }
72         }
73 SET_TRACE
75         return result;
78 void FileTGA::get_parameters(BC_WindowBase *parent_window, 
79                 Asset *asset, 
80                 BC_WindowBase* &format_window,
81                 int audio_options,
82                 int video_options)
84         if(video_options)
85         {
86                 TGAConfigVideo *window = new TGAConfigVideo(parent_window, asset);
87                 format_window = window;
88                 window->create_objects();
89                 window->run_window();
90                 delete window;
91         }
94 #if 0
95 N_("RGB compressed")
96 N_("RGBA compressed")
97 N_("RGB uncompressed")
98 N_("RGBA uncompressed")
99 #endif
101 #define TGA_RGB_RLE "rle "
102 #define TGA_RGBA_RLE "rlea"
103 #define TGA_RGB "raw "
104 #define TGA_RGBA "rawa"
106 #define TGA_RGB_RLE_NAME "RGB compressed"
107 #define TGA_RGBA_RLE_NAME "RGBA compressed"
108 #define TGA_RGB_NAME "RGB uncompressed"
109 #define TGA_RGBA_NAME "RGBA uncompressed"
111 char* FileTGA::compression_to_str(char *compression)
113         if(!strcasecmp(compression, TGA_RGB_RLE)) return _(TGA_RGB_RLE_NAME);
114         if(!strcasecmp(compression, TGA_RGBA_RLE)) return _(TGA_RGBA_RLE_NAME);
115         if(!strcasecmp(compression, TGA_RGB)) return _(TGA_RGB_NAME);
116         if(!strcasecmp(compression, TGA_RGBA)) return _(TGA_RGBA_NAME);
117         return TGA_RGB_NAME;
120 char* FileTGA::str_to_compression(char *string)
122         if(!strcasecmp(compression_to_str(TGA_RGB_RLE), string)) return TGA_RGB_RLE;
123         if(!strcasecmp(compression_to_str(TGA_RGBA_RLE), string)) return TGA_RGBA_RLE;
124         if(!strcasecmp(compression_to_str(TGA_RGB), string)) return TGA_RGB;
125         if(!strcasecmp(compression_to_str(TGA_RGBA), string)) return TGA_RGBA;
126         return TGA_RGB;
129 int FileTGA::can_copy_from(Edit *edit, int64_t position)
131         if(edit->asset->format == FILE_TGA_LIST ||
132                 edit->asset->format == FILE_TGA)
133                 return 1;
134         
135         return 0;
139 int  FileTGA::colormodel_supported(int colormodel)
141         return colormodel;
144 int FileTGA::get_best_colormodel(Asset *asset, int driver)
146         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE) || 
147                 !strcasecmp(asset->vcodec, TGA_RGB)) return BC_RGB888;
148         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE) ||
149                 !strcasecmp(asset->vcodec, TGA_RGBA)) return BC_RGBA8888;
150         return BC_RGB888;
153 int FileTGA::read_frame(VFrame *frame, VFrame *data)
155         read_tga(asset, frame, data, temp);
156         return 0;
159 int FileTGA::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
161         TGAUnit *tga_unit = (TGAUnit*)unit;
163         write_tga(asset, frame, data, tga_unit->temp);
164         return 0;
167 FrameWriterUnit* FileTGA::new_writer_unit(FrameWriter *writer)
169         return new TGAUnit(this, writer);
172 int FileTGA::get_memory_usage()
174         int result = FileList::get_memory_usage();
175         if(temp) result += temp->get_data_size();
176         return result;
186 #define FOOTERSIZE 26
187 #define HEADERSIZE 18
188 int FileTGA::read_frame_header(char *path)
190         int result = 0;
192 //printf("FileTGA::read_frame_header 1\n");
193         FILE *stream;
195         if(!(stream = fopen(path, "rb")))
196         {
197                 perror("FileTGA::read_frame_header");
198                 return 1;
199         }
201         unsigned char header[HEADERSIZE];
202         fread(header, HEADERSIZE, 1, stream);
203         fclose(stream);
205         asset->width = header[12] | (header[13] << 8);
206         asset->height = header[14] | (header[15] << 8);
207         int bpp = header[16];
208         int rle = header[2] & 0x8;
209         switch(bpp)
210         {
211                 case 32:
212                         if(rle) 
213                                 strcpy(asset->vcodec, TGA_RGBA_RLE);
214                         else
215                                 strcpy(asset->vcodec, TGA_RGBA);
216                         break;
217                 case 24:
218                         if(rle) 
219                                 strcpy(asset->vcodec, TGA_RGB_RLE);
220                         else
221                                 strcpy(asset->vcodec, TGA_RGB);
222                         break;
223         }
224 //printf("FileTGA::read_frame_header 2 %d %d\n", asset->width, asset->height);
226         return result;
229 void FileTGA::read_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
231 // Read header
232         unsigned char *footer, *header;
233         int input_cmodel;
234         int64_t file_offset = 0;
236         footer = data->get_data() + 
237                 data->get_compressed_size() - 
238                 FOOTERSIZE;
239         header = data->get_data();
240         file_offset += HEADERSIZE;
242         int image_type;
243         int image_compression;
244         switch(header[2])
245         {
246                 case 1:
247                         image_type = TGA_TYPE_MAPPED;
248                         image_compression = TGA_COMP_NONE;
249                         break;
250                 case 2:
251                         image_type = TGA_TYPE_COLOR;
252                         image_compression = TGA_COMP_NONE;
253                         break;
254                 case 3:
255                         image_type = TGA_TYPE_GRAY;
256                         image_compression = TGA_COMP_NONE;
257                         break;
258                 case 9:
259                         image_type = TGA_TYPE_MAPPED;
260                         image_compression = TGA_COMP_RLE;
261                         break;
262                 case 10:
263                         image_type = TGA_TYPE_COLOR;
264                         image_compression = TGA_COMP_RLE;
265                         break;
266                 case 11:
267                         image_type = TGA_TYPE_GRAY;
268                         image_compression = TGA_COMP_RLE;
269                         break;
270                 default:
271                         image_type = 0;
272         }
273         
274         int idlength = header[0];
275         int colormaptype = header[1];
276         int colormapindex = header[3] + header[4] * 256;
277         int colormaplength = header[5] + header[6] * 256;
278         int colormapsize = header[7];
279         int xorigin = header[8] + header[9] * 256;
280         int yorigin = header[10] + header[11] * 256;
281         int width = header[12] + header[13] * 256;
282         int height = header[14] + header[15] * 256;
283         int bpp = header[16];
284         int bytes = (bpp + 7) / 8;
285         int alphabits = header[17] & 0x0f;
286         int fliphoriz = (header[17] & 0x10) ? 1 : 0;
287         int flipvert = (header[17] & 0x20) ? 0 : 1;
288         int data_size = data->get_compressed_size();
290         if(idlength) file_offset += idlength;
292 // Get colormap
293         unsigned char *tga_cmap;
294         unsigned char colormap[4 * 256];
296         if(colormaptype == 1)
297         {
298                 int cmap_bytes = (colormapsize + 7) / 8;
299                 tga_cmap = data->get_data() + file_offset;
300                 file_offset += colormaplength * cmap_bytes;
301                 
302                 switch(colormapsize)
303                 {
304                         case 32:
305                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 1);
306                                 break;
307                         case 24:
308                                 bgr2rgb(colormap, tga_cmap, colormaplength, cmap_bytes, 0);
309                                 break;
310                         case 16:
311                                 upsample(colormap, tga_cmap, colormaplength, cmap_bytes);
312                                 break;
313                 }
314         }
316         int source_cmodel = BC_RGB888;
317         switch(bpp)
318         {
319                 case 32:
320                         source_cmodel = BC_RGBA8888;
321                         break;
322                 case 24:
323                         source_cmodel = BC_RGB888;
324                         break;
325         }
327 // Read image
328         VFrame *output_frame;
329         if(frame->get_color_model() == source_cmodel)
330         {
331                 output_frame = frame;
332         }
333         else
334         {
335                 if(temp && temp->get_color_model() != source_cmodel)
336                 {
337                         delete temp;
338                         temp = 0;
339                 }
340                 
341                 if(!temp)
342                 {
343                         temp = new VFrame(0, width, height, source_cmodel);
344                 }
345                 output_frame = temp;
346         }
348         if(flipvert)
349         {
350                 for(int i = height - 1; i >= 0; i--)
351                 {
352                         read_line(output_frame->get_rows()[i], 
353                                 data->get_data(), 
354                                 file_offset,
355                                 image_type,
356                                 bpp,
357                                 image_compression,
358                                 bytes,
359                                 width,
360                                 fliphoriz,
361                                 alphabits,
362                                 data_size);
363                 }
364         }
365         else
366         {
367                 for(int i = 0; i < height; i++)
368                 {
369                         read_line(output_frame->get_rows()[i], 
370                                 data->get_data(), 
371                                 file_offset,
372                                 image_type,
373                                 bpp,
374                                 image_compression,
375                                 bytes,
376                                 width,
377                                 fliphoriz,
378                                 alphabits,
379                                 data_size);
380                 }
381         }
383         if(output_frame != frame)
384         {
385                 cmodel_transfer(frame->get_rows(), 
386                         output_frame->get_rows(),
387                         frame->get_y(),
388                         frame->get_u(),
389                         frame->get_v(),
390                         output_frame->get_y(),
391                         output_frame->get_u(),
392                         output_frame->get_v(),
393                         0, 
394                         0, 
395                         width, 
396                         height,
397                         0, 
398                         0, 
399                         frame->get_w(), 
400                         frame->get_h(),
401                         output_frame->get_color_model(), 
402                         frame->get_color_model(),
403                         0,
404                         width,
405                         frame->get_w());
406         }
409 void FileTGA::write_tga(Asset *asset, VFrame *frame, VFrame *data, VFrame* &temp)
411         unsigned char header[18];
412         unsigned char footer[26];
413         int64_t file_offset = 0;
414         int out_bpp = 0;
415         int rle = 0;
416         int dest_cmodel = BC_RGB888;
418 //printf("FileTGA::write_tga 1\n");
420         header[0] = 0;
421         header[1] = 0;
422         if(!strcasecmp(asset->vcodec, TGA_RGBA_RLE))
423         {
424                 header[2] = 10;
425         out_bpp = 4;
426                 rle = 1;
427         header[16] = 32; /* bpp */
428         header[17] = 0x28; /* alpha + orientation */
429                 dest_cmodel = BC_RGBA8888;
430         }
431         else
432         if(!strcasecmp(asset->vcodec, TGA_RGBA))
433         {
434                 header[2] = 2;
435         out_bpp = 4;
436                 rle = 0;
437         header[16] = 32; /* bpp */
438         header[17] = 0x28; /* alpha + orientation */
439                 dest_cmodel = BC_RGBA8888;
440         }
441         else
442         if(!strcasecmp(asset->vcodec, TGA_RGB_RLE))
443         {
444                 header[2] = 10;
445         out_bpp = 3;
446                 rle = 1;
447         header[16] = 24; /* bpp */
448         header[17] = 0x20; /* alpha + orientation */
449                 dest_cmodel = BC_RGB888;
450         }
451         else
452         {
453                 header[2] = 2;
454         out_bpp = 3;
455                 rle = 0;
456         header[16] = 24; /* bpp */
457         header[17] = 0x20; /* alpha + orientation */
458                 dest_cmodel = BC_RGB888;
459         }
460     header[3] = header[4] = header[5] = header[6] = header[7] = 0;
461 //printf("FileTGA::write_tga 1\n");
463         VFrame *input_frame;
464         if(frame->get_color_model() == dest_cmodel)
465         {
466                 input_frame = frame;
467         }
468         else
469         {
470                 if(temp && temp->get_color_model() != dest_cmodel)
471                 {
472                         delete temp;
473                         temp = 0;
474                 }
475                 
476                 if(!temp)
477                 {
478                         temp = new VFrame(0, frame->get_w(), frame->get_h(), dest_cmodel);
479                 }
480                 input_frame = temp;
482                 cmodel_transfer(input_frame->get_rows(), 
483                         frame->get_rows(),
484                         input_frame->get_y(),
485                         input_frame->get_u(),
486                         input_frame->get_v(),
487                         frame->get_y(),
488                         frame->get_u(),
489                         frame->get_v(),
490                         0, 
491                         0, 
492                         frame->get_w(), 
493                         frame->get_h(),
494                         0, 
495                         0, 
496                         frame->get_w(), 
497                         frame->get_h(),
498                         frame->get_color_model(), 
499                         input_frame->get_color_model(),
500                         0,
501                         frame->get_w(),
502                         frame->get_w());
503         }
504 //printf("FileTGA::write_tga 1\n");
506 // xorigin
507 // yorigin
508         header[8]  = header[9]  = 0;
509         header[10] = header[11] = 0;
511         header[12] = input_frame->get_w() % 256;
512         header[13] = input_frame->get_w() / 256;
514         header[14] = input_frame->get_h() % 256;
515         header[15] = input_frame->get_h() / 256;
516 //printf("FileTGA::write_tga 1\n");
517         
518         write_data(header, data, file_offset, sizeof(header));
519 //printf("FileTGA::write_tga 1\n");
521         unsigned char *output = new unsigned char[out_bpp * input_frame->get_w()];
522 //printf("FileTGA::write_tga 1\n");
523         for(int i = 0; i < input_frame->get_h(); i++)
524         {
525 //printf("FileTGA::write_tga 2\n");
526                 bgr2rgb(output, input_frame->get_rows()[i], input_frame->get_w(), out_bpp, (out_bpp == 4));
527 //printf("FileTGA::write_tga 3\n");
528                 
529                 if(rle)
530                 {
531 //printf("FileTGA::write_tga 4\n");
532                         rle_write(output, 
533                                 input_frame->get_w(), 
534                                 out_bpp,
535                                 data,
536                                 file_offset);
537 //printf("FileTGA::write_tga 5\n");
538                 }
539                 else
540                 {
541 //printf("FileTGA::write_tga 6\n");
542                         write_data(output, 
543                                 data, 
544                                 file_offset, 
545                                 input_frame->get_w() * out_bpp);
546 //printf("FileTGA::write_tga 7\n");
547                 }
548         }
549 //printf("FileTGA::write_tga 8\n");
550         delete [] output;
551 //printf("FileTGA::write_tga 9\n");
554 void FileTGA::write_data(unsigned char *buffer, 
555         VFrame *data, 
556         int64_t &file_offset,
557         int64_t len)
559 //printf("FileTGA::write_data 1 %d\n", len);
560         if(data->get_compressed_allocated() <= data->get_compressed_size() + len)
561         {
562                 data->allocate_compressed_data((data->get_compressed_size() + len) * 2);
563         }
564 //printf("FileTGA::write_data 1 %d\n", len);
566         bcopy(buffer, data->get_data() + file_offset, len);
567 //printf("FileTGA::write_data 1 %d\n", len);
568         file_offset += len;
569 //printf("FileTGA::write_data 1 %d\n", len);
570         data->set_compressed_size(file_offset);
571 //printf("FileTGA::write_data 2 %d\n", len);
574 void FileTGA::read_line(unsigned char *row,
575         unsigned char *data,
576         int64_t &file_offset,
577         int image_type,
578         int bpp,
579         int image_compression,
580         int bytes,
581         int width,
582         int fliphoriz,
583         int alphabits,
584         int data_size)
586         if(file_offset >= data_size) return;
587         if(image_compression == TGA_COMP_RLE)
588         {
589                 rle_read(row,
590                         data,
591                         file_offset,
592                         bytes,
593                         width);
594         }
595         else
596         {
597                 if(file_offset + bytes * width <= data_size)
598                         bcopy(data + file_offset, row, bytes * width);
599                 file_offset += bytes * width;
600         }
601         
602         if(fliphoriz)
603         {
604                 flip_line(row, bytes, width);
605         }
606         
607         if(image_type == TGA_TYPE_COLOR)
608         {
609                 if(bpp == 16)
610                 {
611                         upsample(row, row, width, bytes);
612                 }
613                 else
614                 {
615                         bgr2rgb(row, row, width, bytes, alphabits);
616                 }
617         }
618         else
619         {
620                 ;
621         }
624 void FileTGA::flip_line(unsigned char *row, int bytes, int width)
626         unsigned char temp;
627         unsigned char *alt;
628         int x, s;
630         alt = row + (bytes * (width - 1));
632         for (x = 0; x * 2 <= width; x++)
633     {
634         for(s = 0; s < bytes; ++s)
635                 {
636                         temp = row[s];
637                         row[s] = alt[s];
638                         alt[s] = temp;
639                 }
641         row += bytes;
642         alt -= bytes;
643     }
646 void FileTGA::rle_read(unsigned char *row,
647         unsigned char *data,
648         int64_t &file_offset,
649         int bytes,
650         int width)
652         int repeat = 0;
653         int direct = 0;
654         unsigned char sample[4];
655         int head;
657         for(int x = 0; x < width; x++)
658         {
659                 if(repeat == 0 && direct == 0)
660                 {
661                         head = data[file_offset++];
662                         if(head == EOF)
663                         {
664                                 return;
665                         }
666                         else
667                         if(head >= 128)
668                         {
669                                 repeat = head - 127;
670                                 bcopy(data + file_offset, sample, bytes);
671                                 file_offset += bytes;
672                         }
673                         else
674                         {
675                                 direct = head + 1;
676                         }
677                 }
678                 
679                 if(repeat > 0)
680                 {
681                         for(int k = 0; k < bytes; k++)
682                         {
683                                 row[k] = sample[k];
684                         }
685                         
686                         repeat--;
687                 }
688                 else
689                 {
690                         bcopy(data + file_offset, row, bytes);
691                         file_offset += bytes;
692                         
693                         direct--;
694                 }
695                 
696                 row += bytes;
697         }
700 void FileTGA::rle_write(unsigned char *buffer, 
701         int width, 
702         int bytes, 
703         VFrame *frame, 
704         int64_t &file_offset)
706         int repeat = 0;
707         int direct = 0;
708         unsigned char *from = buffer;
709         unsigned char output;
710         int x;
711         
712         for(x = 1; x < width; ++x)
713         {
714 /* next pixel is different */
715                 if(memcmp(buffer, buffer + bytes, bytes))
716                 {
717                         if(repeat)
718                         {
719                                 output = 128 + repeat;
720                                 write_data(&output, frame, file_offset, 1);
721                                 write_data(from, frame, file_offset, bytes);
722                                 from = buffer + bytes;
723                                 repeat = 0;
724                                 direct = 0;
725                         }
726                         else
727                         {
728                                 direct++;
729                         }
730                 }
731                 else
732 /* next pixel is the same */
733                 {
734                         if(direct)
735                         {
736                                 output = direct - 1;
737                                 write_data(&output, frame, file_offset, 1);
738                                 write_data(from, frame, file_offset, bytes * direct);
739                                 from = buffer;
740                                 direct = 0;
741                                 repeat = 1;
742                         }
743                         else
744                         {
745                                 repeat++;
746                         }
747                 }
748                 
749                 if(repeat == 128)
750                 {
751                         output = 255;
752                         write_data(&output, frame, file_offset, 1);
753                         write_data(from, frame, file_offset, bytes);
754                         from = buffer + bytes;
755                         direct = 0;
756                         repeat = 0;
757                 }
758                 else
759                 if(direct == 128)
760                 {
761                         output = 127;
762                         write_data(&output, frame, file_offset, 1);
763                         write_data(from, frame, file_offset, direct * bytes);
764                         from = buffer + bytes;
765                         direct = 0;
766                         repeat = 0;
767                 }
768                 
769                 buffer += bytes;
770         }
771         
772         if(repeat > 0)
773         {
774                 output = 128 + repeat;
775                 write_data(&output, frame, file_offset, 1);
776                 write_data(from, frame, file_offset, bytes);
777         }
778         else
779         {
780                 output = direct;
781                 write_data(&output, frame, file_offset, 1);
782                 write_data(from, frame, file_offset, bytes * (direct + 1));
783         }
787 void FileTGA::bgr2rgb(unsigned char *dest,
788          unsigned char *src,
789          int width,
790          int bytes,
791          int alpha)
793         int x;
794         unsigned char r, g, b;
796         if(alpha)
797     {
798         for(x = 0; x < width; x++)
799                 {
800                         r = src[2];
801                         g = src[1];
802                         b = src[0];
803                         *(dest++) = r;
804                         *(dest++) = g;
805                         *(dest++) = b;
806                         *(dest++) = src[3];
808                         src += bytes;
809                 }
810     }
811         else
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;
822                         src += bytes;
823                 }
824     }
827 void FileTGA::upsample(unsigned char *dest,
828           unsigned char *src,
829           int width,
830           int bytes)
832         int x;
834         dest += (width - 1) * 3;
835         src += (width - 1) * bytes;
836         for(x = width - 1; x >= 0; x--)
837     {
838         dest[0] =  ((src[1] << 1) & 0xf8);
839         dest[0] += (dest[0] >> 5);
841         dest[1] =  ((src[0] & 0xe0) >> 2) + ((src[1] & 0x03) << 6);
842         dest[1] += (dest[1] >> 5);
844         dest[2] =  ((src[0] << 3) & 0xf8);
845         dest[2] += (dest[2] >> 5);
847         dest -= 3;
848         src -= bytes;
849     }
860 TGAUnit::TGAUnit(FileTGA *file, FrameWriter *writer)
861  : FrameWriterUnit(writer)
863         temp = 0;
864         this->file = file;
867 TGAUnit::~TGAUnit()
869         if(temp) delete temp;
884 TGAConfigVideo::TGAConfigVideo(BC_WindowBase *gui, Asset *asset)
885  : BC_Window(PROGRAM_NAME ": Video Compression",
886         gui->get_abs_cursor_x(1),
887         gui->get_abs_cursor_y(1),
888         400,
889         100)
891         this->gui = gui;
892         this->asset = asset;
894         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB_RLE)));
895         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA_RLE)));
896         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGB)));
897         compression_items.append(new BC_ListBoxItem(FileTGA::compression_to_str(TGA_RGBA)));
900 TGAConfigVideo::~TGAConfigVideo()
902         compression_items.remove_all_objects();
905 int TGAConfigVideo::create_objects()
907         int x = 10, y = 10;
909         add_subwindow(new BC_Title(x, y, _("Compression:")));
910         TGACompression *textbox = new TGACompression(this, 
911                 x + 110, 
912                 y, 
913                 asset, 
914                 &compression_items);
915         textbox->create_objects();
916         add_subwindow(new BC_OKButton(this));
917         return 0;
920 int TGAConfigVideo::close_event()
922         set_done(0);
923         return 1;
927 TGACompression::TGACompression(TGAConfigVideo *gui,
928         int x, 
929         int y, 
930         Asset *asset, 
931         ArrayList<BC_ListBoxItem*> *compression_items)
932  : BC_PopupTextBox(gui,
933         compression_items,
934         FileTGA::compression_to_str(gui->asset->vcodec),
935         x, 
936         y, 
937         200,
938         200)
940         this->asset = asset;
942 int TGACompression::handle_event()
944         strcpy(asset->vcodec, FileTGA::str_to_compression(get_text()));
945         return 1;