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