1 /*
2     Generation of subpicture encoding
3 */
4 /*
5  * Copyright (C) 2002, 2003 Jan Panteltje <panteltje@yahoo.com>
6  * With many changes by Scott Smith (trckjunky@users.sourceforge.net)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA.
22  */
23 
24 #include "compat.h"
25 
26 #include <assert.h>
27 
28 #include "subglobals.h"
29 #include "subgen.h"
30 #include "common.h"
31 
32 static int remainbit,subo;
33 
store_init()34 static void store_init()
35 {
36     memset(sub,0,SUB_BUFFER_MAX);
37     remainbit=8;
38     subo=0;
39 }
40 
41 static int bitmask[9]={0,1,3,7,15,31,63,127,255};
store_bits(unsigned int val,int bits)42 static void store_bits(unsigned int val,int bits)
43 {
44     if( subo>SUB_BUFFER_MAX )
45         return;
46     while(bits) {
47         if( bits>remainbit ) {
48             sub[subo++]|=(val>>(bits-remainbit))&bitmask[remainbit];
49             bits-=remainbit;
50             remainbit=8;
51         } else if( bits==remainbit ) {
52             sub[subo++]|=val&bitmask[remainbit];
53             remainbit=8;
54             return;
55         } else {
56             sub[subo]|=(val&bitmask[bits])<<(remainbit-bits);
57             remainbit-=bits;
58             return;
59         }
60     }
61 }
62 
store_2bit(int val)63 static void store_2bit(int val)
64 {
65     assert(val>=0 && val<=3);
66     store_bits(val,2);
67 }
68 
store_nibble(int val)69 static void store_nibble(int val)
70 {
71     assert(val>=0 && val<=15);
72     store_bits(val,4);
73 }
74 
75 
store_trinibble(int val)76 static void store_trinibble(int val)
77 {
78     store_nibble((val>>8)&15);
79     store_nibble((val>>4)&15);
80     store_nibble(val&15);
81 }
82 
store_align()83 static void store_align()
84 {
85     if( remainbit!=8 )
86         store_bits(0,remainbit);
87 }
88 
store_1(int val)89 static void store_1(int val)
90 {
91     store_bits(val,8);
92 }
93 
store_2(int val)94 static void store_2(int val)
95 {
96     store_bits(val,16);
97 }
98 
store_4(unsigned int val)99 static void store_4(unsigned int val)
100 {
101     store_bits(val,32);
102 }
103 
svcd_rotate(stinfo * s)104 static void svcd_rotate(stinfo *s)
105   /* ensures the most popular colour has palette index 0, because that
106     is the only index that SVCD does run-length compression for. */
107   {
108     int cst[4]; /* colour histogram */
109     int i, j;
110     for (i = 0; i < 4; i++)
111         cst[i] = 0;
112     for (i = 0; i < s->xd * s->yd; i++)
113         cst[s->fimg[i]]++;
114     j = 0;
115     for (i = 1; i < 4; i++) /* find most popular colour */
116         if (cst[i] > cst[j])
117             j = i;
118     if (j != 0)
119       { /* rotate entire colour table so most popular colour ends up at index 0 */
120         colorspec p[4];
121         for (i = 0; i < s->xd * s->yd; i++)
122             s->fimg[i] = s->fimg[i] - j & 3;
123         for (i = 0; i < 4; i++)
124             p[i] = s->pal[i + j & 3];
125         memcpy(s->pal, p, 4 * sizeof(colorspec));
126       } /*if*/
127   } /*svcd_rotate*/
128 
svcd_encode(stinfo * s)129 int svcd_encode(stinfo *s)
130 {
131     unsigned int x,y,c,l2o;
132     const colorspec * const epal = s->pal;
133 
134     svcd_rotate(s);
135 
136     store_init();
137     subo = 2;
138     if (s->sd != -1)
139     {
140     store_2(0x2e00);
141         store_4(s->sd);
142     }
143     else
144     {
145     store_2(0x2600);
146     }
147 
148     if (debug > 2)
149     fprintf(stderr,\
150                 "sd: %d   xd: %d  yd: %d  x0: %d  y0: %d\n", s->sd, s->xd, s->yd, s->x0, s->y0);
151 
152     store_2(s->x0);
153     store_2(s->y0);
154     store_2(s->xd);
155     store_2(s->yd);
156     for(c = 0;c<4;c++)
157     {
158     store_1(calcY(&epal[c]));
159     store_1(calcCr(&epal[c]));
160     store_1(calcCb(&epal[c]));
161     store_1(epal[c].a);
162     }
163 
164     store_1(0); //?????
165 
166     l2o = subo;
167     subo += 2;
168     y = 0;
169  odd_row:
170     for(; y<s->yd; y += 2)
171     {
172     for(x = 0; x<s->xd;x++)
173         {
174             if ((c = s->fimg[y*s->xd+x]) != 0) store_2bit(c);
175             else
176             {
177                 c = 1;
178                 while (((++x)<s->xd)  &&  (!s->fimg[y*s->xd+x])) c++;
179                 x--;
180                 while (c>4)
181                 {
182                     store_nibble(3);
183                     c -= 4;
184                 }
185                 store_nibble(c-1);
186             }
187         }
188         store_align();
189     }
190 
191     if (!(y&1))
192     {
193     if (!(subo&1))
194         {
195             if (debug>3)
196                 fprintf(stderr,\
197             "padded betweed fields with 1 byte to %d\n",subo%4);
198             store_1( 0 );
199         }
200     y = 1;
201     sub[l2o] = (subo - l2o - 2) >> 8;
202     sub[l2o+1] = (subo - l2o - 2);
203     goto odd_row;
204     }
205 
206     store_1( 0 );// no additional commands
207     c = 0;
208     while (subo&3)
209     {
210     store_1( 0 ); c++;
211     }
212     if (debug>3) fprintf(stderr,"padded with %d byte\n",c);
213 
214     sub[0] = subo >> 8;
215     sub[1] = subo;
216     if (subo == 65536) return -1;
217     else return subo;
218 } /* end function svcd_encode */
219 
220 
cvd_encode(stinfo * s)221 int cvd_encode(stinfo *s)
222 {
223     unsigned int x, y, c, d;
224     colorspec *epal=s->pal;
225     int ofs, ofs1=0;
226 
227     store_init();
228     subo = 4;
229     ofs = 4;
230 
231     for(y = 0; y < s->yd; y += 2)
232     {
233     odd_row_cvd:
234     for(x = 0; x < s->xd;)
235         {
236             d = s->fimg[y * s->xd + x];
237             c = 1;
238             while (((++x) < s->xd)  &&  (s->fimg[y * s->xd + x] == d) ) c++;
239             if(x == s->xd)
240             {
241                 store_nibble(0);
242                 store_nibble(d);
243                 store_align();
244                 continue;
245             }
246 
247             while(c > 3)
248             {
249                 store_nibble(12 + d);
250                 c -= 3;
251             }
252 
253             store_nibble((c << 2) + d);
254         }
255     }
256 
257     if(!(y & 1))
258     {
259     y = 1;
260     ofs1 = subo;
261     goto odd_row_cvd;
262     }
263 
264     sub[2] = subo >> 8;
265     sub[3] = subo;
266 
267 /* setting this to all 0xff then no more subtitles */
268     store_1( 0x0c );
269     store_1( 0 );
270     store_1( 0 );
271     store_1( 0 );
272 
273 /* set pallette 0-3 */
274     for(c = 0; c < 4; c++)
275     {
276 //#define nco if (subo<65536) sub[subo++]
277     store_1( 0x24 + c );
278     if(debug > 3)
279         {
280             fprintf(stderr, "c=%d R=%.2f G=%.2f B=%.2f\n",\
281                     c, (double)epal[c].r, (double)epal[c].g, (double)epal[c].b);
282         }
283 
284     store_1( calcY(&epal[c]) );
285     store_1( calcCr(&epal[c]) );
286     store_1( calcCb(&epal[c]) );
287 
288     } /* end for pallette 0-3 */
289 
290 /* sethighlight  pallette  */
291     for(c = 0; c < 4; c++)
292     {
293     store_1( 0x2c + c );
294     if(debug > 3)
295         {
296             fprintf(stderr, "c=%d R=%.2f G=%.2f B=%.2f\n",\
297                     c, (double)epal[c].r, (double)epal[c].g, (double)epal[c].b);
298         }
299 
300     store_1( calcY(&epal[c]) );
301     store_1( calcCr(&epal[c]) );
302     store_1( calcCb(&epal[c]) );
303     } /* end for pallette 4-7 */
304 
305     if(debug > 3)
306     {
307     fprintf(stderr,\
308                 "epal[0].a=%d epal[1].a=%d epal[2].a=%d epal[3].a=%d\n",\
309                 epal[0].a, epal[1].a, epal[2].a, epal[3].a);
310     }
311 
312 /* x0, y0 */
313     store_trinibble( 0x17f );
314     store_bits(s->x0,10);
315     store_bits(s->y0,10);
316 
317 /* xd, yd */
318     store_trinibble( 0x1ff );
319     store_bits(s->x0+s->xd-1,10);
320     store_bits(s->y0+s->yd-1,10);
321 
322 /* 0x37 is pallette.a 0-3 contrast */
323     store_2( 0x37ff );
324 //nco = 0x00;
325 //nco = 0xff;
326     store_nibble( epal[3].a >> 4 );
327     store_nibble( epal[2].a >> 4 );
328     store_nibble( epal[1].a >> 4 );
329     store_nibble( epal[0].a >> 4 );
330 
331     if(debug > 3)
332     {
333     fprintf(stderr, "EPALS nco0(2 3h, 2l)=%02x nco1(2 1h,0l)=%02x\n",\
334                 sub[subo - 1], sub[subo - 2]);
335     }
336 
337 /* 0x3f is high light pallette.a 4-7 contrast */
338     store_2( 0x3fff );
339     store_2( 0xfff0 );
340 
341 /* ofs is 4 ? is offset in bitmap to first field data (interlace) */
342     store_2( 0x47ff );
343     store_2( ofs );
344 
345 /* ofs1 is offset to other field in bitmap (interlace) */
346     store_2( 0x4fff );
347     store_2( ofs1 );
348 
349 /* unknown!!! (in RX too!) setting all to 0xff keeps the pic on screen! */
350     store_1( 0x0c );
351     store_1( 0 );
352     store_1( 0 );
353     store_1( 0 );
354 
355 /* sd, time in display, duration */
356     store_1( 0x04 );
357     store_bits( s->sd, 24 );
358 
359 // IA3
360 //0: 02 68 02 24
361 //1: 08 61 08 1d
362 //2: 08 6b 08 27
363 //3: 07 6b 07 27
364 //4: 05 40 04 fc
365 //5: 08 81 08 3d
366 //6: 05 4f 15 40
367 
368 
369     sub[0] = subo >> 8;
370     sub[1] = subo;
371     store_1(4);
372     store_1(8);
373     store_1(12);
374     store_1(16);
375 
376     if(subo == 65536) return -1;
377     else return subo;
378 } /* end function cvd_encode */
379 
380 
do_rle(int count,int color)381 static void do_rle(int count, int color)
382 {
383     int a;
384 
385     /* argument check */
386     assert(count>=1 && count<=255);
387     assert(color>=0 && color<=3);
388 
389     /* make rle code in b */
390     a = (count << 2) | color;
391 
392     /* a now ranges from 0x4 up, because count is at least 1 */
393 
394     if(count >= 64)     // 64 - 255
395     {
396     /* 64-255, 16 bits, 0 0 0 0  0 0 n n  n n n n  n n c c */
397     store_nibble(0);
398     store_nibble( (a & 0xf00) >> 8);
399     store_nibble( (a & 0xf0) >> 4);
400     store_nibble( a & 0xf);
401     }
402     else if(count >= 16)    // 16 - 63
403     {
404     /* 16 - 63, 12 bits, 0 0 0 0  n n n n  n n c c */
405     store_nibble( 0);
406     store_nibble( (a & 0xf0) >> 4);
407     store_nibble( a & 0xf);
408     }
409     else if(count >= 4)     // 4 - 15
410     {
411     /* 4-15, 8 bits, 0 0 n n  n n c c */
412     store_nibble( (a & 0xf0) >> 4);
413     store_nibble( a & 0xf);
414     }
415     else            // 1 - 3
416     {
417     /* 1-3, 4 bits, n n c c */
418     store_nibble( a & 0xf );
419     }
420 } /* end function do_rle */
421 
422 
dvd_encode_row(int y,int xd,unsigned char * icptr)423 static void dvd_encode_row(int y,int xd,unsigned char *icptr)
424 {
425     int new_pos, x;
426     int osubo=subo;
427 
428     new_pos = 0;
429     icptr+=y*xd;
430     for(x = 0; x < xd-1; x++)
431     {
432         /* get color from x,y */
433 
434         if(icptr[x + 1] != icptr[x])
435         {
436             int count=x+1-new_pos;
437             while(count>255) {
438                 do_rle(255,icptr[x]);
439                 count-=255;
440             }
441             if( count )
442                 do_rle(count,icptr[x]);
443             new_pos = x + 1;
444         }
445     } /* end for x */
446 
447     /*
448       One special case,
449       encoding a count of zero using the 16-bit format,
450       indicates the same pixel value until the end of the line.
451     */
452 
453     if( xd != new_pos )
454     {
455         int count=xd-new_pos;
456 
457         if( count < 64 )
458             do_rle(count,icptr[new_pos]);
459         else {
460             /* send same colors to end of line */
461             store_nibble(0);
462             store_nibble(0);
463             store_nibble(0);
464             store_nibble(icptr[new_pos]);
465         }
466     }
467 
468     /*
469       If, at the end of a line, the bit count is not a multiple of 8, four fill bits of 0 are added.
470     */
471 
472     store_align();
473 
474     if( subo-osubo >= 1440/8 ) {
475         fprintf(stderr,"ERR:  Encoded row takes more than 1440 bits.  Please simplify subtitle.\n");
476         exit(1);
477     }
478 }
479 
dvd_encode(stinfo * s)480 int dvd_encode(stinfo *s)
481 {
482     int a;
483     int xstart, xsize;
484     int ystart, ysize;
485     int next_command_ptr;
486     int offset0, offset1;
487     int y;
488     unsigned char *icptr;
489 
490     xstart = s->x0;
491     xsize = s->xd;
492     ystart = s->y0;
493     ysize = s->yd;
494 
495 
496 /*
497   720 x 576 = 414720 bytes, for a 2 bit bitmap = 103680 bytes, compressing MUST reduce this to less then 65536 bytes,
498   or a 2 byte number - overhead 65535 - 65507 = 28 bytes, as max. 65507 is OK).
499   This 23 bytes control buffer, 6 bytes end sequence?
500 */
501 
502     /* encode the .ppm to DVD run length encoded format */
503     /* for all bytes in img */
504 
505 /*
506   (X >> 2) is the number of pixels to display, and (X & 0x3)
507   is the color of the pixel.
508 */
509 
510     icptr = s->fimg;
511 //icptr = img;// use if call to imgfix() commented out
512 
513     store_init();
514     subo=0;
515 
516     //2 bytes packet size, to be filled in later
517     //2 bytes pointer to control area, to be filled in later
518     subo += 4;
519 
520     /* copy image data to sub */
521     offset0=subo;
522     for( y=0; y<s->yd; y+=2 ) /* top field */
523         dvd_encode_row(y,s->xd,icptr);
524 
525     offset1=subo;
526     for( y=1; y<s->yd; y+=2 ) /* bottom field */
527         dvd_encode_row(y,s->xd,icptr);
528 
529     /* start first command block */
530 /*
531    control area starts here, with same pointer
532    SP_DCSQT
533    Sub-Picture Display Control SeQuence Table
534    This area contains blocks (SP_DCSQ) of commands to the decoder.
535    Each SP_DCSQ begins with a 2 word header
536 
537    offset  name            contents
538    0       SP_DCSQ_STM     delay to wait before executing these commands.
539    The units are 90KHz clock (same as PTM) divided by 1024 - see below.
540 
541    2       SP_NXT_DCSQ_SA  offset within the Sub-Picture Unit to the next SP_DCSQ.
542    If this is the last SP_DCSQ, it points to itself.
543 
544    Converting frames and time to SP_DCSQ_STM values
545    The direct method of converting time to delay values is to multiply time in seconds
546    by 90000/1024 and truncate the value.
547    Rounding up will cause the display to occur one frame late.
548 */
549 
550     /* set pointer to this command block */
551     a = subo;
552     sub[2] = a >> 8;
553     sub[3] = a;
554 
555     store_2(0); // delay to wait before executing this command block
556 
557     /* remember position, will set later */
558     next_command_ptr = subo;
559     subo+=2; // pointer to next command block, 2 bytes, to be filled in from next command block.
560 
561 
562     if( s->forced )
563         store_1(SPU_FSTA_DSP); /* command 0, forced start display, 1 byte. */
564     else
565         store_1(SPU_STA_DSP); /* command 1, start display, 1 byte */
566 
567     /* selected palettes for pixel value */
568 
569     /* command 3, palette, 3 bytes */
570     store_1(SPU_SET_COLOR);
571     store_nibble(findmasterpal(s,&s->pal[3]));
572     store_nibble(findmasterpal(s,&s->pal[2]));
573     store_nibble(findmasterpal(s,&s->pal[1]));
574     store_nibble(findmasterpal(s,&s->pal[0]));
575 
576     /* command 4, alpha blend, contrast / transparency t_palette, 3 bytes  0, 15, 15, 15 */
577     store_1(SPU_SET_CONTR);
578     store_nibble(s->pal[3].a>>4);
579     store_nibble(s->pal[2].a>>4);
580     store_nibble(s->pal[1].a>>4);
581     store_nibble(s->pal[0].a>>4);
582 
583     /* command 5, display area, 7 bytes from: startx, xsize, starty, ysize */
584     store_1(SPU_SET_DAREA);
585     store_trinibble(xstart);
586     store_trinibble(xstart+xsize-1);
587     store_trinibble(ystart);
588     store_trinibble(ystart+ysize-1);
589 
590     /* command 6, image offsets, 5 bytes */
591     store_1(SPU_SET_DSPXA);
592     store_2(offset0);
593     store_2(offset1);
594 
595     /* command 0xff, end command block, 1 byte, */
596     store_1(SPU_CMD_END);
597 
598     /* end first command block */
599 
600 
601     /* start second command block */
602 
603     if( s->sd>=0 ) {
604         int duration;
605 
606         /* set pointer in previous block to point to this position */
607         a = subo;
608         sub[next_command_ptr+0] = a >> 8;
609         sub[next_command_ptr+1] = a;
610 
611         /* update pointer to this command block */
612         next_command_ptr = subo;
613 
614         /* delay to wait before executing next comand */
615         duration = (s->sd+512)/1024;
616         while( duration >= 65536 ) {
617           /* duration too long for one command block, generate additional command blocks
618             that do nothing but delay */
619             store_2(65535);
620             duration-=65535;
621             store_2(next_command_ptr+5);
622             store_1(SPU_CMD_END);
623             next_command_ptr = subo;
624         }
625 
626         store_2(duration);
627 
628         /* last block, point to self */
629         store_2(next_command_ptr);
630 
631         /* stop command (executed after above delay) */
632         store_1(SPU_STP_DSP);
633 
634         /* end command block command */
635         store_1(SPU_CMD_END);
636     } else {
637         a=next_command_ptr-2;
638         sub[next_command_ptr+0] = a >> 8;
639         sub[next_command_ptr+1] = a;
640     }
641 
642     /* end second commmand block */
643 
644 
645     /* make size even if odd */
646     if(subo & 1)
647     {
648     /* only if odd length, to make it even */
649     store_1(SPU_CMD_END);
650     }
651 
652     /* set subtitle packet size */
653     a = subo;
654     sub[0] = a >> 8;
655     sub[1] = a;
656 
657     if( a >= SUB_BUFFER_MAX )
658         return -1;
659     return a;
660 } /* end function dvd_encode */
661