The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1092 lines
30KB

  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE Ogg CONTAINER 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. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
  9. * by the Xiph.Org Foundation http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: packing variable sized words into an octet stream
  13. ********************************************************************/
  14. #ifdef JUCE_MSVC
  15. #pragma warning (disable: 4456 4457 4459)
  16. #endif
  17. /* We're 'LSb' endian; if we write a word but read individual bits,
  18. then we'll read the lsb first */
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <limits.h>
  22. #include "ogg.h"
  23. #define BUFFER_INCREMENT 256
  24. static const unsigned long mask[]=
  25. {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
  26. 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
  27. 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
  28. 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  29. 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
  30. 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
  31. 0x3fffffff,0x7fffffff,0xffffffff };
  32. static const unsigned int mask8B[]=
  33. {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
  34. void oggpack_writeinit(oggpack_buffer *b){
  35. memset(b,0,sizeof(*b));
  36. b->ptr=b->buffer=(unsigned char*)_ogg_malloc(BUFFER_INCREMENT);
  37. b->buffer[0]='\0';
  38. b->storage=BUFFER_INCREMENT;
  39. }
  40. void oggpackB_writeinit(oggpack_buffer *b){
  41. oggpack_writeinit(b);
  42. }
  43. int oggpack_writecheck(oggpack_buffer *b){
  44. if(!b->ptr || !b->storage)return -1;
  45. return 0;
  46. }
  47. int oggpackB_writecheck(oggpack_buffer *b){
  48. return oggpack_writecheck(b);
  49. }
  50. void oggpack_writetrunc(oggpack_buffer *b,long bits){
  51. long bytes=bits>>3;
  52. if(b->ptr){
  53. bits-=bytes*8;
  54. b->ptr=b->buffer+bytes;
  55. b->endbit=bits;
  56. b->endbyte=bytes;
  57. *b->ptr&=mask[bits];
  58. }
  59. }
  60. void oggpackB_writetrunc(oggpack_buffer *b,long bits){
  61. long bytes=bits>>3;
  62. if(b->ptr){
  63. bits-=bytes*8;
  64. b->ptr=b->buffer+bytes;
  65. b->endbit=bits;
  66. b->endbyte=bytes;
  67. *b->ptr&=mask8B[bits];
  68. }
  69. }
  70. /* Takes only up to 32 bits. */
  71. void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
  72. if(bits<0 || bits>32) goto err;
  73. if(b->endbyte>=b->storage-4){
  74. void *ret;
  75. if(!b->ptr)return;
  76. if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
  77. ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
  78. if(!ret) goto err;
  79. b->buffer=(unsigned char*)ret;
  80. b->storage+=BUFFER_INCREMENT;
  81. b->ptr=b->buffer+b->endbyte;
  82. }
  83. value&=mask[bits];
  84. bits+=b->endbit;
  85. b->ptr[0]|=value<<b->endbit;
  86. if(bits>=8){
  87. b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
  88. if(bits>=16){
  89. b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
  90. if(bits>=24){
  91. b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
  92. if(bits>=32){
  93. if(b->endbit)
  94. b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
  95. else
  96. b->ptr[4]=0;
  97. }
  98. }
  99. }
  100. }
  101. b->endbyte+=bits/8;
  102. b->ptr+=bits/8;
  103. b->endbit=bits&7;
  104. return;
  105. err:
  106. oggpack_writeclear(b);
  107. }
  108. /* Takes only up to 32 bits. */
  109. void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
  110. if(bits<0 || bits>32) goto err;
  111. if(b->endbyte>=b->storage-4){
  112. void *ret;
  113. if(!b->ptr)return;
  114. if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
  115. ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
  116. if(!ret) goto err;
  117. b->buffer=(unsigned char*)ret;
  118. b->storage+=BUFFER_INCREMENT;
  119. b->ptr=b->buffer+b->endbyte;
  120. }
  121. value=(value&mask[bits])<<(32-bits);
  122. bits+=b->endbit;
  123. b->ptr[0]|=value>>(24+b->endbit);
  124. if(bits>=8){
  125. b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
  126. if(bits>=16){
  127. b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
  128. if(bits>=24){
  129. b->ptr[3]=(unsigned char)(value>>(b->endbit));
  130. if(bits>=32){
  131. if(b->endbit)
  132. b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
  133. else
  134. b->ptr[4]=0;
  135. }
  136. }
  137. }
  138. }
  139. b->endbyte+=bits/8;
  140. b->ptr+=bits/8;
  141. b->endbit=bits&7;
  142. return;
  143. err:
  144. oggpack_writeclear(b);
  145. }
  146. void oggpack_writealign(oggpack_buffer *b){
  147. int bits=8-b->endbit;
  148. if(bits<8)
  149. oggpack_write(b,0,bits);
  150. }
  151. void oggpackB_writealign(oggpack_buffer *b){
  152. int bits=8-b->endbit;
  153. if(bits<8)
  154. oggpackB_write(b,0,bits);
  155. }
  156. static void oggpack_writecopy_helper(oggpack_buffer *b,
  157. void *source,
  158. long bits,
  159. void (*w)(oggpack_buffer *,
  160. unsigned long,
  161. int),
  162. int msb){
  163. unsigned char *ptr=(unsigned char *)source;
  164. long bytes=bits/8;
  165. long pbytes=(b->endbit+bits)/8;
  166. bits-=bytes*8;
  167. /* expand storage up-front */
  168. if(b->endbyte+pbytes>=b->storage){
  169. void *ret;
  170. if(!b->ptr) goto err;
  171. if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err;
  172. b->storage=b->endbyte+pbytes+BUFFER_INCREMENT;
  173. ret=_ogg_realloc(b->buffer,b->storage);
  174. if(!ret) goto err;
  175. b->buffer=(unsigned char*)ret;
  176. b->ptr=b->buffer+b->endbyte;
  177. }
  178. /* copy whole octets */
  179. if(b->endbit){
  180. int i;
  181. /* unaligned copy. Do it the hard way. */
  182. for(i=0;i<bytes;i++)
  183. w(b,(unsigned long)(ptr[i]),8);
  184. }else{
  185. /* aligned block copy */
  186. memmove(b->ptr,source,bytes);
  187. b->ptr+=bytes;
  188. b->endbyte+=bytes;
  189. *b->ptr=0;
  190. }
  191. /* copy trailing bits */
  192. if(bits){
  193. if(msb)
  194. w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
  195. else
  196. w(b,(unsigned long)(ptr[bytes]),bits);
  197. }
  198. return;
  199. err:
  200. oggpack_writeclear(b);
  201. }
  202. void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
  203. oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
  204. }
  205. void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
  206. oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
  207. }
  208. void oggpack_reset(oggpack_buffer *b){
  209. if(!b->ptr)return;
  210. b->ptr=b->buffer;
  211. b->buffer[0]=0;
  212. b->endbit=b->endbyte=0;
  213. }
  214. void oggpackB_reset(oggpack_buffer *b){
  215. oggpack_reset(b);
  216. }
  217. void oggpack_writeclear(oggpack_buffer *b){
  218. if(b->buffer)_ogg_free(b->buffer);
  219. memset(b,0,sizeof(*b));
  220. }
  221. void oggpackB_writeclear(oggpack_buffer *b){
  222. oggpack_writeclear(b);
  223. }
  224. void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
  225. memset(b,0,sizeof(*b));
  226. b->buffer=b->ptr=buf;
  227. b->storage=bytes;
  228. }
  229. void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
  230. oggpack_readinit(b,buf,bytes);
  231. }
  232. /* Read in bits without advancing the bitptr; bits <= 32 */
  233. long oggpack_look(oggpack_buffer *b,int bits){
  234. unsigned long ret;
  235. unsigned long m;
  236. if(bits<0 || bits>32) return -1;
  237. m=mask[bits];
  238. bits+=b->endbit;
  239. if(b->endbyte >= b->storage-4){
  240. /* not the main path */
  241. if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
  242. /* special case to avoid reading b->ptr[0], which might be past the end of
  243. the buffer; also skips some useless accounting */
  244. else if(!bits)return(0L);
  245. }
  246. ret=b->ptr[0]>>b->endbit;
  247. if(bits>8){
  248. ret|=b->ptr[1]<<(8-b->endbit);
  249. if(bits>16){
  250. ret|=b->ptr[2]<<(16-b->endbit);
  251. if(bits>24){
  252. ret|=b->ptr[3]<<(24-b->endbit);
  253. if(bits>32 && b->endbit)
  254. ret|=b->ptr[4]<<(32-b->endbit);
  255. }
  256. }
  257. }
  258. return(m&ret);
  259. }
  260. /* Read in bits without advancing the bitptr; bits <= 32 */
  261. long oggpackB_look(oggpack_buffer *b,int bits){
  262. unsigned long ret;
  263. int m=32-bits;
  264. if(m<0 || m>32) return -1;
  265. bits+=b->endbit;
  266. if(b->endbyte >= b->storage-4){
  267. /* not the main path */
  268. if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
  269. /* special case to avoid reading b->ptr[0], which might be past the end of
  270. the buffer; also skips some useless accounting */
  271. else if(!bits)return(0L);
  272. }
  273. ret=b->ptr[0]<<(24+b->endbit);
  274. if(bits>8){
  275. ret|=b->ptr[1]<<(16+b->endbit);
  276. if(bits>16){
  277. ret|=b->ptr[2]<<(8+b->endbit);
  278. if(bits>24){
  279. ret|=b->ptr[3]<<(b->endbit);
  280. if(bits>32 && b->endbit)
  281. ret|=b->ptr[4]>>(8-b->endbit);
  282. }
  283. }
  284. }
  285. return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
  286. }
  287. long oggpack_look1(oggpack_buffer *b){
  288. if(b->endbyte>=b->storage)return(-1);
  289. return((b->ptr[0]>>b->endbit)&1);
  290. }
  291. long oggpackB_look1(oggpack_buffer *b){
  292. if(b->endbyte>=b->storage)return(-1);
  293. return((b->ptr[0]>>(7-b->endbit))&1);
  294. }
  295. void oggpack_adv(oggpack_buffer *b,int bits){
  296. bits+=b->endbit;
  297. if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
  298. b->ptr+=bits/8;
  299. b->endbyte+=bits/8;
  300. b->endbit=bits&7;
  301. return;
  302. overflow:
  303. b->ptr=NULL;
  304. b->endbyte=b->storage;
  305. b->endbit=1;
  306. }
  307. void oggpackB_adv(oggpack_buffer *b,int bits){
  308. oggpack_adv(b,bits);
  309. }
  310. void oggpack_adv1(oggpack_buffer *b){
  311. if(++(b->endbit)>7){
  312. b->endbit=0;
  313. b->ptr++;
  314. b->endbyte++;
  315. }
  316. }
  317. void oggpackB_adv1(oggpack_buffer *b){
  318. oggpack_adv1(b);
  319. }
  320. /* bits <= 32 */
  321. long oggpack_read(oggpack_buffer *b,int bits){
  322. long ret;
  323. unsigned long m;
  324. if(bits<0 || bits>32) goto err;
  325. m=mask[bits];
  326. bits+=b->endbit;
  327. if(b->endbyte >= b->storage-4){
  328. /* not the main path */
  329. if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
  330. /* special case to avoid reading b->ptr[0], which might be past the end of
  331. the buffer; also skips some useless accounting */
  332. else if(!bits)return(0L);
  333. }
  334. ret=b->ptr[0]>>b->endbit;
  335. if(bits>8){
  336. ret|=b->ptr[1]<<(8-b->endbit);
  337. if(bits>16){
  338. ret|=b->ptr[2]<<(16-b->endbit);
  339. if(bits>24){
  340. ret|=b->ptr[3]<<(24-b->endbit);
  341. if(bits>32 && b->endbit){
  342. ret|=b->ptr[4]<<(32-b->endbit);
  343. }
  344. }
  345. }
  346. }
  347. ret&=m;
  348. b->ptr+=bits/8;
  349. b->endbyte+=bits/8;
  350. b->endbit=bits&7;
  351. return ret;
  352. overflow:
  353. err:
  354. b->ptr=NULL;
  355. b->endbyte=b->storage;
  356. b->endbit=1;
  357. return -1L;
  358. }
  359. /* bits <= 32 */
  360. long oggpackB_read(oggpack_buffer *b,int bits){
  361. long ret;
  362. long m=32-bits;
  363. if(m<0 || m>32) goto err;
  364. bits+=b->endbit;
  365. if(b->endbyte+4>=b->storage){
  366. /* not the main path */
  367. if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
  368. /* special case to avoid reading b->ptr[0], which might be past the end of
  369. the buffer; also skips some useless accounting */
  370. else if(!bits)return(0L);
  371. }
  372. ret=b->ptr[0]<<(24+b->endbit);
  373. if(bits>8){
  374. ret|=b->ptr[1]<<(16+b->endbit);
  375. if(bits>16){
  376. ret|=b->ptr[2]<<(8+b->endbit);
  377. if(bits>24){
  378. ret|=b->ptr[3]<<(b->endbit);
  379. if(bits>32 && b->endbit)
  380. ret|=b->ptr[4]>>(8-b->endbit);
  381. }
  382. }
  383. }
  384. ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
  385. b->ptr+=bits/8;
  386. b->endbyte+=bits/8;
  387. b->endbit=bits&7;
  388. return ret;
  389. overflow:
  390. err:
  391. b->ptr=NULL;
  392. b->endbyte=b->storage;
  393. b->endbit=1;
  394. return -1L;
  395. }
  396. long oggpack_read1(oggpack_buffer *b){
  397. long ret;
  398. if(b->endbyte >= b->storage) goto overflow;
  399. ret=(b->ptr[0]>>b->endbit)&1;
  400. b->endbit++;
  401. if(b->endbit>7){
  402. b->endbit=0;
  403. b->ptr++;
  404. b->endbyte++;
  405. }
  406. return ret;
  407. overflow:
  408. b->ptr=NULL;
  409. b->endbyte=b->storage;
  410. b->endbit=1;
  411. return -1L;
  412. }
  413. long oggpackB_read1(oggpack_buffer *b){
  414. long ret;
  415. if(b->endbyte >= b->storage) goto overflow;
  416. ret=(b->ptr[0]>>(7-b->endbit))&1;
  417. b->endbit++;
  418. if(b->endbit>7){
  419. b->endbit=0;
  420. b->ptr++;
  421. b->endbyte++;
  422. }
  423. return ret;
  424. overflow:
  425. b->ptr=NULL;
  426. b->endbyte=b->storage;
  427. b->endbit=1;
  428. return -1L;
  429. }
  430. long oggpack_bytes(oggpack_buffer *b){
  431. return(b->endbyte+(b->endbit+7)/8);
  432. }
  433. long oggpack_bits(oggpack_buffer *b){
  434. return(b->endbyte*8+b->endbit);
  435. }
  436. long oggpackB_bytes(oggpack_buffer *b){
  437. return oggpack_bytes(b);
  438. }
  439. long oggpackB_bits(oggpack_buffer *b){
  440. return oggpack_bits(b);
  441. }
  442. unsigned char *oggpack_get_buffer(oggpack_buffer *b){
  443. return(b->buffer);
  444. }
  445. unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
  446. return oggpack_get_buffer(b);
  447. }
  448. /* Self test of the bitwise routines; everything else is based on
  449. them, so they damned well better be solid. */
  450. #ifdef _V_SELFTEST
  451. #include <stdio.h>
  452. static int ilog(unsigned int v){
  453. int ret=0;
  454. while(v){
  455. ret++;
  456. v>>=1;
  457. }
  458. return(ret);
  459. }
  460. oggpack_buffer o;
  461. oggpack_buffer r;
  462. void report(char *in){
  463. fprintf(stderr,"%s",in);
  464. exit(1);
  465. }
  466. void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
  467. long bytes,i;
  468. unsigned char *buffer;
  469. oggpack_reset(&o);
  470. for(i=0;i<vals;i++)
  471. oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
  472. buffer=oggpack_get_buffer(&o);
  473. bytes=oggpack_bytes(&o);
  474. if(bytes!=compsize)report("wrong number of bytes!\n");
  475. for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
  476. for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
  477. report("wrote incorrect value!\n");
  478. }
  479. oggpack_readinit(&r,buffer,bytes);
  480. for(i=0;i<vals;i++){
  481. int tbit=bits?bits:ilog(b[i]);
  482. if(oggpack_look(&r,tbit)==-1)
  483. report("out of data!\n");
  484. if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
  485. report("looked at incorrect value!\n");
  486. if(tbit==1)
  487. if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
  488. report("looked at single bit incorrect value!\n");
  489. if(tbit==1){
  490. if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
  491. report("read incorrect single bit value!\n");
  492. }else{
  493. if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
  494. report("read incorrect value!\n");
  495. }
  496. }
  497. if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
  498. }
  499. void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
  500. long bytes,i;
  501. unsigned char *buffer;
  502. oggpackB_reset(&o);
  503. for(i=0;i<vals;i++)
  504. oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
  505. buffer=oggpackB_get_buffer(&o);
  506. bytes=oggpackB_bytes(&o);
  507. if(bytes!=compsize)report("wrong number of bytes!\n");
  508. for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
  509. for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
  510. report("wrote incorrect value!\n");
  511. }
  512. oggpackB_readinit(&r,buffer,bytes);
  513. for(i=0;i<vals;i++){
  514. int tbit=bits?bits:ilog(b[i]);
  515. if(oggpackB_look(&r,tbit)==-1)
  516. report("out of data!\n");
  517. if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
  518. report("looked at incorrect value!\n");
  519. if(tbit==1)
  520. if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
  521. report("looked at single bit incorrect value!\n");
  522. if(tbit==1){
  523. if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
  524. report("read incorrect single bit value!\n");
  525. }else{
  526. if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
  527. report("read incorrect value!\n");
  528. }
  529. }
  530. if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
  531. }
  532. void copytest(int prefill, int copy){
  533. oggpack_buffer source_write;
  534. oggpack_buffer dest_write;
  535. oggpack_buffer source_read;
  536. oggpack_buffer dest_read;
  537. unsigned char *source;
  538. unsigned char *dest;
  539. long source_bytes,dest_bytes;
  540. int i;
  541. oggpack_writeinit(&source_write);
  542. oggpack_writeinit(&dest_write);
  543. for(i=0;i<(prefill+copy+7)/8;i++)
  544. oggpack_write(&source_write,(i^0x5a)&0xff,8);
  545. source=oggpack_get_buffer(&source_write);
  546. source_bytes=oggpack_bytes(&source_write);
  547. /* prefill */
  548. oggpack_writecopy(&dest_write,source,prefill);
  549. /* check buffers; verify end byte masking */
  550. dest=oggpack_get_buffer(&dest_write);
  551. dest_bytes=oggpack_bytes(&dest_write);
  552. if(dest_bytes!=(prefill+7)/8){
  553. fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
  554. exit(1);
  555. }
  556. oggpack_readinit(&source_read,source,source_bytes);
  557. oggpack_readinit(&dest_read,dest,dest_bytes);
  558. for(i=0;i<prefill;i+=8){
  559. int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
  560. int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
  561. if(s!=d){
  562. fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
  563. exit(1);
  564. }
  565. }
  566. if(prefill<dest_bytes){
  567. if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){
  568. fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
  569. exit(1);
  570. }
  571. }
  572. /* second copy */
  573. oggpack_writecopy(&dest_write,source,copy);
  574. /* check buffers; verify end byte masking */
  575. dest=oggpack_get_buffer(&dest_write);
  576. dest_bytes=oggpack_bytes(&dest_write);
  577. if(dest_bytes!=(copy+prefill+7)/8){
  578. fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
  579. exit(1);
  580. }
  581. oggpack_readinit(&source_read,source,source_bytes);
  582. oggpack_readinit(&dest_read,dest,dest_bytes);
  583. for(i=0;i<prefill;i+=8){
  584. int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
  585. int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
  586. if(s!=d){
  587. fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
  588. exit(1);
  589. }
  590. }
  591. oggpack_readinit(&source_read,source,source_bytes);
  592. for(i=0;i<copy;i+=8){
  593. int s=oggpack_read(&source_read,copy-i<8?copy-i:8);
  594. int d=oggpack_read(&dest_read,copy-i<8?copy-i:8);
  595. if(s!=d){
  596. fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
  597. exit(1);
  598. }
  599. }
  600. if(copy+prefill<dest_bytes){
  601. if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){
  602. fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
  603. exit(1);
  604. }
  605. }
  606. oggpack_writeclear(&source_write);
  607. oggpack_writeclear(&dest_write);
  608. }
  609. void copytestB(int prefill, int copy){
  610. oggpack_buffer source_write;
  611. oggpack_buffer dest_write;
  612. oggpack_buffer source_read;
  613. oggpack_buffer dest_read;
  614. unsigned char *source;
  615. unsigned char *dest;
  616. long source_bytes,dest_bytes;
  617. int i;
  618. oggpackB_writeinit(&source_write);
  619. oggpackB_writeinit(&dest_write);
  620. for(i=0;i<(prefill+copy+7)/8;i++)
  621. oggpackB_write(&source_write,(i^0x5a)&0xff,8);
  622. source=oggpackB_get_buffer(&source_write);
  623. source_bytes=oggpackB_bytes(&source_write);
  624. /* prefill */
  625. oggpackB_writecopy(&dest_write,source,prefill);
  626. /* check buffers; verify end byte masking */
  627. dest=oggpackB_get_buffer(&dest_write);
  628. dest_bytes=oggpackB_bytes(&dest_write);
  629. if(dest_bytes!=(prefill+7)/8){
  630. fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
  631. exit(1);
  632. }
  633. oggpackB_readinit(&source_read,source,source_bytes);
  634. oggpackB_readinit(&dest_read,dest,dest_bytes);
  635. for(i=0;i<prefill;i+=8){
  636. int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
  637. int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
  638. if(s!=d){
  639. fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
  640. exit(1);
  641. }
  642. }
  643. if(prefill<dest_bytes){
  644. if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){
  645. fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
  646. exit(1);
  647. }
  648. }
  649. /* second copy */
  650. oggpackB_writecopy(&dest_write,source,copy);
  651. /* check buffers; verify end byte masking */
  652. dest=oggpackB_get_buffer(&dest_write);
  653. dest_bytes=oggpackB_bytes(&dest_write);
  654. if(dest_bytes!=(copy+prefill+7)/8){
  655. fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
  656. exit(1);
  657. }
  658. oggpackB_readinit(&source_read,source,source_bytes);
  659. oggpackB_readinit(&dest_read,dest,dest_bytes);
  660. for(i=0;i<prefill;i+=8){
  661. int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
  662. int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
  663. if(s!=d){
  664. fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
  665. exit(1);
  666. }
  667. }
  668. oggpackB_readinit(&source_read,source,source_bytes);
  669. for(i=0;i<copy;i+=8){
  670. int s=oggpackB_read(&source_read,copy-i<8?copy-i:8);
  671. int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8);
  672. if(s!=d){
  673. fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
  674. exit(1);
  675. }
  676. }
  677. if(copy+prefill<dest_bytes){
  678. if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){
  679. fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
  680. exit(1);
  681. }
  682. }
  683. oggpackB_writeclear(&source_write);
  684. oggpackB_writeclear(&dest_write);
  685. }
  686. int main(void){
  687. unsigned char *buffer;
  688. long bytes,i,j;
  689. static unsigned long testbuffer1[]=
  690. {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
  691. 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
  692. int test1size=43;
  693. static unsigned long testbuffer2[]=
  694. {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
  695. 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
  696. 85525151,0,12321,1,349528352};
  697. int test2size=21;
  698. static unsigned long testbuffer3[]=
  699. {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
  700. 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
  701. int test3size=56;
  702. static unsigned long large[]=
  703. {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
  704. 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
  705. 85525151,0,12321,1,2146528352};
  706. int onesize=33;
  707. static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
  708. 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
  709. 223,4};
  710. static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
  711. 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
  712. 245,251,128};
  713. int twosize=6;
  714. static int two[6]={61,255,255,251,231,29};
  715. static int twoB[6]={247,63,255,253,249,120};
  716. int threesize=54;
  717. static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
  718. 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
  719. 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
  720. 100,52,4,14,18,86,77,1};
  721. static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
  722. 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
  723. 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
  724. 200,20,254,4,58,106,176,144,0};
  725. int foursize=38;
  726. static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
  727. 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
  728. 28,2,133,0,1};
  729. static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
  730. 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
  731. 129,10,4,32};
  732. int fivesize=45;
  733. static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
  734. 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
  735. 84,75,159,2,1,0,132,192,8,0,0,18,22};
  736. static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
  737. 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
  738. 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
  739. int sixsize=7;
  740. static int six[7]={17,177,170,242,169,19,148};
  741. static int sixB[7]={136,141,85,79,149,200,41};
  742. /* Test read/write together */
  743. /* Later we test against pregenerated bitstreams */
  744. oggpack_writeinit(&o);
  745. fprintf(stderr,"\nSmall preclipped packing (LSb): ");
  746. cliptest(testbuffer1,test1size,0,one,onesize);
  747. fprintf(stderr,"ok.");
  748. fprintf(stderr,"\nNull bit call (LSb): ");
  749. cliptest(testbuffer3,test3size,0,two,twosize);
  750. fprintf(stderr,"ok.");
  751. fprintf(stderr,"\nLarge preclipped packing (LSb): ");
  752. cliptest(testbuffer2,test2size,0,three,threesize);
  753. fprintf(stderr,"ok.");
  754. fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
  755. oggpack_reset(&o);
  756. for(i=0;i<test2size;i++)
  757. oggpack_write(&o,large[i],32);
  758. buffer=oggpack_get_buffer(&o);
  759. bytes=oggpack_bytes(&o);
  760. oggpack_readinit(&r,buffer,bytes);
  761. for(i=0;i<test2size;i++){
  762. if(oggpack_look(&r,32)==-1)report("out of data. failed!");
  763. if(oggpack_look(&r,32)!=large[i]){
  764. fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpack_look(&r,32),large[i],
  765. oggpack_look(&r,32),large[i]);
  766. report("read incorrect value!\n");
  767. }
  768. oggpack_adv(&r,32);
  769. }
  770. if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
  771. fprintf(stderr,"ok.");
  772. fprintf(stderr,"\nSmall unclipped packing (LSb): ");
  773. cliptest(testbuffer1,test1size,7,four,foursize);
  774. fprintf(stderr,"ok.");
  775. fprintf(stderr,"\nLarge unclipped packing (LSb): ");
  776. cliptest(testbuffer2,test2size,17,five,fivesize);
  777. fprintf(stderr,"ok.");
  778. fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
  779. cliptest(testbuffer3,test3size,1,six,sixsize);
  780. fprintf(stderr,"ok.");
  781. fprintf(stderr,"\nTesting read past end (LSb): ");
  782. oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
  783. for(i=0;i<64;i++){
  784. if(oggpack_read(&r,1)!=0){
  785. fprintf(stderr,"failed; got -1 prematurely.\n");
  786. exit(1);
  787. }
  788. }
  789. if(oggpack_look(&r,1)!=-1 ||
  790. oggpack_read(&r,1)!=-1){
  791. fprintf(stderr,"failed; read past end without -1.\n");
  792. exit(1);
  793. }
  794. oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
  795. if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
  796. fprintf(stderr,"failed 2; got -1 prematurely.\n");
  797. exit(1);
  798. }
  799. if(oggpack_look(&r,18)!=0 ||
  800. oggpack_look(&r,18)!=0){
  801. fprintf(stderr,"failed 3; got -1 prematurely.\n");
  802. exit(1);
  803. }
  804. if(oggpack_look(&r,19)!=-1 ||
  805. oggpack_look(&r,19)!=-1){
  806. fprintf(stderr,"failed; read past end without -1.\n");
  807. exit(1);
  808. }
  809. if(oggpack_look(&r,32)!=-1 ||
  810. oggpack_look(&r,32)!=-1){
  811. fprintf(stderr,"failed; read past end without -1.\n");
  812. exit(1);
  813. }
  814. oggpack_writeclear(&o);
  815. fprintf(stderr,"ok.");
  816. /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
  817. fprintf(stderr,"\nTesting aligned writecopies (LSb): ");
  818. for(i=0;i<71;i++)
  819. for(j=0;j<5;j++)
  820. copytest(j*8,i);
  821. for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
  822. for(j=0;j<5;j++)
  823. copytest(j*8,i);
  824. fprintf(stderr,"ok. ");
  825. fprintf(stderr,"\nTesting unaligned writecopies (LSb): ");
  826. for(i=0;i<71;i++)
  827. for(j=1;j<40;j++)
  828. if(j&0x7)
  829. copytest(j,i);
  830. for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
  831. for(j=1;j<40;j++)
  832. if(j&0x7)
  833. copytest(j,i);
  834. fprintf(stderr,"ok. \n");
  835. /********** lazy, cut-n-paste retest with MSb packing ***********/
  836. /* Test read/write together */
  837. /* Later we test against pregenerated bitstreams */
  838. oggpackB_writeinit(&o);
  839. fprintf(stderr,"\nSmall preclipped packing (MSb): ");
  840. cliptestB(testbuffer1,test1size,0,oneB,onesize);
  841. fprintf(stderr,"ok.");
  842. fprintf(stderr,"\nNull bit call (MSb): ");
  843. cliptestB(testbuffer3,test3size,0,twoB,twosize);
  844. fprintf(stderr,"ok.");
  845. fprintf(stderr,"\nLarge preclipped packing (MSb): ");
  846. cliptestB(testbuffer2,test2size,0,threeB,threesize);
  847. fprintf(stderr,"ok.");
  848. fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
  849. oggpackB_reset(&o);
  850. for(i=0;i<test2size;i++)
  851. oggpackB_write(&o,large[i],32);
  852. buffer=oggpackB_get_buffer(&o);
  853. bytes=oggpackB_bytes(&o);
  854. oggpackB_readinit(&r,buffer,bytes);
  855. for(i=0;i<test2size;i++){
  856. if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
  857. if(oggpackB_look(&r,32)!=large[i]){
  858. fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpackB_look(&r,32),large[i],
  859. oggpackB_look(&r,32),large[i]);
  860. report("read incorrect value!\n");
  861. }
  862. oggpackB_adv(&r,32);
  863. }
  864. if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
  865. fprintf(stderr,"ok.");
  866. fprintf(stderr,"\nSmall unclipped packing (MSb): ");
  867. cliptestB(testbuffer1,test1size,7,fourB,foursize);
  868. fprintf(stderr,"ok.");
  869. fprintf(stderr,"\nLarge unclipped packing (MSb): ");
  870. cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
  871. fprintf(stderr,"ok.");
  872. fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
  873. cliptestB(testbuffer3,test3size,1,sixB,sixsize);
  874. fprintf(stderr,"ok.");
  875. fprintf(stderr,"\nTesting read past end (MSb): ");
  876. oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
  877. for(i=0;i<64;i++){
  878. if(oggpackB_read(&r,1)!=0){
  879. fprintf(stderr,"failed; got -1 prematurely.\n");
  880. exit(1);
  881. }
  882. }
  883. if(oggpackB_look(&r,1)!=-1 ||
  884. oggpackB_read(&r,1)!=-1){
  885. fprintf(stderr,"failed; read past end without -1.\n");
  886. exit(1);
  887. }
  888. oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
  889. if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
  890. fprintf(stderr,"failed 2; got -1 prematurely.\n");
  891. exit(1);
  892. }
  893. if(oggpackB_look(&r,18)!=0 ||
  894. oggpackB_look(&r,18)!=0){
  895. fprintf(stderr,"failed 3; got -1 prematurely.\n");
  896. exit(1);
  897. }
  898. if(oggpackB_look(&r,19)!=-1 ||
  899. oggpackB_look(&r,19)!=-1){
  900. fprintf(stderr,"failed; read past end without -1.\n");
  901. exit(1);
  902. }
  903. if(oggpackB_look(&r,32)!=-1 ||
  904. oggpackB_look(&r,32)!=-1){
  905. fprintf(stderr,"failed; read past end without -1.\n");
  906. exit(1);
  907. }
  908. fprintf(stderr,"ok.");
  909. oggpackB_writeclear(&o);
  910. /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
  911. fprintf(stderr,"\nTesting aligned writecopies (MSb): ");
  912. for(i=0;i<71;i++)
  913. for(j=0;j<5;j++)
  914. copytestB(j*8,i);
  915. for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
  916. for(j=0;j<5;j++)
  917. copytestB(j*8,i);
  918. fprintf(stderr,"ok. ");
  919. fprintf(stderr,"\nTesting unaligned writecopies (MSb): ");
  920. for(i=0;i<71;i++)
  921. for(j=1;j<40;j++)
  922. if(j&0x7)
  923. copytestB(j,i);
  924. for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
  925. for(j=1;j<40;j++)
  926. if(j&0x7)
  927. copytestB(j,i);
  928. fprintf(stderr,"ok. \n\n");
  929. return(0);
  930. }
  931. #endif /* _V_SELFTEST */
  932. #undef BUFFER_INCREMENT