main.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "vint.h"
  2. #include "header.h"
  3. #include "ebml_float.h"
  4. #include "segment.h"
  5. #include "ebml_unsigned.h"
  6. #include "ebml_signed.h"
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include "SeekTable.h"
  10. #include <time.h>
  11. #include "parser.h"
  12. #include "SegmentInfo.h"
  13. #include "global_elements.h"
  14. #include "Tracks.h"
  15. #include "Cluster.h"
  16. #include "Cues.h"
  17. #include "Chapters.h"
  18. #include "Tags.h"
  19. #include "read.h"
  20. #include "Attachments.h"
  21. using namespace nsmkv;
  22. static nsmkv::SeekTable seekTable;
  23. static nsmkv::Header header;
  24. static SegmentInfo segment_info;
  25. static Tracks tracks;
  26. static Cues cues;
  27. static Attachments attachments;
  28. static Tags tags;
  29. uint64_t max_id_length = header.ebml_max_id_length;
  30. uint64_t max_size_length = header.ebml_max_size_length;
  31. uint32_t num_seekhead_elements_found = 0;
  32. uint32_t num_seek_elements_found = 0;
  33. bool ebml_segment_found = false;
  34. uint64_t segment_data_offset = 0;
  35. // returns bytes read. 0 means EOF
  36. uint64_t read_vsint(FILE *f, int64_t *val)
  37. {
  38. uint8_t data[9];
  39. size_t bytes_read = fread(data, 1, 1, f);
  40. if (bytes_read != 1)
  41. return 0;
  42. uint8_t length = vint_get_number_bytes(data[0]);
  43. bytes_read = fread(data+1, 1, length, f);
  44. if (bytes_read != length)
  45. return 0;
  46. *val = vsint_read_ptr_len(length+1, data);
  47. return bytes_read+1;
  48. }
  49. char *read_utf8(FILE *f, size_t size)
  50. {
  51. char *doctype = (char *)malloc(size + 1);
  52. if (doctype)
  53. {
  54. doctype[size]=0;
  55. if (fread(doctype, 1, size, f) == size)
  56. return doctype;
  57. }
  58. free(doctype);
  59. return 0;
  60. }
  61. // returns bytes read. 0 means EOF
  62. uint64_t ReadSegment(FILE *f, uint64_t size)
  63. {
  64. uint64_t total_bytes_read=0;
  65. // store the segment element data offset for later use
  66. segment_data_offset = ftell(f);
  67. #ifdef WA_VALIDATE
  68. printf("[%I64u] Segment element data offset\n", segment_data_offset);
  69. #endif
  70. while (size)
  71. {
  72. uint64_t this_position = ftell(f);
  73. #ifdef WA_VALIDATE
  74. printf("[%I64u] ", this_position);
  75. #endif
  76. ebml_node node;
  77. uint64_t bytes_read = read_ebml_node((nsmkv::MKVReader*)f, &node);
  78. if (bytes_read == 0)
  79. return 0;
  80. // benski> checking bytes_read and node.size separately prevents possible integer overflow attack
  81. if (bytes_read > size)
  82. return 0;
  83. total_bytes_read+=bytes_read;
  84. size-=bytes_read;
  85. if (node.size > size)
  86. return 0;
  87. total_bytes_read+=node.size;
  88. size-=node.size;
  89. switch(node.id)
  90. {
  91. case mkv_segment_attachments:
  92. {
  93. printf(" Attachments\n");
  94. ReadAttachment((nsmkv::MKVReader*)f, node.size, attachments);
  95. }
  96. break;
  97. case mkv_metaseek_seekhead:
  98. {
  99. printf(" SeekHead\n");
  100. ReadSeekHead((nsmkv::MKVReader*)f, node.size, seekTable);
  101. }
  102. break;
  103. case mkv_segment_segmentinfo:
  104. {
  105. printf(" SegmentInfo\n");
  106. ReadSegmentInfo((nsmkv::MKVReader*)f, node.size, segment_info);
  107. }
  108. break;
  109. case mkv_segment_tracks:
  110. {
  111. printf(" Tracks\n");
  112. ReadTracks((nsmkv::MKVReader*)f, node.size, tracks);
  113. }
  114. break;
  115. case mkv_segment_cues:
  116. {
  117. printf(" Cues\n");
  118. ReadCues((nsmkv::MKVReader*)f, node.size, cues);
  119. }
  120. break;
  121. case mkv_segment_cluster:
  122. {
  123. printf(" Clusters\n");
  124. nsmkv::Cluster cluster;
  125. ReadCluster((nsmkv::MKVReader*)f, node.size, cluster);
  126. }
  127. break;
  128. case mkv_segment_chapters:
  129. {
  130. printf(" Chapters\n");
  131. }
  132. break;
  133. case mkv_segment_tags:
  134. {
  135. printf(" Tags\n");
  136. nsmkv::ReadTags(f, node.size, tags);
  137. }
  138. break;
  139. default:
  140. ReadGlobal((nsmkv::MKVReader*)f, node.id, node.size);
  141. }
  142. }
  143. return total_bytes_read;
  144. }
  145. int main()
  146. {
  147. // char *file_in = "\\\\o2d2\\ftp\\usr\\nullsoft\\test media\\mkv\\Ratatouille.2007.nHD.720.x264.NhaNc3.mkv";
  148. //char *file_in = "\\\\o2d2\\ftp\\usr\\nullsoft\\test media\\mkv\\cham_mp4v_aac.mkv";
  149. char *file_in = "c:/users/benski/desktop/metadata.mkv";
  150. FILE *f = fopen(file_in, "rb");
  151. if (f == NULL)
  152. {
  153. printf("****Error attempting to open file: %s\n",file_in);
  154. return -1;
  155. }
  156. else
  157. {
  158. printf("Starting Processing of File: %s\n",file_in);
  159. }
  160. ebml_node node;
  161. while (read_ebml_node((nsmkv::MKVReader*)f, &node))
  162. {
  163. switch(node.id)
  164. {
  165. case mkv_header:
  166. if (header.ebml_header_found == false)
  167. {
  168. #ifdef WA_VALIDATE
  169. printf("MKV header found, processing...\n");
  170. #endif
  171. header.ebml_header_found = true;
  172. nsmkv::ReadHeader((nsmkv::MKVReader*)f, node.size, header);
  173. }
  174. else
  175. {
  176. #ifdef WA_VALIDATE
  177. printf("Extra MKV header found, ignoring...\n");
  178. #endif
  179. nsmkv::Header extraHeader;
  180. nsmkv::ReadHeader((nsmkv::MKVReader*)f, node.size, extraHeader);
  181. }
  182. break;
  183. case mkv_segment:
  184. printf("MKV Segment element found, processing\n");
  185. #ifdef WA_VALIDATE
  186. ebml_segment_found = true;
  187. #endif
  188. ReadSegment(f, node.size);
  189. break;
  190. default:
  191. ReadGlobal((nsmkv::MKVReader*)f, node.id, node.size);
  192. }
  193. }
  194. // seekTable.Dump();
  195. fclose(f);
  196. printf("Number of SeekHead elements found: %I32u\n",num_seekhead_elements_found);
  197. printf("Number of Seek elements found: %I32u\n",num_seek_elements_found);
  198. }