1 /*******************************************************************************
2  avi_indx.c
3 
4  libquicktime - A library for reading and writing quicktime/avi/mp4 files.
5  http://libquicktime.sourceforge.net
6 
7  Copyright (C) 2002 Heroine Virtual Ltd.
8  Copyright (C) 2002-2011 Members of the libquicktime project.
9 
10  This library is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free
12  Software Foundation; either version 2.1 of the License, or (at your option)
13  any later version.
14 
15  This library is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  details.
19 
20  You should have received a copy of the GNU Lesser General Public License along
21  with this library; if not, write to the Free Software Foundation, Inc., 51
22  Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *******************************************************************************/
24 
25 #include "lqt_private.h"
26 #include <stdlib.h>
27 #include <string.h>
28 
quicktime_delete_indx(quicktime_indx_t * indx)29 void quicktime_delete_indx(quicktime_indx_t *indx)
30   {
31   int i;
32   if(indx->table)
33     {
34     for(i = 0; i < indx->table_size; i++)
35       {
36       quicktime_indxtable_t *indx_table = &indx->table[i];
37       if(indx_table->ix) quicktime_delete_ix(indx_table->ix);
38       }
39     free(indx->table);
40     }
41   }
42 
quicktime_init_indx(quicktime_t * file,quicktime_indx_t * indx,quicktime_strl_t * strl)43 void quicktime_init_indx(quicktime_t *file,
44                          quicktime_indx_t *indx,
45                          quicktime_strl_t *strl)
46   {
47   indx->longs_per_entry = 4;
48   indx->index_subtype = 0;
49   indx->index_type = AVI_INDEX_OF_INDEXES;
50   memcpy(indx->chunk_id, strl->tag, 4);
51   }
52 
quicktime_indx_init_riff(quicktime_t * file,quicktime_trak_t * trak)53 void quicktime_indx_init_riff(quicktime_t *file, quicktime_trak_t * trak)
54   {
55   quicktime_strl_t * strl;
56   quicktime_indx_t * indx;
57   quicktime_indxtable_t *indx_table;
58 
59   strl = trak->strl;
60   indx = &strl->indx;
61 
62 
63   if(indx->table_size >= indx->table_allocation)
64     {
65     int new_allocation = indx->table_allocation * 2;
66     if(new_allocation < 1) new_allocation = 1;
67 
68     indx->table = realloc(indx->table, new_allocation * sizeof(quicktime_indxtable_t));
69     memset(indx->table + indx->table_size, 0, new_allocation - indx->table_size);
70     indx->table_allocation = new_allocation;
71     }
72 
73   /* Append */
74   indx_table = &indx->table[indx->table_size++];
75   indx_table->ix = quicktime_new_ix(file, trak, strl);
76 
77   }
78 
quicktime_indx_finalize_riff(quicktime_t * file,quicktime_trak_t * trak)79 void quicktime_indx_finalize_riff(quicktime_t *file, quicktime_trak_t * trak)
80   {
81   quicktime_strl_t * strl;
82   quicktime_indx_t * indx;
83   quicktime_indxtable_t *indx_table;
84 
85   strl = trak->strl;
86   indx = &strl->indx;
87 
88   indx_table = &indx->table[indx->table_size-1];
89 
90   quicktime_write_ix(file, trak);
91 
92   indx_table->index_offset = indx_table->ix->atom.start - 8;
93   indx_table->index_size   = indx_table->ix->atom.size;
94   indx_table->duration     = indx_table->ix->table_size;
95   }
96 
97 
quicktime_finalize_indx(quicktime_t * file,quicktime_indx_t * indx)98 void quicktime_finalize_indx(quicktime_t *file, quicktime_indx_t * indx)
99   {
100   int j;
101   quicktime_atom_t junk_atom;
102 
103   quicktime_set_position(file, indx->offset);
104 
105   /* Write indx */
106   //  quicktime_set_position(file, strl->indx_offset);
107   quicktime_atom_write_header(file, &indx->atom, "indx");
108   /* longs per entry */
109   quicktime_write_int16_le(file, indx->longs_per_entry);
110   /* index sub type */
111   quicktime_write_char(file, indx->index_subtype);
112   /* index type */
113   quicktime_write_char(file, indx->index_type);
114   /* entries in use */
115   quicktime_write_int32_le(file, indx->table_size);
116   /* chunk ID */
117   quicktime_write_char32(file, indx->chunk_id);
118   /* reserved */
119   quicktime_write_int32_le(file, 0);
120   quicktime_write_int32_le(file, 0);
121   quicktime_write_int32_le(file, 0);
122 
123   /* table */
124   for(j = 0; j < indx->table_size; j++)
125     {
126     quicktime_indxtable_t *indx_table = &indx->table[j];
127     quicktime_write_int64_le(file, indx_table->index_offset);
128     quicktime_write_int32_le(file, indx_table->index_size);
129     quicktime_write_int32_le(file, indx_table->duration);
130     }
131 
132   quicktime_atom_write_footer(file, &indx->atom);
133 
134   quicktime_atom_write_header(file, &junk_atom, "JUNK");
135 
136   while(quicktime_position(file) < indx->offset + indx->size)
137     quicktime_write_char(file, 0);
138   quicktime_atom_write_footer(file, &junk_atom);
139   }
140 
quicktime_read_indx(quicktime_t * file,quicktime_strl_t * strl,quicktime_atom_t * parent_atom)141 void quicktime_read_indx(quicktime_t *file,
142                          quicktime_strl_t *strl,
143                          quicktime_atom_t *parent_atom)
144   {
145   quicktime_indx_t *indx = &strl->indx;
146   quicktime_indxtable_t *indx_table;
147   quicktime_ix_t *ix;
148   int i;
149   int64_t offset;
150 
151   file->file_type = LQT_FILE_AVI_ODML;
152 
153   indx->longs_per_entry = quicktime_read_int16_le(file);
154   indx->index_subtype = quicktime_read_char(file);
155   indx->index_type = quicktime_read_char(file);
156   indx->table_size = quicktime_read_int32_le(file);
157   quicktime_read_char32(file, indx->chunk_id);
158   quicktime_read_int32_le(file);
159   quicktime_read_int32_le(file);
160   quicktime_read_int32_le(file);
161 
162   /* Read indx entries */
163   indx->table = calloc(indx->table_size, sizeof(quicktime_indxtable_t));
164   for(i = 0; i < indx->table_size; i++)
165     {
166     indx_table = &indx->table[i];
167     indx_table->index_offset = quicktime_read_int64_le(file);
168     indx_table->index_size = quicktime_read_int32_le(file);
169     indx_table->duration = quicktime_read_int32_le(file);
170     offset = quicktime_position(file);
171 
172     /* Now read the partial index */
173     ix = indx_table->ix = calloc(1, sizeof(quicktime_ix_t));
174     quicktime_set_position(file, indx_table->index_offset);
175     quicktime_read_ix(file, ix);
176     quicktime_set_position(file, offset);
177     }
178 
179   }
180 
quicktime_set_indx_keyframe(quicktime_t * file,quicktime_trak_t * trak,long new_keyframe)181 void quicktime_set_indx_keyframe(quicktime_t *file,
182                                  quicktime_trak_t *trak,
183                                  long new_keyframe)
184   {
185   long frame_count;
186   int i;
187   quicktime_indx_t *indx = &trak->strl->indx;
188 
189   /* Get the right ix table */
190   frame_count = 0;
191   i = 0;
192 
193 
194   while(frame_count + indx->table[i].ix->table_size < new_keyframe)
195     {
196     frame_count+= indx->table[i].ix->table_size;
197     i++;
198     }
199   indx->table[i].ix->table[new_keyframe - frame_count].size &= 0x7fffffff;
200   }
201 
quicktime_indx_dump(quicktime_indx_t * indx)202 void quicktime_indx_dump(quicktime_indx_t *indx)
203   {
204   int i;
205   lqt_dump(" indx");
206   lqt_dump(" longs_per_entry: %d\n", indx->longs_per_entry);
207   lqt_dump(" index_subtype:   %d\n", indx->index_subtype);
208   lqt_dump(" index_type:      %d\n", indx->index_type);
209   lqt_dump(" chunk_id:        %s\n", indx->chunk_id);
210   lqt_dump(" table_size:      %d\n", indx->table_size);
211 
212   for(i = 0; i < indx->table_size; i++)
213     {
214     lqt_dump("   index_offset: %"PRId64"\n", indx->table[i].index_offset);
215     lqt_dump("   index_size:   %d\n", indx->table[i].index_size);
216     lqt_dump("   duration:     %d\n", indx->table[i].duration);
217     quicktime_ix_dump(indx->table[i].ix);
218     }
219 
220   }
221 
222