WRIFF.CPP 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. //////////////////////////////////////////////////////////////////////////////
  2. //////////////////////////////////////////////////////////////////////////////
  3. //////////////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <windows.h>
  9. #include <mmsystem.h>
  10. #include "avifmt.h"
  11. #include "wriff.h"
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. //////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////
  21. riffFile *riffCreate( LPCTSTR filename )
  22. {
  23. riffFile *result;
  24. if ( (result = (riffFile*)malloc( sizeof(riffFile) )) == NULL )
  25. {
  26. //fprintf( stderr, "Error - riffCreate() - can't allocate memory for riffFile\n" );
  27. return NULL;
  28. }
  29. if ( (result->f = fopen( filename, "wb" )) == NULL )
  30. {
  31. //fprintf( stderr, "Error - riffCreate() - can't create <%s>\n", filename );
  32. free( result );
  33. return NULL;
  34. }
  35. result->stackTop = -1;
  36. return result;
  37. }
  38. //////////////////////////////////////////////////////////////////////////////
  39. //////////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////////
  41. bool riffClose( riffFile *f )
  42. {
  43. while( f->stackTop > -1 )
  44. {
  45. riffCloseSection( f );
  46. }
  47. if ( fclose( f->f ) != 0 )
  48. {
  49. // fprintf( stderr, "Error - riffClose() - can't close RIFF file\n" );
  50. return false;
  51. }
  52. //free( f );
  53. return true;
  54. }
  55. //////////////////////////////////////////////////////////////////////////////
  56. //////////////////////////////////////////////////////////////////////////////
  57. //////////////////////////////////////////////////////////////////////////////
  58. bool riffPadWord( riffFile *f )
  59. {
  60. char dummy = 0;
  61. if ( ftell( f->f ) % 2 == 1 )
  62. {
  63. fwrite( &dummy, 1, 1, f->f );
  64. }
  65. return true;
  66. }
  67. //////////////////////////////////////////////////////////////////////////////
  68. //////////////////////////////////////////////////////////////////////////////
  69. //////////////////////////////////////////////////////////////////////////////
  70. #define MAX_GRAN 2048
  71. bool riffPadJunk( riffFile *f,
  72. long granularity,
  73. long from )
  74. {
  75. long currentSize;
  76. if ( granularity > MAX_GRAN )
  77. {
  78. //fprintf( stderr, "Error - riffPadJunk() - granularity greater than %d\n", MAX_GRAN );
  79. return false;
  80. }
  81. if ( f->stack[ f->stackTop ].type != RIFF_SECTION_LIST )
  82. {
  83. //fprintf( stderr, "Error - riffPadJunk() - current section type is not LIST\n" );
  84. return false;
  85. }
  86. currentSize = ( riffSize( f ) - from ) % granularity;
  87. if ( currentSize != 0 )
  88. {
  89. char buf[MAX_GRAN];
  90. currentSize = ( currentSize + 8 ) % granularity;
  91. memset( buf, 0, granularity );
  92. riffAddChunk( f, "JUNK" );
  93. riffWriteData( f, buf, granularity-currentSize );
  94. riffCloseChunk( f );
  95. }
  96. return true;
  97. }
  98. //////////////////////////////////////////////////////////////////////////////
  99. //////////////////////////////////////////////////////////////////////////////
  100. //////////////////////////////////////////////////////////////////////////////
  101. bool riffAddList( riffFile *f,
  102. str4 type, // "LIST" or "RIFF"
  103. str4 name )
  104. {
  105. if ( f->stackTop == MAX_RIFF_NESTING_LEVEL )
  106. {
  107. //fprintf( stderr, "Error - riffAddList() - maximum nesting level reached\n" );
  108. return false;
  109. }
  110. if ( f->stackTop > -1 )
  111. {
  112. if ( f->stack[ f->stackTop ].type != RIFF_SECTION_LIST )
  113. {
  114. //fprintf( stderr, "Error - riffAddList() - current section type is not LIST\n" );
  115. return false;
  116. }
  117. }
  118. (f->stackTop)++;
  119. f->stack[ f->stackTop ].type = RIFF_SECTION_LIST;
  120. f->stack[ f->stackTop ].sizeOffset = ftell( f->f ) + 4;
  121. f->stack[ f->stackTop ].currentSize = 0;
  122. fwrite( type, 1, 4, f->f ); // "LIST" or "RIFF"
  123. fwrite( "xxxx", 1, 4, f->f ); // reserve room for size
  124. fwrite( name, 1, 4, f->f );
  125. return true;
  126. }
  127. //////////////////////////////////////////////////////////////////////////////
  128. //////////////////////////////////////////////////////////////////////////////
  129. //////////////////////////////////////////////////////////////////////////////
  130. bool riffAddChunk( riffFile *f,
  131. str4 name )
  132. {
  133. if ( f->stackTop == MAX_RIFF_NESTING_LEVEL )
  134. {
  135. //fprintf( stderr, "Error - riffAddChunk() - maximum nesting level reached\n" );
  136. return false;
  137. }
  138. if ( f->stack[ f->stackTop ].type != RIFF_SECTION_LIST )
  139. {
  140. //fprintf( stderr, "Error - riffAddChunk() - current section type is not LIST\n" );
  141. return false;
  142. }
  143. (f->stackTop)++;
  144. f->stack[ f->stackTop ].type = RIFF_SECTION_CHUNK;
  145. f->stack[ f->stackTop ].sizeOffset = ftell( f->f ) + 4;
  146. f->stack[ f->stackTop ].currentSize = 0;
  147. fwrite( name, 1, 4, f->f );
  148. fwrite( "xxxx", 1, 4, f->f ); // reserve room for size
  149. return true;
  150. }
  151. //////////////////////////////////////////////////////////////////////////////
  152. //////////////////////////////////////////////////////////////////////////////
  153. //////////////////////////////////////////////////////////////////////////////
  154. bool riffWriteData( riffFile *f,
  155. void *buf,
  156. long size )
  157. {
  158. if ( (long)fwrite( buf, 1, size, f->f ) != size )
  159. {
  160. //fprintf( stderr, "Error - riffWriteData() - fwrite() didn't return expected result\n" );
  161. return false;
  162. }
  163. f->stack[ f->stackTop ].currentSize += size;
  164. return true;
  165. }
  166. //////////////////////////////////////////////////////////////////////////////
  167. //////////////////////////////////////////////////////////////////////////////
  168. //////////////////////////////////////////////////////////////////////////////
  169. long riffSize( riffFile *f )
  170. {
  171. return ftell( f->f );
  172. }
  173. //////////////////////////////////////////////////////////////////////////////
  174. //////////////////////////////////////////////////////////////////////////////
  175. //////////////////////////////////////////////////////////////////////////////
  176. bool riffCloseSection( riffFile *f )
  177. {
  178. long sizeToAdd;
  179. if ( f->stackTop == -1 )
  180. {
  181. //fprintf( stderr, "Error - riffCloseSection() - stack underflow\n" );
  182. return false;
  183. }
  184. if ( f->stack[ f->stackTop ].type == RIFF_SECTION_LIST )
  185. {
  186. f->stack[ f->stackTop ].currentSize += 4;
  187. }
  188. fseek( f->f, f->stack[ f->stackTop ].sizeOffset, SEEK_SET );
  189. fwrite( &(f->stack[ f->stackTop ].currentSize), 1, 4, f->f );
  190. fseek( f->f, 0, SEEK_END );
  191. switch ( f->stack[ f->stackTop ].type )
  192. {
  193. case RIFF_SECTION_LIST:
  194. sizeToAdd = 12;
  195. break;
  196. case RIFF_SECTION_CHUNK:
  197. sizeToAdd = 8;
  198. break;
  199. default:
  200. //fprintf( stderr, "Error - riffCloseSection() - unexpected section type\n" );
  201. sizeToAdd = 0;
  202. }
  203. if ( f->stack[ f->stackTop ].type == RIFF_SECTION_LIST )
  204. {
  205. f->stack[ f->stackTop ].currentSize -= 4;
  206. }
  207. if ( f->stackTop > 0 )
  208. {
  209. f->stack[ f->stackTop - 1 ].currentSize += ( f->stack[ f->stackTop ].currentSize + sizeToAdd );
  210. }
  211. (f->stackTop)--;
  212. return true;
  213. }
  214. //////////////////////////////////////////////////////////////////////////////
  215. //////////////////////////////////////////////////////////////////////////////
  216. //////////////////////////////////////////////////////////////////////////////
  217. bool riffCloseChunk( riffFile *f )
  218. {
  219. return riffCloseSection( f );
  220. }
  221. //////////////////////////////////////////////////////////////////////////////
  222. //////////////////////////////////////////////////////////////////////////////
  223. //////////////////////////////////////////////////////////////////////////////
  224. bool riffCloseList( riffFile *f )
  225. {
  226. return riffCloseSection( f );
  227. }
  228. //////////////////////////////////////////////////////////////////////////////
  229. //////////////////////////////////////////////////////////////////////////////
  230. //////////////////////////////////////////////////////////////////////////////
  231. /**/