1 /********************************************************************
3 * THIS FILE IS PART OF THE OggWrit SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggWrit SOURCE CODE IS (C) COPYRIGHT 2003 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 encode.c: Writ stream encoding
14 last mod: $Id: encode.c,v 1.3 2003/12/09 20:40:50 arc Exp $
16 ********************************************************************/
20 #include <writ/writ.h>
22 int writ_encode_init(writ_state
*ws
, ogg_uint32_t granule_num
,
23 ogg_uint32_t granule_den
) {
24 ws
= _ogg_malloc(sizeof(writ_state
));
29 ws
->opb
= _ogg_malloc(oggpack_buffersize());
30 ws
->opb_state
= ogg_buffer_create();
32 ws
->wi
= _ogg_malloc(sizeof(writ_info
));
33 ws
->wi
->subversion
= 0;
34 ws
->wi
->granulerate_numerator
= granule_num
;
35 ws
->wi
->granulerate_denominator
= granule_den
;
40 int writ_encode_clear(writ_state
*ws
) {
48 int writ_encode_lang_add(writ_state
*ws
, char *name
, char *desc
) {
49 writ_language
*new_lang
;
50 int name_length
= strlen(name
);
51 int desc_length
= strlen(desc
);
53 if (ws
->wi
->subversion
== 0) {
54 ws
->wi
->subversion
= 1;
55 ws
->wi
->num_languages
= 0;
56 ws
->wi
->languages
= malloc(sizeof(writ_language
)*256);
58 if (ws
->wi
->num_languages
== 255) return -8;
59 ws
->wi
->num_languages
++;
61 new_lang
= ws
->wi
->languages
+ ws
->wi
->num_languages
;
62 new_lang
->language_name
.length
= name_length
;
63 new_lang
->language_name
.string
= malloc(name_length
+desc_length
);
64 memcpy(new_lang
->language_name
.string
, name
, name_length
);
65 new_lang
->language_desc
.length
= desc_length
;
66 new_lang
->language_desc
.string
= new_lang
->language_name
.string
+
68 memcpy(new_lang
->language_desc
.string
, desc
, desc_length
);
70 return ws
->wi
->num_languages
;
73 int writ_encode_wind_init(writ_state
*ws
, int scale_x
, int scale_y
) {
74 if (ws
->wi
->subversion
== 0) return -1; /* Lang must come first */
75 if (ws
->wi
->subversion
>= 2) return -1; /* Windows already init */
77 ws
->wi
->location_scale_x
= scale_x
;
78 ws
->wi
->location_scale_y
= scale_y
;
79 ws
->wi
->num_windows
= 0;
80 ws
->wi
->windows
= malloc(sizeof(writ_window
)*256);
85 int writ_encode_wind_add(writ_state
*ws
, int left
, int top
, int width
,
86 int height
, int align_x
, int align_y
) {
87 if (ws
->wi
->num_windows
== 255) return -8;
89 ws
->wi
->windows
[ws
->wi
->num_windows
].location_x
= left
;
90 ws
->wi
->windows
[ws
->wi
->num_windows
].location_y
= top
;
91 ws
->wi
->windows
[ws
->wi
->num_windows
].location_width
= width
;
92 ws
->wi
->windows
[ws
->wi
->num_windows
].location_height
= height
;
93 ws
->wi
->windows
[ws
->wi
->num_windows
].alignment_x
= align_x
;
94 ws
->wi
->windows
[ws
->wi
->num_windows
].alignment_y
= align_y
;
95 ws
->wi
->num_windows
++;
101 int writ_encode_packetout(writ_state
*ws
, ogg_packet
**op
) {
104 if ( ws
->granulepos
!= -1 ) return -1;
106 oggpack_writeinit(ws
->opb
, ws
->opb_state
);
107 oggpack_write(ws
->opb
, 0, 8);
108 oggpack_write(ws
->opb
, 1953067639, 32);
109 oggpack_write(ws
->opb
, 0, 8);
110 oggpack_write(ws
->opb
, ws
->wi
->subversion
, 8);
111 oggpack_write(ws
->opb
, ws
->wi
->granulerate_numerator
, 32);
112 oggpack_write(ws
->opb
, ws
->wi
->granulerate_denominator
, 32);
113 ws
->packet_queue
[0] = oggpack_writebuffer(ws
->opb
);
115 if (ws
->wi
->subversion
> 0) {
118 oggpack_writeinit(ws
->opb
, ws
->opb_state
);
119 oggpack_write(ws
->opb
, 1, 8);
120 oggpack_write(ws
->opb
, 1953067639, 32);
121 oggpack_write(ws
->opb
, ws
->wi
->num_languages
, 8);
122 /* One or more times */
123 for (i
=0; i
<=ws
->wi
->num_languages
; i
++) {
124 wl
= ws
->wi
->languages
+ i
;
125 writ_text_write(ws
->opb
, wl
.language_name
);
126 writ_text_write(ws
->opb
, wl
.language_desc
);
128 ws
->packet_queue
[1] = oggpack_writebuffer(ws
->opb
);
130 if (ws
->wi
->subversion
> 1) {
131 int bitx
= ilog(ws
->wi
->location_scale_x
);
132 int bity
= ilog(ws
->wi
->location_scale_y
);
134 oggpack_writeinit(ws
->opb
, ws
->opb_state
);
135 oggpack_write(ws
->opb
, 2, 8);
136 oggpack_write(ws
->opb
, 1953067639, 32);
137 oggpack_write(ws
->opb
, ws
->wi
->location_scale_x
, 16);
138 oggpack_write(ws
->opb
, ws
->wi
->location_scale_y
, 16);
139 oggpack_write(ws
->opb
, ws
->wi
->num_windows
, 8);
140 /* Zero or more times */
141 for (i
=0; i
< ws
->wi
->num_windows
; i
++) {
142 wn
= ws
->wi
->windows
+ i
;
143 oggpack_write(ws
->opb
, wn
.location_x
, bitx
);
144 oggpack_write(ws
->opb
, wn
.location_y
, bity
);
145 oggpack_write(ws
->opb
, wn
.location_width
, bitx
);
146 oggpack_write(ws
->opb
, wn
.location_height
, bity
);
147 oggpack_write(ws
->opb
, wn
.alignment_x
, 2);
148 oggpack_write(ws
->opb
, wn
.alignment_y
, 2);
150 ws
->packet_queue
[2] = oggpack_writebuffer(ws
->opb
);