1 # h261-titling.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1999-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 import DaliSubprogram
32 import RealParameter
33 import TextParameter
34 import IntParameter
35 import ColorParameter
36
37 Class H261TitleSubprogram -superclass DaliSubprogram
38
39 H261TitleSubprogram instproc init {args} {
40 eval $self next $args;
41
42 # Set up inputs
43
44 $self instvar input_id_list_;
45 $self instvar input_info_;
46
47 lappend input_id_list_ i1
48
49 set input_info_(i1,spec) "";
50 set input_info_(i1,trigger) 0;
51 set input_info_(i1,buffertype) Uncompressed;
52 set input_info_(i1,buffername) [new VidRep/Uncompressed];
53 set input_info_(i1,decoder) "";
54 set input_info_(i1,primary_trigger) 1
55
56 # Set up outputs
57
58 $self instvar output_id_list_;
59 $self instvar output_info_;
60
61 lappend output_id_list_ o1;
62
63 set output_info_(o1,spec) "";
64 set output_info_(o1,buffertype) Uncompressed;
65 set output_info_(o1,buffername) [new VidRep/Uncompressed];
66 set output_info_(o1,encoder) "";
67 set output_info_(o1,format) H261;
68 set output_info_(o1,vagent) "";
69
70 # Set up which input will drive each output's synchronization
71 $self set_ntp_reference i1 o1
72
73 # Set up parameters
74
75 $self instvar parameter_id_list_;
76 $self instvar parameter_info_;
77
78 lappend parameter_id_list_ text
79 set pobj [new TextParameter];
80 set parameter_info_(text,oname) $pobj;
81 $pobj set "";
82
83 lappend parameter_id_list_ xpos
84 set pobj [new RealParameter];
85 set parameter_info_(xpos,oname) $pobj;
86 $pobj from 0.0
87 $pobj to 1.0
88 $pobj set 0.0
89
90 lappend parameter_id_list_ ypos
91 set pobj [new RealParameter];
92 set parameter_info_(ypos,oname) $pobj;
93 $pobj from 0.0
94 $pobj to 1.0
95 $pobj set 0.0
96
97 lappend parameter_id_list_ back_color
98 set pobj [new ColorParameter];
99 set parameter_info_(back_color,oname) $pobj;
100 $pobj from [list 0 0 0]
101 $pobj to [list 255 255 255]
102 $pobj set [list 0 128 128];
103
104 lappend parameter_id_list_ text_color
105 set pobj [new ColorParameter];
106 set parameter_info_(text_color,oname) $pobj;
107 $pobj from [list 0 0 0]
108 $pobj to [list 255 255 255]
109 $pobj set [list 255 128 128];
110
111 lappend parameter_id_list_ point_size;
112 set pobj [new IntParameter];
113 set parameter_info_(point_size,oname) $pobj;
114 $pobj from 5
115 $pobj to 40
116 $pobj set 30
117
118 lappend parameter_id_list_ font
119 set pobj [new ExclusiveChoiceParameter];
120 set parameter_info_(font,oname) $pobj;
121 $pobj add "Times-Roman"
122 $pobj add "Times-Bold"
123 $pobj add "Times-Italic"
124 $pobj add "Helvetica"
125 $pobj add "Helvetica-Bold"
126 $pobj add "Helvetica-Narrow"
127 $pobj set "Times-Roman"
128
129 lappend parameter_id_list_ back_alpha
130 set pobj [new RealParameter];
131 set parameter_info_(back_alpha,oname) $pobj;
132 $pobj from 0.0
133 $pobj to 1.0
134 $pobj set 0.5
135
136 lappend parameter_id_list_ master_alpha
137 set pobj [new RealParameter];
138 set parameter_info_(master_alpha,oname) $pobj;
139 $pobj from 0.0
140 $pobj to 1.0
141 $pobj set 0.0
142
143 $self instvar comm_obj_;
144 $comm_obj_ setup;
145 }
146
147 H261TitleSubprogram instproc trigger {} {
148 $self instvar comm_obj_;
149
150 $self instvar parameter_id_list_;
151
152 foreach p $parameter_id_list_ {
153 if {![$comm_obj_ parameter_attr_has_value $p value]} {
154 return;
155 }
156 }
157
158 $self instvar init_done_;
159 $self instvar input_info_ output_info_
160
161 $self instvar old_xpos_ old_ypos_ old_text_ old_sz_ old_font_
162 $self instvar old_balpha_ old_malpha_;
163
164 set in_frame $input_info_(i1,buffername);
165 set out_frame $output_info_(o1,buffername);
166
167 if {![info exists init_done_]} {
168 # Stuff to do only the first time
169 if {[$in_frame set w_] == 0} {
170 return;
171 }
172 $out_frame copy_geometry $in_frame;
173 $out_frame allocate;
174
175 set old_xpos_ "";
176 set old_ypos_ "";
177 set old_text_ "";
178 set old_sz_ "";
179 set old_font_ "";
180 set old_balpha_ "";
181 set old_malpha_ "";
182 set init_done_ 1;
183 }
184
185 $self instvar parameter_info_;
186
187 set xpos [$parameter_info_(xpos,oname) get];
188 set ypos [$parameter_info_(ypos,oname) get];
189 set text [$parameter_info_(text,oname) get];
190 set sz [$parameter_info_(point_size,oname) get];
191 set font [$parameter_info_(font,oname) get];
192 set balpha [$parameter_info_(back_alpha,oname) get];
193 set malpha [$parameter_info_(master_alpha,oname) get];
194 set bcolor [$parameter_info_(back_color,oname) get];
195 set tcolor [$parameter_info_(text_color,oname) get];
196
197 $self instvar y_clip_ cr_clip_ cb_clip_;
198 $self instvar text_mask_ inv_text_mask_;
199 $self instvar alpha_text_mask_ alpha_inv_text_mask_;
200 $self instvar subsamp_alpha_text_mask_ subsamp_alpha_inv_text_mask_;
201
202 set recalc_alphas 0;
203
204 if {$old_xpos_ != $xpos || $old_ypos_ != $ypos || $old_text_ != $text || $old_sz_ != $sz || $old_font_ != $font} {
205 # Do changes associated with xpos, ypos and text
206
207 if {($old_sz_ != $sz) || ($old_text_ != $text) || ($old_font_ != $font)} {
208
209 if {[info exists text_mask_]} {
210 byte_free $text_mask_;
211 }
212 if {[info exists inv_text_mask_]} {
213 byte_free $inv_text_mask_;
214 }
215 if {[info exists alpha_text_mask_]} {
216 byte_free $alpha_text_mask_;
217 }
218 if {[info exists alpha_inv_text_mask_]} {
219 byte_free $alpha_inv_text_mask_;
220 }
221 if {[info exists subsamp_alpha_text_mask_]} {
222 byte_free $subsamp_alpha_text_mask_;
223 }
224 if {[info exists subsamp_alpha_inv_text_mask_]} {
225 byte_free $subsamp_alpha_inv_text_mask_;
226 }
227
228 set text_mask_ [$self DrawString $text $sz $font];
229 set old_text_ $text;
230 set old_sz_ $sz;
231 set old_font_ $font;
232
233 set inv_text_mask_ [byte_new [byte_get_width $text_mask_] [byte_get_height $text_mask_]];
234 byte_not $text_mask_ $inv_text_mask_
235
236 set alpha_text_mask_ [byte_new [byte_get_width $text_mask_] [byte_get_height $text_mask_]];
237 set alpha_inv_text_mask_ [byte_new [byte_get_width $text_mask_] [byte_get_height $text_mask_]];
238
239 set subsamp_alpha_text_mask_ [byte_new [expr [byte_get_width $text_mask_] / [$out_frame set h_subsample_]] [expr [byte_get_height $text_mask_] / [$out_frame set v_subsample_]]];
240
241 set subsamp_alpha_inv_text_mask_ [byte_new [expr [byte_get_width $text_mask_] / [$out_frame set h_subsample_]] [expr [byte_get_height $text_mask_] / [$out_frame set v_subsample_]]];
242
243 set recalc_alphas 1;
244 }
245
246 set old_xpos_ $xpos;
247 set old_ypos_ $ypos;
248
249 set str_width [byte_get_width $text_mask_];
250 set str_height [byte_get_height $text_mask_];
251
252 set left [expr int($xpos * [$out_frame set true_w_])];
253 set right [expr $left + $str_width - 1];
254 set top [expr int($ypos * [$out_frame set true_h_])];
255 set bottom [expr $top + $str_height - 1];
256
257 if {$left < 0} {set left 0};
258 if {$right > [$out_frame set true_w_]} {set right [$out_frame set true_w_]};
259 if {$top < 0} {set top 0};
260 if {$bottom > [$out_frame set true_h_]} {set bottom [$out_frame set true_h_]};
261
262 if {[info exists y_clip_]} {
263 byte_free $y_clip_;
264 unset y_clip_;
265 }
266 if {[info exists cr_clip_]} {
267 byte_free $cr_clip_;
268 unset cr_clip_;
269 }
270 if {[info exists cb_clip_]} {
271 byte_free $cb_clip_;
272 unset cb_clip_;
273 }
274
275 set cwidth [expr $right - $left + 1];
276 set cheight [expr $bottom - $top + 1];
277
278 set y_clip_ [byte_clip [$out_frame get_lum_name] $left $top $cwidth $cheight];
279 set cr_clip_ [byte_clip [$out_frame get_cr_name] [expr $left / [$out_frame set h_subsample_]] [expr $top / [$out_frame set v_subsample_]] [expr $cwidth / [$out_frame set h_subsample_]] [expr $cheight / [$out_frame set v_subsample_]]];
280 set cb_clip_ [byte_clip [$out_frame get_cb_name] [expr $left / [$out_frame set h_subsample_]] [expr $top / [$out_frame set v_subsample_]] [expr $cwidth / [$out_frame set h_subsample_]] [expr $cheight / [$out_frame set v_subsample_]]];
281 }
282
283 if {$old_balpha_ != $balpha || $old_malpha_ != $malpha || $recalc_alphas == 1} {
284 set old_balpha_ $balpha;
285 set old_malpha_ $malpha;
286
287 byte_scalar_mult $inv_text_mask_ $alpha_inv_text_mask_ [expr $balpha * $malpha];
288 byte_scalar_add $alpha_inv_text_mask_ $alpha_inv_text_mask_ [expr int(((1.0 - $balpha) * $malpha * 255) + ((1.0 - $malpha) * 255))];
289
290 byte_scalar_mult $text_mask_ $alpha_text_mask_ $malpha;
291 byte_scalar_add $alpha_text_mask_ $alpha_text_mask_ [expr int(255 * (1.0 - $malpha))];
292
293 if {[$out_frame set h_subsample_] == 2} {
294 if {[$out_frame set v_subsample_] == 2} {
295 byte_shrink_2x2 $alpha_text_mask_ $subsamp_alpha_text_mask_;
296 byte_shrink_2x2 $alpha_inv_text_mask_ $subsamp_alpha_inv_text_mask_;
297 } else {
298 byte_shrink_2x1 $alpha_text_mask_ $subsamp_alpha_text_mask_;
299 byte_shrink_2x1 $alpha_inv_text_mask_ $subsamp_alpha_inv_text_mask_;
300 }
301 } else {
302 if {[$out_frame set v_subsample_] == 2} {
303 byte_shrink_1x2 $alpha_text_mask_ $subsamp_alpha_text_mask_;
304 byte_shrink_1x2 $alpha_inv_text_mask_ $subsamp_alpha_inv_text_mask_;
305 } else {
306 byte_copy $alpha_text_mask_ $subsamp_alpha_text_mask_;
307 byte_copy $alpha_inv_text_mask_ $subsamp_alpha_inv_text_mask_;
308 }
309 }
310 }
311
312 byte_copy [$in_frame get_lum_name] [$out_frame get_lum_name];
313 byte_copy [$in_frame get_cr_name] [$out_frame get_cr_name];
314 byte_copy [$in_frame get_cb_name] [$out_frame get_cb_name];
315
316 set blum [lindex $bcolor 0];
317 set bcr [lindex $bcolor 1];
318 set bcb [lindex $bcolor 2];
319
320 byte_set_with_alpha_mask $y_clip_ $alpha_inv_text_mask_ $blum;
321 byte_set_with_alpha_mask $cr_clip_ $subsamp_alpha_inv_text_mask_ $bcr;
322 byte_set_with_alpha_mask $cb_clip_ $subsamp_alpha_inv_text_mask_ $bcb;
323
324 set tlum [lindex $tcolor 0];
325 set tcr [lindex $tcolor 1];
326 set tcb [lindex $tcolor 2];
327
328 byte_set_with_alpha_mask $y_clip_ $alpha_text_mask_ $tlum
329 byte_set_with_alpha_mask $cr_clip_ $subsamp_alpha_text_mask_ $tcr
330 byte_set_with_alpha_mask $cb_clip_ $subsamp_alpha_text_mask_ $tcb
331
332 $out_frame set ts_ [$in_frame set ts_];
333
334 set encoder $output_info_(o1,encoder);
335
336 if {$encoder != ""} {
337 $encoder recv $out_frame;
338 }
339
340 $self send_completion_token
341
342 [[[[$input_info_(i1,decoder) set agent_] set network_] set net_(0)] set dn_] recv_flush
343
344 }
345
346
347 H261TitleSubprogram instproc DrawString {str sz font} {
348 $self instvar id_;
349
350 set coord_file "gs_${id_}.out";
351 set pgm_file "gs_${id_}.pgm";
352 set cut_file "gs_${id_}_cut.pgm";
353
354 exec rm -f $coord_file
355 exec rm -f $pgm_file
356 set gs_fp [open "| gs -q -sDEVICE=pgmraw -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$pgm_file > $coord_file" w];
357
358 puts $gs_fp "/$font findfont $sz scalefont setfont"
359 puts $gs_fp "0 0 moveto"
360 puts $gs_fp "($str) true charpath flattenpath pathbbox"
361 puts $gs_fp "(\\ncoords\\n) print stack"
362 puts $gs_fp "pop"
363 puts $gs_fp "pop"
364 puts $gs_fp "-1 mul"
365 puts $gs_fp "2 1 roll"
366 puts $gs_fp "-1 mul"
367 puts $gs_fp "2 1 roll"
368 puts $gs_fp "translate"
369 puts $gs_fp "0 0 moveto"
370 puts $gs_fp "($str) show"
371 puts $gs_fp "showpage";
372 close $gs_fp;
373
374 set fp [open "$coord_file" r];
375 set nline [gets $fp];
376 while {$nline != "coords"} {
377 set nline [gets $fp];
378 }
379 set y2 [gets $fp];
380 set x2 [gets $fp];
381 set y1 [gets $fp];
382 set x1 [gets $fp];
383
384 close $fp;
385
386 set width [expr int($x2 - $x1 + 0.5)];
387 set height [expr int($y2 - $y1 + 0.5)];
388
389 exec rm -f $cut_file
390 exec pnmcut 0 [expr -1 * $height] $width $height $pgm_file > $cut_file
391 exec mv $cut_file $pgm_file
392
393 set bs [bitstream_mmap_read_new $pgm_file];
394 set bp [bitparser_new];
395 bitparser_wrap $bp $bs;
396
397 set hdr [pnm_hdr_new];
398
399 pnm_hdr_parse $bp $hdr;
400
401 set bimage [byte_new [pnm_hdr_get_width $hdr] [pnm_hdr_get_height $hdr]];
402 pgm_parse $bp $bimage;
403
404 bitparser_free $bp
405 bitstream_mmap_read_free $bs
406 pnm_hdr_free $hdr
407
408 return $bimage
409 }
410
411
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.