bitwise.c 30 KB

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