several bug fixes and minor feature changes:
[goodguy/history.git] / cinelerra-5.0 / cinelerra / formattools.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2010-2013 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "asset.h"
23 #include "bcsignals.h"
24 #include "clip.h"
25 #include "guicast.h"
26 #include "file.h"
27 #include "filesystem.h"
28 #include "formattools.h"
29 #include "language.h"
30 #include "maxchannels.h"
31 #include "mwindow.h"
32 #include "preferences.h"
33 #include "quicktime.h"
34 #include "theme.h"
35 #include "videodevice.inc"
36 #include <string.h>
37 #include <unistd.h>
38 #include <ctype.h>
39
40
41 FormatTools::FormatTools(MWindow *mwindow,
42                                 BC_WindowBase *window, 
43                                 Asset *asset)
44 {
45         this->mwindow = mwindow;
46         this->window = window;
47         this->asset = asset;
48         this->plugindb = mwindow->plugindb;
49
50         aparams_button = 0;
51         vparams_button = 0;
52         aparams_thread = 0;
53         vparams_thread = 0;
54         channels_tumbler = 0;
55         audio_switch = 0;
56         video_switch = 0;
57         path_textbox = 0;
58         path_button = 0;
59         format_title = 0;
60         format_button = 0;
61         format_text = 0;
62         audio_title = 0;
63         audio_switch = 0;
64         video_title = 0;
65         video_switch = 0;
66         channels_title = 0;
67         channels_button = 0;
68         multiple_files = 0;
69         file_entries = 0;
70         w = window->get_w();
71
72         recording = 0;
73         use_brender = 0;
74         do_audio = 0;
75         do_video = 0;
76         prompt_audio = 0;
77         prompt_audio_channels = 0;
78         prompt_video = 0;
79         prompt_video_compression = 0;
80         strategy = 0;
81         locked_compressor = 0;
82         video_driver = 0;
83 }
84
85 FormatTools::~FormatTools()
86 {
87 SET_TRACE
88         delete path_button;
89 SET_TRACE
90         delete path_textbox;
91 SET_TRACE
92         delete format_button;
93 SET_TRACE
94
95         if(aparams_button) delete aparams_button;
96 SET_TRACE
97         if(vparams_button) delete vparams_button;
98 SET_TRACE
99         if(aparams_thread) delete aparams_thread;
100 SET_TRACE
101         if(vparams_thread) delete vparams_thread;
102 SET_TRACE
103         if(channels_tumbler) delete channels_tumbler;
104 SET_TRACE
105         if(file_entries)
106         {
107                 file_entries->remove_all_objects();
108                 delete file_entries;
109         }
110 }
111
112 void FormatTools::create_objects(int &init_x, 
113                                                 int &init_y, 
114                                                 int do_audio,    // Include support for audio
115                                                 int do_video,   // Include support for video
116                                                 int prompt_audio,  // Include checkbox for audio
117                                                 int prompt_video,
118                                                 int prompt_audio_channels,
119                                                 int prompt_video_compression,
120                                                 char *locked_compressor,
121                                                 int recording,
122                                                 int *strategy,
123                                                 int brender)
124 {
125         int x = init_x;
126         int y = init_y;
127
128         this->locked_compressor = locked_compressor;
129         this->recording = recording;
130         this->use_brender = brender;
131         this->do_audio = do_audio;
132         this->do_video = do_video;
133         this->prompt_audio = prompt_audio;
134         this->prompt_audio_channels = prompt_audio_channels;
135         this->prompt_video = prompt_video;
136         this->prompt_video_compression = prompt_video_compression;
137         this->strategy = strategy;
138
139
140         file_entries = new ArrayList<BC_ListBoxItem*>;
141         FileSystem fs;
142         char string[BCTEXTLEN];
143 // Load current directory
144         fs.update(getcwd(string, BCTEXTLEN));
145         for(int i = 0; i < fs.total_files(); i++)
146         {
147                 file_entries->append(
148                         new BC_ListBoxItem(
149                                 fs.get_entry(i)->get_name()));
150         }
151
152 //printf("FormatTools::create_objects 1\n");
153
154 // Modify strategy depending on render farm
155         if(strategy)
156         {
157                 if(mwindow->preferences->use_renderfarm)
158                 {
159                         if(*strategy == FILE_PER_LABEL)
160                                 *strategy = FILE_PER_LABEL_FARM;
161                         else
162                         if(*strategy == SINGLE_PASS)
163                                 *strategy = SINGLE_PASS_FARM;
164                 }
165                 else
166                 {
167                         if(*strategy == FILE_PER_LABEL_FARM)
168                                 *strategy = FILE_PER_LABEL;
169                         else
170                         if(*strategy == SINGLE_PASS_FARM)
171                                 *strategy = SINGLE_PASS;
172                 }
173         }
174
175         if(!recording)
176         {
177                 window->add_subwindow(path_textbox = new FormatPathText(x, y, this));
178                 x += path_textbox->get_w() + 5;
179                 window->add_subwindow(path_button = new BrowseButton(
180                         mwindow,
181                         window,
182                         path_textbox, 
183                         x, 
184                         y, 
185                         asset->path,
186                         _("Output to file"),
187                         _("Select a file to write to:"),
188                         0));
189
190 // Set w for user.
191                 w = MAX(w, 305);
192 //              w = x + path_button->get_w() + 5;
193                 x -= path_textbox->get_w() + 5;
194                 y += 35;
195         }
196         else
197         {
198 //              w = x + 305;
199                 w = 305;
200         }
201
202         window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
203         x += 90;
204         window->add_subwindow(format_text = new BC_TextBox(x, y, 200, 1, 
205                 File::formattostr(asset->format)));
206         x += format_text->get_w();
207 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
208         window->add_subwindow(format_button = new FormatFormat(x, y, this));
209         format_button->create_objects();
210
211         x = init_x;
212         y += format_button->get_h() + 10;
213         if(do_audio)
214         {
215                 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT, RED));
216                 x += 80;
217                 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
218                 x += aparams_button->get_w() + 10;
219                 if(prompt_audio) 
220                 {
221                         window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
222                 }
223                 x = init_x;
224                 y += aparams_button->get_h() + 10;
225
226 // Audio channels only used for recording.
227 //              if(prompt_audio_channels)
228 //              {
229 //                      window->add_subwindow(channels_title = new BC_Title(x, y, _("Number of audio channels to record:")));
230 //                      x += 260;
231 //                      window->add_subwindow(channels_button = new FormatChannels(x, y, this));
232 //                      x += channels_button->get_w() + 5;
233 //                      window->add_subwindow(channels_tumbler = new BC_ITumbler(channels_button, 1, MAXCHANNELS, x, y));
234 //                      y += channels_button->get_h() + 20;
235 //                      x = init_x;
236 //              }
237
238 //printf("FormatTools::create_objects 6\n");
239                 aparams_thread = new FormatAThread(this);
240         }
241
242 //printf("FormatTools::create_objects 7\n");
243         if(do_video)
244         {
245
246 //printf("FormatTools::create_objects 8\n");
247                 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT, RED));
248                 x += 80;
249                 if(prompt_video_compression)
250                 {
251                         window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
252                         x += vparams_button->get_w() + 10;
253                 }
254
255 //printf("FormatTools::create_objects 9\n");
256                 if(prompt_video)
257                 {
258                         window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
259                         y += video_switch->get_h();
260                 }
261                 else
262                 {
263                         y += vparams_button->get_h();
264                 }
265
266 //printf("FormatTools::create_objects 10\n");
267                 y += 10;
268                 vparams_thread = new FormatVThread(this);
269         }
270
271 //printf("FormatTools::create_objects 11\n");
272
273         x = init_x;
274         if(strategy)
275         {
276                 window->add_subwindow(multiple_files = new FormatMultiple(mwindow, x, y, strategy));
277                 y += multiple_files->get_h() + 10;
278         }
279
280 //printf("FormatTools::create_objects 12\n");
281
282         init_y = y;
283         update_format();
284 }
285
286 void FormatTools::update_driver(int driver)
287 {
288         this->video_driver = driver;
289
290         switch(driver)
291         {
292                 case CAPTURE_DVB:
293                 case VIDEO4LINUX2MPEG:
294 // Just give the user information about how the stream is going to be
295 // stored but don't change the asset.
296 // Want to be able to revert to user settings.
297                         if(asset->format != FILE_MPEG)
298                         {
299                                 format_text->update(_("MPEG stream"));
300                                 asset->format = FILE_MPEG;
301                         }
302                         locked_compressor = 0;
303                         audio_switch->update(1);
304                         video_switch->update(1);
305                         break;
306
307                 case CAPTURE_IEC61883:
308                 case CAPTURE_FIREWIRE:
309                 case CAPTURE_BUZ:
310                 case VIDEO4LINUX2JPEG:
311                 case CAPTURE_JPEG_WEBCAM:
312                         if(asset->format != FILE_AVI &&
313                                 asset->format != FILE_MOV)
314                         {
315                                 format_text->update(MOV_NAME);
316                                 asset->format = FILE_MOV;
317                         }
318                         else
319                                 format_text->update(File::formattostr(asset->format));
320
321                         switch(driver)
322                         {
323                                 case CAPTURE_IEC61883:
324                                 case CAPTURE_FIREWIRE:
325                                         locked_compressor = (char*)QUICKTIME_DVSD;
326                                         strcpy(asset->vcodec, QUICKTIME_DVSD);
327                                         break;
328
329                                 case CAPTURE_BUZ:
330                                 case VIDEO4LINUX2JPEG:
331                                         locked_compressor = (char*)QUICKTIME_MJPA;
332                                         strcpy(asset->vcodec, QUICKTIME_MJPA);
333                                         break;
334
335                                 case CAPTURE_JPEG_WEBCAM:
336                                         locked_compressor = (char*)QUICKTIME_JPEG;
337                                         strcpy(asset->vcodec, QUICKTIME_JPEG);
338                                         break;
339                         }
340
341                         audio_switch->update(asset->audio_data);
342                         video_switch->update(asset->video_data);
343                         break;
344
345
346
347
348
349                 default:
350                         format_text->update(File::formattostr(asset->format));
351                         locked_compressor = 0;
352                         audio_switch->update(asset->audio_data);
353                         video_switch->update(asset->video_data);
354                         break;
355         }
356         close_format_windows();
357 }
358
359 void FormatTools::update_format()
360 {
361         if( do_audio && prompt_audio && audio_switch ) {
362                 asset->audio_data = File::supports_audio(asset->format);
363                 audio_switch->update(asset->audio_data);
364                 if( !asset->audio_data )
365                         audio_switch->disable();
366                 else
367                         audio_switch->enable();
368         }
369         if( do_video && prompt_video && video_switch ) {
370                 asset->video_data = File::supports_video(asset->format);
371                 video_switch->update(asset->video_data);
372                 if( !asset->video_data )
373                         video_switch->disable();
374                 else
375                         video_switch->enable();
376         }
377 }
378
379 int FormatTools::handle_event()
380 {
381         return 0;
382 }
383
384 Asset* FormatTools::get_asset()
385 {
386         return asset;
387 }
388
389 void FormatTools::update_extension()
390 {
391         const char *extension = File::get_tag(asset->format);
392 // split multiple extensions
393         ArrayList<const char*> extensions;
394         int len = strlen(extension);
395         const char *extension_ptr = extension;
396         for(int i = 0; i <= len; i++)
397         {
398                 if(extension[i] == '/' || extension[i] == 0)
399                 {
400                         extensions.append(extension_ptr);
401                         extension_ptr = extension + i + 1;
402                 }
403         }
404         
405         if(extensions.size())
406         {
407                 char *ptr = strrchr(asset->path, '.');
408                 if(!ptr)
409                 {
410                         ptr = asset->path + strlen(asset->path);
411                         *ptr = '.';
412                 }
413                 ptr++;
414                 
415                 
416 // test for equivalent extension
417                 int need_extension = 1;
418                 //int extension_len = 0;
419                 for(int i = 0; i < extensions.size() && need_extension; i++)
420                 {
421                         char *ptr1 = ptr;
422                         extension_ptr = extensions.get(i);
423 // test an extension
424                         need_extension = 0;
425                         while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
426                         {
427                                 if(tolower(*ptr1) != tolower(*extension_ptr))
428                                 {
429                                         need_extension = 1;
430                                         break;
431                                 }
432                                 ptr1++;
433                                 extension_ptr++;
434                         }
435
436                         if(*ptr1 == 0 && 
437                                 *extension_ptr != 0 &&
438                                 *extension_ptr != '/')
439                                 need_extension = 1;
440                 }
441
442 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
443 // copy extension
444                 if(need_extension) 
445                 {
446                         char *ptr1 = ptr;
447                         extension_ptr = extensions.get(0);
448                         while(*extension_ptr != 0 && *extension_ptr != '/')
449                                 *ptr1++ = *extension_ptr++;
450                         *ptr1 = 0;
451                 }
452
453                 int character1 = ptr - asset->path;
454                 int character2 = strlen(asset->path);
455 //              *(asset->path + character2) = 0;
456                 if(path_textbox) 
457                 {
458                         path_textbox->update(asset->path);
459                         path_textbox->set_selection(character1, character2, character2);
460                 }
461         }
462 }
463
464 void FormatTools::update(Asset *asset, int *strategy)
465 {
466         this->asset = asset;
467         this->strategy = strategy;
468
469         if(path_textbox) 
470                 path_textbox->update(asset->path);
471         format_text->update(File::formattostr(plugindb, asset->format));
472         if(do_audio && prompt_audio && audio_switch)
473                 audio_switch->update(asset->audio_data);
474         if(do_video && prompt_video && video_switch)
475                 video_switch->update(asset->video_data);
476         if(strategy)
477         {
478                 multiple_files->update(strategy);
479         }
480         close_format_windows();
481 }
482
483 void FormatTools::close_format_windows()
484 {
485 // This is done in ~file
486         if(aparams_thread && aparams_thread->running())
487         {
488                 aparams_thread->file->close_window();
489                 aparams_thread->join();
490         }
491         if(vparams_thread && vparams_thread->running())
492         {
493                 vparams_thread->file->close_window();
494                 vparams_thread->join();
495         }
496 }
497
498 int FormatTools::get_w()
499 {
500         return w;
501 }
502
503 void FormatTools::set_w(int w)
504 {
505         this->w = w;
506 }
507
508 void FormatTools::reposition_window(int &init_x, int &init_y)
509 {
510         int x = init_x;
511         int y = init_y;
512
513         if(path_textbox) 
514         {
515                 path_textbox->reposition_window(x, y);
516                 x += path_textbox->get_w() + 5;
517                 path_button->reposition_window(x, y);
518                 x -= path_textbox->get_w() + 5;
519                 y += 35;
520         }
521
522         format_title->reposition_window(x, y);
523         x += 90;
524         format_text->reposition_window(x, y);
525         x += format_text->get_w();
526         format_button->reposition_window(x, y);
527
528         x = init_x;
529         y += format_button->get_h() + 10;
530
531         if(do_audio)
532         {
533                 audio_title->reposition_window(x, y);
534                 x += 80;
535                 aparams_button->reposition_window(x, y);
536                 x += aparams_button->get_w() + 10;
537                 if(prompt_audio) audio_switch->reposition_window(x, y);
538
539                 x = init_x;
540                 y += aparams_button->get_h() + 20;
541                 if(prompt_audio_channels)
542                 {
543                         channels_title->reposition_window(x, y);
544                         x += 260;
545                         channels_button->reposition_window(x, y);
546                         x += channels_button->get_w() + 5;
547                         channels_tumbler->reposition_window(x, y);
548                         y += channels_button->get_h() + 20;
549                         x = init_x;
550                 }
551         }
552
553
554         if(do_video)
555         {
556                 video_title->reposition_window(x, y);
557                 x += 80;
558                 if(prompt_video_compression)
559                 {
560                         vparams_button->reposition_window(x, y);
561                         x += vparams_button->get_w() + 10;
562                 }
563
564                 if(prompt_video)
565                 {
566                         video_switch->reposition_window(x, y);
567                         y += video_switch->get_h();
568                 }
569                 else
570                 {
571                         y += vparams_button->get_h();
572                 }
573
574                 y += 10;
575                 x = init_x;
576         }
577
578         if(strategy)
579         {
580                 multiple_files->reposition_window(x, y);
581                 y += multiple_files->get_h() + 10;
582         }
583
584         init_y = y;
585 }
586
587
588 int FormatTools::set_audio_options()
589 {
590 //      if(video_driver == CAPTURE_DVB)
591 //      {
592 //              return 0;
593 //      }
594
595         if(!aparams_thread->running())
596         {
597                 aparams_thread->start();
598         }
599         else
600         {
601                 aparams_thread->file->raise_window();
602         }
603         return 0;
604 }
605
606 int FormatTools::set_video_options()
607 {
608 //      if(video_driver == CAPTURE_DVB)
609 //      {
610 //              return 0;
611 //      }
612
613         if(!vparams_thread->running())
614         {
615                 vparams_thread->start();
616         }
617         else
618         {
619                 vparams_thread->file->raise_window();
620         }
621
622         return 0;
623 }
624
625
626
627
628
629 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
630  : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
631 {
632         this->format = format;
633         set_tooltip(_("Configure audio compression"));
634 }
635
636 FormatAParams::~FormatAParams() 
637 {
638 }
639
640 int FormatAParams::handle_event() 
641 {
642         format->set_audio_options(); 
643         return 1;
644 }
645
646
647
648
649
650 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
651  : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
652
653         this->format = format; 
654         set_tooltip(_("Configure video compression"));
655 }
656
657 FormatVParams::~FormatVParams() 
658 {
659 }
660
661 int FormatVParams::handle_event() 
662
663         format->set_video_options(); 
664         return 1;
665 }
666
667
668
669
670
671 FormatAThread::FormatAThread(FormatTools *format)
672  : Thread(1, 0, 0)
673
674         this->format = format; 
675         file = new File;
676         joined = 1;
677 }
678
679 FormatAThread::~FormatAThread() 
680 {
681         join();
682         delete file;
683         file = 0;
684 }
685
686 void FormatAThread::start()
687 {
688         join();
689         joined = 0;
690         Thread::start();
691 }
692
693
694 void FormatAThread::run()
695 {
696         file->get_options(format, 1, 0);
697 }
698
699
700
701
702 FormatVThread::FormatVThread(FormatTools *format)
703  : Thread(1, 0, 0)
704 {
705         this->format = format;
706         file = new File;
707         joined = 1;
708 }
709
710 FormatVThread::~FormatVThread() 
711 {
712         join();
713         delete file;
714         file = 0;
715 }
716
717 void FormatVThread::start()
718 {
719         join();
720         joined = 0;
721         Thread::start();
722 }
723
724 void FormatVThread::run()
725 {
726         file->get_options(format, 0, 1);
727 }
728
729
730
731
732
733 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
734  : BC_TextBox(x, 
735         y, 
736         format->w - 
737                 format->mwindow->theme->get_image_set("wrench")[0]->get_w() - 
738                 x - 10, 
739         1, 
740         format->asset->path) 
741 {
742         this->format = format; 
743 }
744
745 FormatPathText::~FormatPathText() 
746 {
747 }
748 int FormatPathText::handle_event() 
749 {
750 // Suggestions
751         calculate_suggestions(format->file_entries);
752
753
754
755         strcpy(format->asset->path, get_text());
756         format->handle_event();
757
758         return 1;
759 }
760
761
762
763
764 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
765  : BC_CheckBox(x, 
766         y, 
767         default_, 
768         (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
769
770         this->format = format; 
771 }
772
773 FormatAudio::~FormatAudio() {}
774 int FormatAudio::handle_event()
775 {
776         format->asset->audio_data = get_value();
777         return 1;
778 }
779
780
781 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
782  : BC_CheckBox(x, 
783         y, 
784         default_, 
785         (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
786 {
787 this->format = format; 
788 }
789
790 FormatVideo::~FormatVideo() {}
791 int FormatVideo::handle_event()
792 {
793         format->asset->video_data = get_value();
794         return 1;
795 }
796
797
798
799
800 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
801  : FormatPopup(format->plugindb, x, y, format->use_brender)
802
803         this->format = format; 
804 }
805
806 FormatFormat::~FormatFormat() 
807 {
808 }
809
810 int FormatFormat::handle_event()
811 {
812         if(get_selection(0, 0) >= 0)
813         {
814                 int new_format = File::strtoformat(format->plugindb, get_selection(0, 0)->get_text());
815 //              if(new_format != format->asset->format)
816                 {
817                         format->asset->format = new_format;
818                         format->format_text->update(get_selection(0, 0)->get_text());
819                         format->update_extension();
820                         format->close_format_windows();
821                         format->update_format();
822                 }
823         }
824         return 1;
825 }
826
827
828
829 FormatChannels::FormatChannels(int x, int y, FormatTools *format)
830  : BC_TextBox(x, y, 100, 1, format->asset->channels) 
831
832         this->format = format; 
833 }
834
835 FormatChannels::~FormatChannels() 
836 {
837 }
838
839 int FormatChannels::handle_event() 
840 {
841         format->asset->channels = atol(get_text());
842         return 1;
843 }
844
845
846 FormatToTracks::FormatToTracks(int x, int y, int *output)
847  : BC_CheckBox(x, y, *output, _("Overwrite project with output"))
848
849         this->output = output; 
850 }
851
852 FormatToTracks::~FormatToTracks() 
853 {
854 }
855
856 int FormatToTracks::handle_event()
857 {
858         *output = get_value();
859         return 1;
860 }
861
862
863 FormatMultiple::FormatMultiple(MWindow *mwindow, int x, int y, int *output)
864  : BC_CheckBox(x, 
865         y, 
866         (*output == FILE_PER_LABEL) || (*output == FILE_PER_LABEL_FARM), 
867         _("Create new file at each label"))
868
869         this->output = output;
870         this->mwindow = mwindow;
871 }
872
873 FormatMultiple::~FormatMultiple() 
874 {
875 }
876
877 int FormatMultiple::handle_event()
878 {
879         if(get_value())
880         {
881                 if(mwindow->preferences->use_renderfarm)
882                         *output = FILE_PER_LABEL_FARM;
883                 else
884                         *output = FILE_PER_LABEL;
885         }
886         else
887         {
888                 if(mwindow->preferences->use_renderfarm)
889                         *output = SINGLE_PASS_FARM;
890                 else
891                         *output = SINGLE_PASS;
892         }
893         return 1;
894 }
895
896 void FormatMultiple::update(int *output)
897 {
898         this->output = output;
899         if(*output == FILE_PER_LABEL_FARM ||
900                 *output ==FILE_PER_LABEL)
901                 set_value(1);
902         else
903                 set_value(0);
904 }
905
906