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