ff tooltip, shcmds doc, bld_prepare fix, edl load_xml fix
[goodguy/history.git] / cinelerra-5.1 / cinelerra / filetiff.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 "edit.h"
24 #include "file.h"
25 #include "filetiff.h"
26 #include "interlacemodes.h"
27 #include "language.h"
28 #include "vframe.h"
29 #include "mainerror.h"
30
31 #include <stdint.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 FileTIFF::FileTIFF(Asset *asset, File *file)
36  : FileList(asset, file, "TIFFLIST", ".tif", FILE_TIFF, FILE_TIFF_LIST)
37 {
38         asset->video_data = 1;
39         temp = 0;
40 }
41
42 FileTIFF::~FileTIFF()
43 {
44         if(temp) delete temp;
45 }
46
47
48 void FileTIFF::get_parameters(BC_WindowBase *parent_window,
49         Asset *asset,
50         BC_WindowBase* &format_window,
51         int audio_options,
52         int video_options)
53 {
54         if(video_options)
55         {
56                 TIFFConfigVideo *window = new TIFFConfigVideo(parent_window, asset);
57                 format_window = window;
58                 window->create_objects();
59                 window->run_window();
60                 delete window;
61         }
62 }
63
64
65 int FileTIFF::check_sig(Asset *asset)
66 {
67         FILE *stream = fopen(asset->path, "rb");
68
69         if(stream)
70         {
71                 char test[10];
72                 (void)fread(test, 10, 1, stream);
73                 fclose(stream);
74
75                 if(test[0] == 'I' && test[1] == 'I')
76                 {
77                         // Reject cr2, libtiff fails with it
78                         if( test[4] == 0x10 && !test[5] && !test[6] && !test[7] &&
79                                         test[8] == 'C' && test[9] == 'R' )
80                                 return 0;
81                         return 1;
82                 }
83                 else
84                 if(test[0] == 'T' && test[1] == 'I' && test[2] == 'F' && test[3] == 'F' &&
85                         test[4] == 'L' && test[5] == 'I' && test[6] == 'S' && test[7] == 'T')
86                 {
87                         return 1;
88                 }
89                 else
90                 if(strlen(asset->path) > 4 &&
91                         !strcasecmp(asset->path + strlen(asset->path) - 4, ".tif"))
92                 {
93                         return 1;
94                 }
95                 else
96                 if(strlen(asset->path) > 5 &&
97                         !strcasecmp(asset->path + strlen(asset->path) - 5, ".tiff"))
98                 {
99                         return 1;
100                 }
101         }
102         return 0;
103 }
104
105 const char* FileTIFF::compression_to_str(int value)
106 {
107         switch(value)
108         {
109                 case FileTIFF::NONE: return "None"; break;
110                 case FileTIFF::LZW: return "LZW"; break;
111                 case FileTIFF::PACK_BITS: return "Pack Bits"; break;
112                 case FileTIFF::DEFLATE: return "Deflate"; break;
113                 case FileTIFF::JPEG: return "JPEG"; break;
114                 default:
115                         return "None";
116                         break;
117         }
118 }
119
120 const char* FileTIFF::cmodel_to_str(int value)
121 {
122         switch(value)
123         {
124                 case FileTIFF::GREYSCALE: return "Greyscale"; break;
125                 case FileTIFF::RGB_888: return "RGB-8 Bit"; break;
126                 case FileTIFF::RGB_161616: return "RGB-16 Bit"; break;
127                 case FileTIFF::RGBA_8888: return "RGBA-8 Bit"; break;
128                 case FileTIFF::RGBA_16161616: return "RGBA-16 Bit"; break;
129                 case FileTIFF::RGB_FLOAT: return "RGB-FLOAT"; break;
130                 case FileTIFF::RGBA_FLOAT: return "RGBA-FLOAT"; break;
131                 default:
132                         return "RGB-8 Bit";
133                         break;
134         }
135 }
136
137
138 int FileTIFF::can_copy_from(Asset *asset, int64_t position)
139 {
140         if(asset->format == FILE_TIFF_LIST ||
141                 asset->format == FILE_TIFF)
142                 return 1;
143
144         return 0;
145 }
146
147
148
149 int FileTIFF::read_frame_header(char *path)
150 {
151         TIFF *stream;
152         int result = 0;
153
154         if(!(stream = TIFFOpen(path, "rb")))
155         {
156                 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
157                 return 1;
158         }
159
160         char *ptr = 0;
161         TIFFGetField(stream, TIFFTAG_MODEL, &ptr);
162 //printf("FileTIFF::read_frame_header 1 %s\n", ptr);
163         if(ptr && !strcmp(ptr, "Canon EOS-1DS"))       // FIXME: Does this have a purpose?
164         {
165                 printf("FileTIFF::read_frame_header: got a %s.\n",
166                         ptr);
167         }
168
169 // The raw format for certain cameras deviates from TIFF here.
170
171         TIFFGetField(stream, TIFFTAG_IMAGEWIDTH, &(asset->width));
172         TIFFGetField(stream, TIFFTAG_IMAGELENGTH, &(asset->height));
173
174         int components = 0;
175         TIFFGetField(stream, TIFFTAG_SAMPLESPERPIXEL, &components);
176         int bitspersample = 0;
177         TIFFGetField(stream, TIFFTAG_BITSPERSAMPLE, &bitspersample);
178         int sampleformat = 0;
179         TIFFGetField(stream, TIFFTAG_SAMPLEFORMAT, &sampleformat);
180
181         if(bitspersample == 8 && components == 3)
182                 asset->tiff_cmodel = FileTIFF::RGB_888;
183         else
184         if(bitspersample == 16 && components == 3)
185                 asset->tiff_cmodel = FileTIFF::RGB_161616;
186         else
187         if(bitspersample == 8 && components == 4)
188                 asset->tiff_cmodel = FileTIFF::RGBA_8888;
189         else
190         if(bitspersample == 16 && components == 4)
191                 asset->tiff_cmodel = FileTIFF::RGBA_16161616;
192         else
193         if(bitspersample == 32 && components == 3)
194                 asset->tiff_cmodel = FileTIFF::RGB_FLOAT;
195         else
196         if(bitspersample == 32 && components == 4)
197                 asset->tiff_cmodel = FileTIFF::RGBA_FLOAT;
198         else
199         if(bitspersample == 8 && (components == 1 || components == 0))
200                 asset->tiff_cmodel = FileTIFF::GREYSCALE;
201
202 //printf("FileTIFF::read_frame_header %d %d %d\n", bitspersample, components, asset->tiff_cmodel);
203         TIFFClose(stream);
204
205         asset->interlace_mode = ILACE_MODE_NOTINTERLACED;
206         return result;
207 }
208
209 int FileTIFF::colormodel_supported(int colormodel)
210 {
211         switch(asset->tiff_cmodel)
212         {
213                 case FileTIFF::RGB_888: return BC_RGB888; break;
214                 case FileTIFF::RGB_161616: return BC_RGB_FLOAT; break;
215                 case FileTIFF::GREYSCALE: return BC_RGB888; break;
216                 case FileTIFF::RGBA_8888: return BC_RGBA8888; break;
217                 case FileTIFF::RGBA_16161616: return BC_RGBA_FLOAT; break;
218                 case FileTIFF::RGB_FLOAT: return BC_RGB_FLOAT; break;
219                 case FileTIFF::RGBA_FLOAT: return BC_RGBA_FLOAT; break;
220                 default: return BC_RGB888; break;
221         }
222 }
223
224 int FileTIFF::get_best_colormodel(Asset *asset, int driver)
225 {
226         switch(asset->tiff_cmodel)
227         {
228                 case FileTIFF::GREYSCALE: return BC_RGB888; break;
229                 case FileTIFF::RGB_888: return BC_RGB888; break;
230                 case FileTIFF::RGB_161616: return BC_RGB_FLOAT; break;
231                 case FileTIFF::RGBA_8888: return BC_RGBA8888; break;
232                 case FileTIFF::RGBA_16161616: return BC_RGBA_FLOAT; break;
233                 case FileTIFF::RGB_FLOAT: return BC_RGB_FLOAT; break;
234                 case FileTIFF::RGBA_FLOAT: return BC_RGBA_FLOAT; break;
235                 default: return BC_RGB888; break;
236         }
237 }
238
239
240 static tsize_t tiff_read(thandle_t ptr, tdata_t buf, tsize_t size)
241 {
242         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr;
243         if(tiff_unit->data->get_compressed_size() < tiff_unit->offset + size)
244                 return 0;
245         memcpy(buf, tiff_unit->data->get_data() + tiff_unit->offset, size);
246         tiff_unit->offset += size;
247         return size;
248 }
249
250 static tsize_t tiff_write(thandle_t ptr, tdata_t buf, tsize_t size)
251 {
252         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr;
253         if(tiff_unit->data->get_compressed_allocated() < tiff_unit->offset + size)
254         {
255                 tiff_unit->data->allocate_compressed_data((tiff_unit->offset + size) * 2);
256         }
257
258
259         if(tiff_unit->data->get_compressed_size() < tiff_unit->offset + size)
260                 tiff_unit->data->set_compressed_size(tiff_unit->offset + size);
261         memcpy(tiff_unit->data->get_data() + tiff_unit->offset,
262                 buf,
263                 size);
264         tiff_unit->offset += size;
265         return size;
266 }
267
268 static toff_t tiff_seek(thandle_t ptr, toff_t off, int whence)
269 {
270         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr;
271         switch(whence)
272         {
273                 case SEEK_SET:
274                         tiff_unit->offset = off;
275                         break;
276                 case SEEK_CUR:
277                         tiff_unit->offset += off;
278                         break;
279                 case SEEK_END:
280                         tiff_unit->offset = tiff_unit->data->get_compressed_size() + off;
281                         break;
282         }
283         return tiff_unit->offset;
284 }
285
286 static int tiff_close(thandle_t ptr)
287 {
288         return 0;
289 }
290
291 static toff_t tiff_size(thandle_t ptr)
292 {
293         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr;
294         return tiff_unit->data->get_compressed_size();
295 }
296
297 static int tiff_mmap(thandle_t ptr, tdata_t* pbase, toff_t* psize)
298 {
299         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr;
300         *pbase = tiff_unit->data->get_data();
301         *psize = tiff_unit->data->get_compressed_size();
302         return 0;
303 }
304
305 void tiff_unmap(thandle_t ptr, tdata_t base, toff_t size)
306 {
307 }
308
309 int FileTIFF::read_frame(VFrame *output, VFrame *input)
310 {
311         FileTIFFUnit *unit = new FileTIFFUnit(this, 0);
312         TIFF *stream;
313         unit->offset = 0;
314         unit->data = input;
315
316         stream = TIFFClientOpen("FileTIFF",
317                 "r",
318             (void*)unit,
319             tiff_read,
320                 tiff_write,
321             tiff_seek,
322                 tiff_close,
323             tiff_size,
324             tiff_mmap,
325                 tiff_unmap);
326
327 // This loads the original TIFF data into each scanline of the output frame,
328 // assuming the output scanlines are bigger than the input scanlines.
329 // Then it expands the input data in reverse to fill the row.
330         for(int i = 0; i < asset->height; i++)
331         {
332                 TIFFReadScanline(stream, output->get_rows()[i], i, 0);
333
334 // For the greyscale model, the output is RGB888 but the input must be expanded
335                 if(asset->tiff_cmodel == FileTIFF::GREYSCALE)
336                 {
337                         unsigned char *row = output->get_rows()[i];
338                         for(int j = output->get_w() - 1; j >= 0; j--)
339                         {
340                                 unsigned char value = row[j];
341                                 row[j * 3] = value;
342                                 row[j * 3 + 1] = value;
343                                 row[j * 3 + 2] = value;
344                         }
345                 }
346 // For the 16 bit models, the output is floating point.
347                 else
348                 if(asset->tiff_cmodel == FileTIFF::RGB_161616)
349                 {
350                         uint16_t *input_row = (uint16_t*)output->get_rows()[i];
351                         float *output_row = (float*)output->get_rows()[i];
352                         for(int j = output->get_w() - 1; j >= 0; j--)
353                         {
354                                 uint16_t r = input_row[j * 3];
355                                 uint16_t g = input_row[j * 3 + 1];
356                                 uint16_t b = input_row[j * 3 + 2];
357                                 output_row[j * 3] = (float)r / 65535;
358                                 output_row[j * 3 + 1] = (float)g / 65535;
359                                 output_row[j * 3 + 2] = (float)b / 65535;
360                         }
361                 }
362                 else
363                 if(asset->tiff_cmodel == FileTIFF::RGBA_16161616)
364                 {
365                         uint16_t *input_row = (uint16_t*)output->get_rows()[i];
366                         float *output_row = (float*)output->get_rows()[i];
367                         for(int j = output->get_w() - 1; j >= 0; j--)
368                         {
369                                 uint16_t r = input_row[j * 4];
370                                 uint16_t g = input_row[j * 4 + 1];
371                                 uint16_t b = input_row[j * 4 + 2];
372                                 output_row[j * 4] = (float)r / 65535;
373                                 output_row[j * 4 + 1] = (float)g / 65535;
374                                 output_row[j * 4 + 2] = (float)b / 65535;
375                         }
376                 }
377         }
378
379         TIFFClose(stream);
380         delete unit;
381
382         return 0;
383 }
384
385 int FileTIFF::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
386 {
387 //printf("FileTIFF::write_frame 1\n");
388         FileTIFFUnit *tiff_unit = (FileTIFFUnit*)unit;
389         int result = 0;
390         TIFF *stream;
391         tiff_unit->offset = 0;
392         tiff_unit->data = data;
393         tiff_unit->data->set_compressed_size(0);
394
395         stream = TIFFClientOpen("FileTIFF",
396                 "w",
397             (void*)tiff_unit,
398             tiff_read,
399                 tiff_write,
400             tiff_seek,
401                 tiff_close,
402             tiff_size,
403             tiff_mmap,
404                 tiff_unmap);
405
406         int components, color_model, bits, compression;
407         int sampleformat = SAMPLEFORMAT_UINT;
408         //int bytesperrow, type;
409         switch(asset->tiff_cmodel)
410         {
411                 case FileTIFF::RGB_888:
412                         components = 3;
413                         color_model = BC_RGB888;
414                         bits = 8;
415                         //type = TIFF_BYTE;
416                         //bytesperrow = 3 * asset->width;
417                         break;
418                 case FileTIFF::RGB_161616:
419                         components = 3;
420                         color_model = BC_RGB_FLOAT;
421                         bits = 16;
422                         //type = TIFF_SHORT;
423                         //bytesperrow = 6 * asset->width;
424                         break;
425                 case FileTIFF::RGBA_8888:
426                         components = 4;
427                         color_model = BC_RGBA8888;
428                         bits = 8;
429                         //type = TIFF_BYTE;
430                         //bytesperrow = 4 * asset->width;
431                         break;
432                 case FileTIFF::RGBA_16161616:
433                         components = 4;
434                         color_model = BC_RGBA_FLOAT;
435                         bits = 16;
436                         //type = TIFF_SHORT;
437                         //bytesperrow = 8 * asset->width;
438                         break;
439                 case FileTIFF::RGB_FLOAT:
440                         components = 3;
441                         color_model = BC_RGB_FLOAT;
442                         bits = 32;
443                         //type = TIFF_FLOAT;
444                         sampleformat = SAMPLEFORMAT_IEEEFP;
445                         //bytesperrow = 12 * asset->width;
446                         break;
447                 case FileTIFF::RGBA_FLOAT:
448                         components = 4;
449                         color_model = BC_RGBA_FLOAT;
450                         bits = 32;
451                         //type = TIFF_FLOAT;
452                         sampleformat = SAMPLEFORMAT_IEEEFP;
453                         //bytesperrow = 16 * asset->width;
454                         break;
455                 default:
456                         components = 3;
457                         color_model = BC_RGB888;
458                         bits = 8;
459                         //type = TIFF_BYTE;
460                         //bytesperrow = 3 * asset->width;
461                         break;
462         }
463
464
465         switch(asset->tiff_compression)
466         {
467                 case FileTIFF::LZW:
468                         compression = COMPRESSION_LZW;
469                         break;
470                 case FileTIFF::PACK_BITS:
471                         compression = COMPRESSION_PACKBITS;
472                         break;
473                 case FileTIFF::DEFLATE:
474                         compression = COMPRESSION_DEFLATE;
475                         break;
476                 case FileTIFF::JPEG:
477                         compression = COMPRESSION_JPEG;
478                         break;
479                 default:
480                         compression = COMPRESSION_NONE;
481                         break;
482         }
483
484         TIFFSetField(stream, TIFFTAG_IMAGEWIDTH, asset->width);
485         TIFFSetField(stream, TIFFTAG_IMAGELENGTH, asset->height);
486         TIFFSetField(stream, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
487         TIFFSetField(stream, TIFFTAG_SAMPLESPERPIXEL, components);
488         TIFFSetField(stream, TIFFTAG_BITSPERSAMPLE, bits);
489     TIFFSetField(stream, TIFFTAG_SAMPLEFORMAT, sampleformat);
490         TIFFSetField(stream, TIFFTAG_COMPRESSION, compression);
491         TIFFSetField(stream, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
492         TIFFSetField(stream, TIFFTAG_ROWSPERSTRIP,
493                 TIFFDefaultStripSize(stream, (uint32_t)-1));
494 //      TIFFSetField(stream, TIFFTAG_ROWSPERSTRIP,
495 //              (8 * 1024) / bytesperrow);
496         TIFFSetField(stream, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
497
498         if(frame->get_color_model() == color_model)
499         {
500                 for(int i = 0; i < asset->height; i++)
501                 {
502                         TIFFWriteScanline(stream, frame->get_rows()[i], i, 0);
503                 }
504         }
505         else
506         {
507                 if(tiff_unit->temp &&
508                         tiff_unit->temp->get_color_model() != color_model)
509                 {
510                         delete tiff_unit->temp;
511                         tiff_unit->temp = 0;
512                 }
513                 if(!tiff_unit->temp)
514                 {
515                         tiff_unit->temp = new VFrame(0,
516                                 -1,
517                                 asset->width,
518                                 asset->height,
519                                 color_model,
520                                 -1);
521                 }
522
523                 BC_CModels::transfer(tiff_unit->temp->get_rows(),
524                         frame->get_rows(),
525                         tiff_unit->temp->get_y(),
526                         tiff_unit->temp->get_u(),
527                         tiff_unit->temp->get_v(),
528                         frame->get_y(),
529                         frame->get_u(),
530                         frame->get_v(),
531                         0,
532                         0,
533                         frame->get_w(),
534                         frame->get_h(),
535                         0,
536                         0,
537                         frame->get_w(),
538                         frame->get_h(),
539                         frame->get_color_model(),
540                         color_model,
541                         0,
542                         frame->get_w(),
543                         frame->get_w());
544                 for(int i = 0; i < asset->height; i++)
545                 {
546                         TIFFWriteScanline(stream, tiff_unit->temp->get_rows()[i], i, 0);
547                 }
548         }
549
550         TIFFClose(stream);
551
552 //printf("FileTIFF::write_frame 10\n");
553         return result;
554 }
555
556 FrameWriterUnit* FileTIFF::new_writer_unit(FrameWriter *writer)
557 {
558         return new FileTIFFUnit(this, writer);
559 }
560
561
562
563
564
565
566
567
568 FileTIFFUnit::FileTIFFUnit(FileTIFF *file, FrameWriter *writer)
569  : FrameWriterUnit(writer)
570 {
571         this->file = file;
572         temp = 0;
573 }
574
575 FileTIFFUnit::~FileTIFFUnit()
576 {
577         if(temp) delete temp;
578 }
579
580
581
582
583
584
585
586
587
588
589
590
591 TIFFConfigVideo::TIFFConfigVideo(BC_WindowBase *parent_window, Asset *asset)
592  : BC_Window(_(PROGRAM_NAME ": Video Compression"),
593         parent_window->get_abs_cursor_x(1),
594         parent_window->get_abs_cursor_y(1),
595         400,
596         200)
597 {
598         this->parent_window = parent_window;
599         this->asset = asset;
600 }
601
602 TIFFConfigVideo::~TIFFConfigVideo()
603 {
604 }
605
606 void TIFFConfigVideo::create_objects()
607 {
608         lock_window("TIFFConfigVideo::create_objects()");
609         int x = 10, y = 10;
610
611         add_subwindow(new BC_Title(x, y, _("Colorspace:")));
612         TIFFColorspace *menu1;
613         add_subwindow(menu1 = new TIFFColorspace(this, x + 150, y, 200));
614         menu1->create_objects();
615         y += 40;
616         add_subwindow(new BC_Title(x, y, _("Compression:")));
617         TIFFCompression *menu2;
618         add_subwindow(menu2 = new TIFFCompression(this, x + 150, y, 200));
619         menu2->create_objects();
620
621         add_subwindow(new BC_OKButton(this));
622         show_window(1);
623         unlock_window();
624 }
625
626 int TIFFConfigVideo::close_event()
627 {
628         set_done(0);
629         return 1;
630 }
631
632
633
634
635
636
637 TIFFColorspace::TIFFColorspace(TIFFConfigVideo *gui, int x, int y, int w)
638  : BC_PopupMenu(x,
639         y,
640         w,
641         FileTIFF::cmodel_to_str(gui->asset->tiff_cmodel))
642 {
643         this->gui = gui;
644 }
645 int TIFFColorspace::handle_event()
646 {
647         return 1;
648 }
649 void TIFFColorspace::create_objects()
650 {
651         add_item(new TIFFColorspaceItem(gui, FileTIFF::RGB_888));
652 //      add_item(new TIFFColorspaceItem(gui, FileTIFF::RGB_16161616));
653         add_item(new TIFFColorspaceItem(gui, FileTIFF::RGBA_8888));
654 //      add_item(new TIFFColorspaceItem(gui, FileTIFF::RGBA_16161616));
655         add_item(new TIFFColorspaceItem(gui, FileTIFF::RGB_FLOAT));
656         add_item(new TIFFColorspaceItem(gui, FileTIFF::RGBA_FLOAT));
657 }
658
659
660 TIFFColorspaceItem::TIFFColorspaceItem(TIFFConfigVideo *gui, int value)
661  : BC_MenuItem(FileTIFF::cmodel_to_str(value))
662 {
663         this->gui = gui;
664         this->value = value;
665 }
666 int TIFFColorspaceItem::handle_event()
667 {
668         gui->asset->tiff_cmodel = value;
669         return 0;
670 }
671
672
673
674
675
676
677
678 TIFFCompression::TIFFCompression(TIFFConfigVideo *gui, int x, int y, int w)
679  : BC_PopupMenu(x, y, w, FileTIFF::compression_to_str(gui->asset->tiff_compression))
680 {
681         this->gui = gui;
682 }
683 int TIFFCompression::handle_event()
684 {
685         return 1;
686 }
687 void TIFFCompression::create_objects()
688 {
689         add_item(new TIFFCompressionItem(gui, FileTIFF::NONE));
690 //      add_item(new TIFFCompressionItem(gui, FileTIFF::LZW));
691         add_item(new TIFFCompressionItem(gui, FileTIFF::PACK_BITS));
692 //      add_item(new TIFFCompressionItem(gui, FileTIFF::DEFLATE));
693 //      add_item(new TIFFCompressionItem(gui, FileTIFF::JPEG));
694 }
695
696
697
698
699
700 TIFFCompressionItem::TIFFCompressionItem(TIFFConfigVideo *gui, int value)
701  : BC_MenuItem(FileTIFF::compression_to_str(value))
702 {
703         this->gui = gui;
704         this->value = value;
705 }
706 int TIFFCompressionItem::handle_event()
707 {
708         gui->asset->tiff_compression = value;
709         return 0;
710 }
711
712
713