Leaked source code of windows server 2003
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.

2770 lines
87 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: sc_buf.c,v $
  7. * Revision 1.1.8.4 1996/12/12 20:54:41 Hans_Graves
  8. * Fixed reading of last odd bits.
  9. * [1996/12/12 20:54:05 Hans_Graves]
  10. *
  11. * Revision 1.1.8.3 1996/11/13 16:10:46 Hans_Graves
  12. * Tom's changes to ScBSGetBitsW() and ScBSSeekAlignStopBeforeW().
  13. * [1996/11/13 15:57:34 Hans_Graves]
  14. *
  15. * Revision 1.1.8.2 1996/11/08 21:50:32 Hans_Graves
  16. * Added ScBSGetBitsW(), ScBSSkipBitsW() and sc_BSLoadDataWordW() for AC3.
  17. * [1996/11/08 21:25:52 Hans_Graves]
  18. *
  19. * Revision 1.1.6.4 1996/04/17 16:38:33 Hans_Graves
  20. * Correct some type casting to support 64-bit buffers under NT
  21. * [1996/04/17 16:36:08 Hans_Graves]
  22. *
  23. * Revision 1.1.6.3 1996/04/15 21:08:37 Hans_Graves
  24. * Declare mask and imask as ScBitString_t
  25. * [1996/04/15 21:06:32 Hans_Graves]
  26. *
  27. * Revision 1.1.6.2 1996/04/01 16:23:05 Hans_Graves
  28. * Replace File I/O with ScFile calls
  29. * [1996/04/01 16:22:27 Hans_Graves]
  30. *
  31. * Revision 1.1.4.7 1996/02/19 14:29:25 Bjorn_Engberg
  32. * Enable FILTER_SUPPORT for NT, so Mview can play audio.
  33. * This is only until we port the MPEG Systems code to NT.
  34. * [1996/02/19 14:29:07 Bjorn_Engberg]
  35. *
  36. * Revision 1.1.4.6 1996/02/01 17:15:48 Hans_Graves
  37. * Added FILTER_SUPPORT ifdef; disabled it
  38. * [1996/02/01 17:13:29 Hans_Graves]
  39. *
  40. * Revision 1.1.4.5 1996/01/08 16:41:12 Hans_Graves
  41. * Remove NT compiler warnings, and minor fixes for NT.
  42. * [1996/01/08 14:14:10 Hans_Graves]
  43. *
  44. * Revision 1.1.4.3 1995/11/06 18:47:37 Hans_Graves
  45. * Added support for small buffer: 1-7 bytes
  46. * [1995/11/06 18:46:49 Hans_Graves]
  47. *
  48. * Revision 1.1.4.2 1995/09/13 14:51:34 Hans_Graves
  49. * Added ScBufQueueGetHeadExt() and ScBufQueueAddExt().
  50. * [1995/09/13 14:47:11 Hans_Graves]
  51. *
  52. * Revision 1.1.2.18 1995/08/30 19:37:49 Hans_Graves
  53. * Fixed compiler warning about #else and #elif.
  54. * [1995/08/30 19:36:15 Hans_Graves]
  55. *
  56. * Revision 1.1.2.17 1995/08/29 22:17:04 Hans_Graves
  57. * Disabled debugging statements.
  58. * [1995/08/29 22:11:38 Hans_Graves]
  59. *
  60. * PTT 00938 - MPEG Seg Faulting fixes, Repositioning problem.
  61. * [1995/08/29 22:04:06 Hans_Graves]
  62. *
  63. * Revision 1.1.2.16 1995/08/14 19:40:24 Hans_Graves
  64. * Added Flush routines. Some optimization.
  65. * [1995/08/14 18:40:33 Hans_Graves]
  66. *
  67. * Revision 1.1.2.15 1995/08/02 15:26:58 Hans_Graves
  68. * Fixed writing bitstreams directly to files.
  69. * [1995/08/02 14:11:00 Hans_Graves]
  70. *
  71. * Revision 1.1.2.14 1995/07/28 20:58:37 Hans_Graves
  72. * Initialized all variables in callback messages.
  73. * [1995/07/28 20:52:04 Hans_Graves]
  74. *
  75. * Revision 1.1.2.13 1995/07/28 17:36:04 Hans_Graves
  76. * Fixed END_BUFFER callback from GetNextBuffer()
  77. * [1995/07/28 17:31:30 Hans_Graves]
  78. *
  79. * Revision 1.1.2.12 1995/07/27 18:28:52 Hans_Graves
  80. * Fixed buffer queues in PutData and StoreDataWord.
  81. * [1995/07/27 18:23:30 Hans_Graves]
  82. *
  83. * Revision 1.1.2.11 1995/07/27 12:20:35 Hans_Graves
  84. * Renamed SvErrorClientAbort to SvErrorClientEnd
  85. * [1995/07/27 12:19:12 Hans_Graves]
  86. *
  87. * Revision 1.1.2.10 1995/07/21 17:40:59 Hans_Graves
  88. * Renamed Callback related stuff. Added DataType.
  89. * [1995/07/21 17:26:48 Hans_Graves]
  90. *
  91. * Revision 1.1.2.9 1995/07/17 22:01:27 Hans_Graves
  92. * Added Callback call in PutData().
  93. * [1995/07/17 21:50:49 Hans_Graves]
  94. *
  95. * Revision 1.1.2.8 1995/07/12 19:48:21 Hans_Graves
  96. * Added Queue debugging statements.
  97. * [1995/07/12 19:30:37 Hans_Graves]
  98. *
  99. * Revision 1.1.2.7 1995/07/07 20:11:23 Hans_Graves
  100. * Fixed ScBSGetBit() so it returns the bit.
  101. * [1995/07/07 20:07:27 Hans_Graves]
  102. *
  103. * Revision 1.1.2.6 1995/06/27 13:54:17 Hans_Graves
  104. * Added ScBSCreateFromNet() and STREAM_USE_NET cases.
  105. * [1995/06/27 13:27:38 Hans_Graves]
  106. *
  107. * Revision 1.1.2.5 1995/06/21 18:37:56 Hans_Graves
  108. * Added ScBSPutBytes()
  109. * [1995/06/21 18:37:08 Hans_Graves]
  110. *
  111. * Revision 1.1.2.4 1995/06/15 21:17:55 Hans_Graves
  112. * Changed return type for GetBits() and PeekBits() to ScBitString_t. Added some debug statements.
  113. * [1995/06/15 20:40:54 Hans_Graves]
  114. *
  115. * Revision 1.1.2.3 1995/06/09 18:33:28 Hans_Graves
  116. * Fixed up some problems with Bitstream reads from Buffer Queues
  117. * [1995/06/09 16:27:50 Hans_Graves]
  118. *
  119. * Revision 1.1.2.2 1995/05/31 18:07:25 Hans_Graves
  120. * Inclusion in new SLIB location.
  121. * [1995/05/31 16:05:37 Hans_Graves]
  122. *
  123. * Revision 1.1.2.3 1995/04/17 18:41:05 Hans_Graves
  124. * Added ScBSPutBits, BSStoreWord, and BSPutData functions
  125. * [1995/04/17 18:40:44 Hans_Graves]
  126. *
  127. * Revision 1.1.2.2 1995/04/07 18:22:55 Hans_Graves
  128. * Bitstream and Buffer Queue functions pulled from Sv sources.
  129. * Added functionality and cleaned up API.
  130. * [1995/04/07 18:21:58 Hans_Graves]
  131. *
  132. * $EndLog$
  133. */
  134. /*****************************************************************************
  135. ** Copyright (c) Digital Equipment Corporation, 1995 **
  136. ** **
  137. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  138. ** laws of the United States. **
  139. ** **
  140. ** The software contained on this media is proprietary to and embodies **
  141. ** the confidential technology of Digital Equipment Corporation. **
  142. ** Possession, use, duplication or dissemination of the software and **
  143. ** media is authorized only pursuant to a valid written license from **
  144. ** Digital Equipment Corporation. **
  145. ** **
  146. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  147. ** Government is subject to restrictions as set forth in Subparagraph **
  148. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  149. ******************************************************************************/
  150. /*
  151. ** Bitstream and queue routines
  152. **
  153. ** Note: For reading, "BS->shift" refers to the number of bits stored across
  154. ** BS->OutBuff and BS->InBuff
  155. */
  156. /*
  157. #define _SLIBDEBUG_
  158. */
  159. #include "SC.h"
  160. #include "SC_err.h"
  161. #include <string.h>
  162. #ifdef WIN32
  163. #include <io.h>
  164. #include <windows.h>
  165. #include <assert.h>
  166. #endif
  167. #ifdef _SLIBDEBUG_
  168. #include <stdio.h>
  169. #define _DEBUG_ 0 /* detailed debuging statements */
  170. #define _VERBOSE_ 0 /* show progress */
  171. #define _VERIFY_ 1 /* verify correct operation */
  172. #define _WARN_ 1 /* warnings about strange behavior */
  173. #define _QUEUE_ 0 /* show queue progress */
  174. #define _DUMP_ 0 /* dump out buffer data in hex */
  175. int _debug_getbits=TRUE;
  176. long _debug_start=0, _debug_stop=0;
  177. #endif
  178. #define USE_FAST_SEEK 0 /* fast seeking for words in the bistream */
  179. #define FILTER_SUPPORT 0 /* data filtering callback support */
  180. #ifdef __VMS
  181. #define USE_MASK_TABLES
  182. #else
  183. #define USE_MASK_TABLES
  184. #endif
  185. #ifdef USE_MASK_TABLES
  186. /* to mask the n least significant bits of an integer */
  187. #if SC_BITBUFFSZ == 64
  188. const static ScBitString_t mask[65] =
  189. {
  190. (ScBitString_t)0x0000000000000000,(ScBitString_t)0x0000000000000001,
  191. (ScBitString_t)0x0000000000000003,(ScBitString_t)0x0000000000000007,
  192. (ScBitString_t)0x000000000000000f,(ScBitString_t)0x000000000000001f,
  193. (ScBitString_t)0x000000000000003f,(ScBitString_t)0x000000000000007f,
  194. (ScBitString_t)0x00000000000000ff,(ScBitString_t)0x00000000000001ff,
  195. (ScBitString_t)0x00000000000003ff,(ScBitString_t)0x00000000000007ff,
  196. (ScBitString_t)0x0000000000000fff,(ScBitString_t)0x0000000000001fff,
  197. (ScBitString_t)0x0000000000003fff,(ScBitString_t)0x0000000000007fff,
  198. (ScBitString_t)0x000000000000ffff,(ScBitString_t)0x000000000001ffff,
  199. (ScBitString_t)0x000000000003ffff,(ScBitString_t)0x000000000007ffff,
  200. (ScBitString_t)0x00000000000fffff,(ScBitString_t)0x00000000001fffff,
  201. (ScBitString_t)0x00000000003fffff,(ScBitString_t)0x00000000007fffff,
  202. (ScBitString_t)0x0000000000ffffff,(ScBitString_t)0x0000000001ffffff,
  203. (ScBitString_t)0x0000000003ffffff,(ScBitString_t)0x0000000007ffffff,
  204. (ScBitString_t)0x000000000fffffff,(ScBitString_t)0x000000001fffffff,
  205. (ScBitString_t)0x000000003fffffff,(ScBitString_t)0x000000007fffffff,
  206. (ScBitString_t)0x00000000ffffffff,(ScBitString_t)0x00000001ffffffff,
  207. (ScBitString_t)0x00000003ffffffff,(ScBitString_t)0x00000007ffffffff,
  208. (ScBitString_t)0x0000000fffffffff,(ScBitString_t)0x0000001fffffffff,
  209. (ScBitString_t)0x0000003fffffffff,(ScBitString_t)0x0000007fffffffff,
  210. (ScBitString_t)0x000000ffffffffff,(ScBitString_t)0x000001ffffffffff,
  211. (ScBitString_t)0x000003ffffffffff,(ScBitString_t)0x000007ffffffffff,
  212. (ScBitString_t)0x00000fffffffffff,(ScBitString_t)0x00001fffffffffff,
  213. (ScBitString_t)0x00003fffffffffff,(ScBitString_t)0x00007fffffffffff,
  214. (ScBitString_t)0x0000ffffffffffff,(ScBitString_t)0x0001ffffffffffff,
  215. (ScBitString_t)0x0003ffffffffffff,(ScBitString_t)0x0007ffffffffffff,
  216. (ScBitString_t)0x000fffffffffffff,(ScBitString_t)0x001fffffffffffff,
  217. (ScBitString_t)0x003fffffffffffff,(ScBitString_t)0x007fffffffffffff,
  218. (ScBitString_t)0x00ffffffffffffff,(ScBitString_t)0x01ffffffffffffff,
  219. (ScBitString_t)0x03ffffffffffffff,(ScBitString_t)0x07ffffffffffffff,
  220. (ScBitString_t)0x0fffffffffffffff,(ScBitString_t)0x1fffffffffffffff,
  221. (ScBitString_t)0x3fffffffffffffff,(ScBitString_t)0x7fffffffffffffff,
  222. (ScBitString_t)0xffffffffffffffff
  223. };
  224. /* inverse mask */
  225. const static ScBitString_t imask[65] =
  226. {
  227. (ScBitString_t)0xffffffffffffffff,(ScBitString_t)0xfffffffffffffffe,
  228. (ScBitString_t)0xfffffffffffffffc,(ScBitString_t)0xfffffffffffffff8,
  229. (ScBitString_t)0xfffffffffffffff0,(ScBitString_t)0xffffffffffffffe0,
  230. (ScBitString_t)0xffffffffffffffc0,(ScBitString_t)0xffffffffffffff80,
  231. (ScBitString_t)0xffffffffffffff00,(ScBitString_t)0xfffffffffffffe00,
  232. (ScBitString_t)0xfffffffffffffc00,(ScBitString_t)0xfffffffffffff800,
  233. (ScBitString_t)0xfffffffffffff000,(ScBitString_t)0xffffffffffffe000,
  234. (ScBitString_t)0xffffffffffffc000,(ScBitString_t)0xffffffffffff8000,
  235. (ScBitString_t)0xffffffffffff0000,(ScBitString_t)0xfffffffffffe0000,
  236. (ScBitString_t)0xfffffffffffc0000,(ScBitString_t)0xfffffffffff80000,
  237. (ScBitString_t)0xfffffffffff00000,(ScBitString_t)0xffffffffffe00000,
  238. (ScBitString_t)0xffffffffffc00000,(ScBitString_t)0xffffffffff800000,
  239. (ScBitString_t)0xffffffffff000000,(ScBitString_t)0xfffffffffe000000,
  240. (ScBitString_t)0xfffffffffc000000,(ScBitString_t)0xfffffffff8000000,
  241. (ScBitString_t)0xfffffffff0000000,(ScBitString_t)0xffffffffe0000000,
  242. (ScBitString_t)0xffffffffc0000000,(ScBitString_t)0xffffffff80000000,
  243. (ScBitString_t)0xffffffff00000000,(ScBitString_t)0xfffffffe00000000,
  244. (ScBitString_t)0xfffffffc00000000,(ScBitString_t)0xfffffff800000000,
  245. (ScBitString_t)0xfffffff000000000,(ScBitString_t)0xffffffe000000000,
  246. (ScBitString_t)0xffffffc000000000,(ScBitString_t)0xffffff8000000000,
  247. (ScBitString_t)0xffffff0000000000,(ScBitString_t)0xfffffe0000000000,
  248. (ScBitString_t)0xfffffc0000000000,(ScBitString_t)0xfffff80000000000,
  249. (ScBitString_t)0xfffff00000000000,(ScBitString_t)0xffffe00000000000,
  250. (ScBitString_t)0xffffc00000000000,(ScBitString_t)0xffff800000000000,
  251. (ScBitString_t)0xffff000000000000,(ScBitString_t)0xfffe000000000000,
  252. (ScBitString_t)0xfffc000000000000,(ScBitString_t)0xfff8000000000000,
  253. (ScBitString_t)0xfff0000000000000,(ScBitString_t)0xffe0000000000000,
  254. (ScBitString_t)0xffc0000000000000,(ScBitString_t)0xff80000000000000,
  255. (ScBitString_t)0xff00000000000000,(ScBitString_t)0xfe00000000000000,
  256. (ScBitString_t)0xfc00000000000000,(ScBitString_t)0xf800000000000000,
  257. (ScBitString_t)0xf000000000000000,(ScBitString_t)0xe000000000000000,
  258. (ScBitString_t)0xc000000000000000,(ScBitString_t)0x8000000000000000,
  259. (ScBitString_t)0x0000000000000000
  260. };
  261. #else
  262. const static ScBitString_t mask[33] =
  263. {
  264. 0x00000000,0x00000001,0x00000003,0x00000007,
  265. 0x0000000f,0x0000001f,0x0000003f,0x0000007f,
  266. 0x000000ff,0x000001ff,0x000003ff,0x000007ff,
  267. 0x00000fff,0x00001fff,0x00003fff,0x00007fff,
  268. 0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  269. 0x000fffff,0x001fffff,0x003fffff,0x007fffff,
  270. 0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff,
  271. 0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,
  272. 0xffffffff
  273. };
  274. /* inverse mask */
  275. const static ScBitString_t imask[33] =
  276. {
  277. 0xffffffff,0xfffffffe,0xfffffffc,0xfffffff8,
  278. 0xfffffff0,0xffffffe0,0xffffffc0,0xffffff80,
  279. 0xffffff00,0xfffffe00,0xfffffc00,0xfffff800,
  280. 0xfffff000,0xffffe000,0xffffc000,0xffff8000,
  281. 0xffff0000,0xfffe0000,0xfffc0000,0xfff80000,
  282. 0xfff00000,0xffe00000,0xffc00000,0xff800000,
  283. 0xff000000,0xfe000000,0xfc000000,0xf8000000,
  284. 0xf0000000,0xe0000000,0xc0000000,0x80000000,
  285. 0x00000000
  286. };
  287. #endif
  288. #endif USE_MASK_TABLES
  289. /*********************** Bitstream/Buffer Management *************************/
  290. /*
  291. ** sc_GetNextBuffer()
  292. ** Release current buffer and return info about buffer at head of queue
  293. ** Callbacks are made to 1) release old buffer and 2) ask for more buffers
  294. */
  295. static u_char *sc_GetNextBuffer(ScBitstream_t *BS, int *BufSize)
  296. {
  297. u_char *Data;
  298. int Size;
  299. ScCallbackInfo_t CB;
  300. ScQueue_t *Q=BS->Q;
  301. _SlibDebug(_VERBOSE_, printf("sc_GetNextBuffer(Q=%p)\n", Q) );
  302. if (ScBufQueueGetNum(Q))
  303. {
  304. /*
  305. ** Get pointer to current buffer so we can release it with a callback
  306. */
  307. ScBufQueueGetHead(Q, &Data, &Size);
  308. /*
  309. ** Remove current buffer from head of queue, replacing it with next in line
  310. */
  311. ScBufQueueRemove(Q);
  312. /*
  313. ** Make callback to client to tell that old buffer can be reused.
  314. ** Client may tell us to abort processing. If so, return 0 for BufSize.
  315. */
  316. if (BS->Callback && Data) {
  317. CB.Message = CB_RELEASE_BUFFER;
  318. CB.Data = Data;
  319. CB.DataSize = Size;
  320. CB.DataUsed = Size;
  321. CB.DataType = BS->DataType;
  322. CB.UserData = BS->UserData;
  323. CB.Action = CB_ACTION_CONTINUE;
  324. (*(BS->Callback))(BS->Sch, &CB, NULL);
  325. _SlibDebug(_DEBUG_,
  326. printf("Callback: RELEASE_BUFFER. Addr = 0x%x, Client response = %d\n",
  327. CB.Data, CB.Action) );
  328. if (CB.Action == CB_ACTION_END)
  329. {
  330. *BufSize = 0;
  331. return(NULL);
  332. }
  333. }
  334. }
  335. /*
  336. ** If there's no more buffers in queue, make a callback telling client.
  337. ** Hopefully, client will call ScAddBuffer to add one or more buffers.
  338. ** If not, or if client tells us to abort, return 0 for BufSize.
  339. */
  340. if (!ScBufQueueGetNum(Q)) {
  341. if (BS->Callback) {
  342. CB.Message = CB_END_BUFFERS;
  343. CB.Data = NULL;
  344. CB.DataSize = 0;
  345. CB.DataUsed = 0;
  346. CB.DataType = BS->DataType;
  347. CB.UserData = BS->UserData;
  348. CB.Action = CB_ACTION_CONTINUE;
  349. (*(BS->Callback))(BS->Sch, &CB, NULL);
  350. if (CB.Action == CB_ACTION_END)
  351. {
  352. _SlibDebug(_DEBUG_,
  353. printf("sc_GetNextBuffer() CB.Action = CB_ACTION_END\n") );
  354. *BufSize = 0;
  355. return(NULL);
  356. }
  357. else
  358. _SlibDebug(_VERBOSE_, printf("sc_GetNextBuffer() CB.Action = %d\n",
  359. CB.Action) );
  360. }
  361. if (!ScBufQueueGetNum(Q)) {
  362. _SlibDebug(_DEBUG_, printf("sc_GetNextBuffer() no more buffers\n") );
  363. *BufSize = 0;
  364. return(NULL);
  365. }
  366. }
  367. /*
  368. ** Get & return pointer & size of new current buffer
  369. */
  370. ScBufQueueGetHead(Q, &Data, BufSize);
  371. _SlibDebug(_VERBOSE_, printf("New buffer: Addr = 0x%p, size = %d\n",
  372. Data, *BufSize) );
  373. return(Data);
  374. }
  375. /*************************** Bitstream Management ***************************/
  376. /* Name: ScBSSetFilter
  377. ** Purpose: Set the callback used to filter out data from the Bitstream
  378. */
  379. ScStatus_t ScBSSetFilter(ScBitstream_t *BS,
  380. int (*Callback)(ScBitstream_t *))
  381. {
  382. if (!BS)
  383. return(ScErrorBadPointer);
  384. BS->FilterCallback=Callback;
  385. BS->FilterBit=BS->CurrentBit;
  386. BS->InFilterCallback=FALSE;
  387. return(ScErrorNone);
  388. }
  389. /* Name: ScBSCreate
  390. ** Purpose: Open a Bitstream (no data source)
  391. */
  392. ScStatus_t ScBSCreate(ScBitstream_t **BS)
  393. {
  394. _SlibDebug(_VERBOSE_, printf("ScBSCreate()\n"));
  395. if ((*BS = (ScBitstream_t *)ScAlloc(sizeof(ScBitstream_t))) == NULL)
  396. return(ScErrorMemory);
  397. (*BS)->DataSource = STREAM_USE_NULL;
  398. (*BS)->Mode='r';
  399. (*BS)->Q=NULL;
  400. (*BS)->Callback=NULL;
  401. (*BS)->FilterCallback=NULL;
  402. (*BS)->FilterBit=0;
  403. (*BS)->InFilterCallback=FALSE;
  404. (*BS)->Sch=0;
  405. (*BS)->DataType=0;
  406. (*BS)->UserData=NULL;
  407. (*BS)->FileFd=0;
  408. (*BS)->RdBuf=NULL;
  409. (*BS)->RdBufSize=0;
  410. (*BS)->RdBufAllocated=FALSE;
  411. (*BS)->shift=0;
  412. (*BS)->CurrentBit=0;
  413. (*BS)->buff=0;
  414. (*BS)->buffstart=0;
  415. (*BS)->buffp=0;
  416. (*BS)->bufftop=0;
  417. (*BS)->OutBuff = 0;
  418. (*BS)->InBuff = 0;
  419. (*BS)->Flush = FALSE;
  420. (*BS)->EOI = FALSE;
  421. return(ScErrorNone);
  422. }
  423. /* Name: ScBSCreateFromBuffer
  424. ** Purpose: Open a Bitstream using a single Buffer as a data source
  425. */
  426. ScStatus_t ScBSCreateFromBuffer(ScBitstream_t **BS, u_char *Buffer,
  427. unsigned int BufSize)
  428. {
  429. _SlibDebug(_VERBOSE_, printf("ScBSCreateFromBuffer()\n") );
  430. if (!Buffer)
  431. return(ScErrorBadPointer);
  432. if (BufSize <= 0)
  433. return(ScErrorBadArgument);
  434. if (ScBSCreate(BS) != ScErrorNone)
  435. return (ScErrorMemory);
  436. (*BS)->DataSource = STREAM_USE_BUFFER;
  437. (*BS)->RdBuf=Buffer;
  438. (*BS)->RdBufSize=BufSize;
  439. (*BS)->RdBufAllocated=FALSE;
  440. return(ScErrorNone);
  441. }
  442. /* Name: ScBSCreateFromBufferQueue
  443. ** Purpose: Open a Bitstream using a Buffer Queue as a data source
  444. */
  445. ScStatus_t ScBSCreateFromBufferQueue(ScBitstream_t **BS, ScHandle_t Sch,
  446. int DataType, ScQueue_t *Q,
  447. int (*Callback)(ScHandle_t,ScCallbackInfo_t *, void *),
  448. void *UserData)
  449. {
  450. _SlibDebug(_VERBOSE_, printf("ScBSCreateFromBufferQueue()\n") );
  451. if (!Q)
  452. return(ScErrorNullStruct);
  453. if (!Callback)
  454. return(ScErrorBadPointer);
  455. if (ScBSCreate(BS) != ScErrorNone)
  456. return (ScErrorMemory);
  457. (*BS)->DataSource = STREAM_USE_QUEUE;
  458. (*BS)->Q=Q;
  459. (*BS)->Callback=Callback;
  460. (*BS)->Sch=Sch;
  461. (*BS)->DataType=DataType;
  462. (*BS)->UserData=UserData;
  463. return(ScErrorNone);
  464. }
  465. /* Name: ScBSCreateFromFile
  466. ** Purpose: Open a Bitstream using a file as a data source
  467. */
  468. ScStatus_t ScBSCreateFromFile(ScBitstream_t **BS, int FileFd,
  469. u_char *Buffer, int BufSize)
  470. {
  471. _SlibDebug(_VERBOSE_, printf("ScBSCreateFromFile()\n") );
  472. if (BufSize < SC_BITBUFFSZ)
  473. return(ScErrorBadArgument);
  474. if (FileFd < 0)
  475. return(ScErrorBadArgument);
  476. if (ScBSCreate(BS) != ScErrorNone)
  477. return (ScErrorMemory);
  478. (*BS)->DataSource = STREAM_USE_FILE;
  479. (*BS)->FileFd=FileFd;
  480. if (Buffer==NULL) /* if no buffer provided, alloc one */
  481. {
  482. if (((*BS)->RdBuf=(u_char *)ScAlloc(BufSize))==NULL)
  483. {
  484. ScFree(*BS);
  485. *BS=NULL;
  486. return (ScErrorMemory);
  487. }
  488. (*BS)->RdBufAllocated=TRUE;
  489. }
  490. else
  491. {
  492. (*BS)->RdBufAllocated=FALSE;
  493. (*BS)->RdBuf=Buffer;
  494. }
  495. (*BS)->RdBufSize=BufSize;
  496. return(ScErrorNone);
  497. }
  498. /* Name: ScBSCreateFromNet
  499. ** Purpose: Open a Bitstream using a network socket as a data source
  500. */
  501. ScStatus_t ScBSCreateFromNet(ScBitstream_t **BS, int SocketFd,
  502. u_char *Buffer, int BufSize)
  503. {
  504. ScStatus_t stat;
  505. _SlibDebug(_VERBOSE_, printf("ScBSCreateFromNet(SocketFd=%d)\n", SocketFd) );
  506. stat=ScBSCreateFromFile(BS, SocketFd, Buffer, BufSize);
  507. if (stat!=NoErrors)
  508. return(stat);
  509. (*BS)->DataSource = STREAM_USE_NET;
  510. return(ScErrorNone);
  511. }
  512. /* Name: ScBSCreateFromDevice
  513. ** Purpose: Open a Bitstream using a device (i.e. WAVE_MAPPER)
  514. */
  515. ScStatus_t ScBSCreateFromDevice(ScBitstream_t **BS, int device)
  516. {
  517. _SlibDebug(_VERBOSE_, printf("ScBSCreateFromBuffer()\n") );
  518. if (ScBSCreate(BS) != ScErrorNone)
  519. return (ScErrorMemory);
  520. (*BS)->DataSource = STREAM_USE_DEVICE;
  521. (*BS)->Device=device;
  522. return(ScErrorNone);
  523. }
  524. /*
  525. ** Name: ScBSSeekToPosition()
  526. ** Purpose: Position the bitstream to a specific byte offset.
  527. */
  528. ScStatus_t ScBSSeekToPosition(ScBitstream_t *BS, unsigned long pos)
  529. {
  530. #ifndef SEEK_SET
  531. #define SEEK_SET 0
  532. #endif
  533. ScCallbackInfo_t CB;
  534. _SlibDebug(_VERBOSE_,
  535. printf("ScBSSeekToPosition(pos=%d 0x%X) from %d (0x%X)\n",
  536. pos, pos, ScBSBytePosition(BS),ScBSBytePosition(BS)) );
  537. BS->shift=0;
  538. BS->OutBuff = 0;
  539. BS->InBuff = 0;
  540. switch (BS->DataSource)
  541. {
  542. case STREAM_USE_BUFFER:
  543. if (pos==0)
  544. {
  545. if (BS->Mode=='w')
  546. {
  547. BS->buff = BS->RdBuf;
  548. BS->bufftop = BS->RdBufSize;
  549. }
  550. else
  551. {
  552. BS->buff = 0;
  553. BS->bufftop = 0;
  554. }
  555. BS->buffp=0;
  556. BS->EOI = FALSE;
  557. }
  558. else if (pos>=BS->buffstart && pos<(BS->buffstart+BS->bufftop))
  559. {
  560. BS->buffp=pos-BS->buffstart;
  561. BS->EOI = FALSE;
  562. }
  563. else
  564. BS->EOI = TRUE;
  565. break;
  566. case STREAM_USE_QUEUE:
  567. if (pos>=BS->buffstart && pos<(BS->buffstart+BS->bufftop) && pos>0)
  568. {
  569. BS->buffp=pos-BS->buffstart;
  570. BS->EOI = FALSE;
  571. }
  572. else /* use callback to reset buffer position */
  573. {
  574. int datasize;
  575. /* Release the current buffer */
  576. if (BS->Callback && BS->buff)
  577. {
  578. CB.Message = CB_RELEASE_BUFFER;
  579. CB.Data = BS->buff;
  580. CB.DataSize = BS->bufftop;
  581. CB.DataUsed = BS->buffp;
  582. CB.DataType = BS->DataType;
  583. CB.UserData = BS->UserData;
  584. CB.Action = CB_ACTION_CONTINUE;
  585. (*(BS->Callback))(BS->Sch, &CB, NULL);
  586. _SlibDebug(_VERBOSE_,
  587. printf("Callback: RELEASE_BUFFER. Addr = 0x%x, Client response = %d\n",
  588. CB.Data, CB.Action) );
  589. }
  590. /* Remove all buffers from queue */
  591. while (ScBufQueueGetNum(BS->Q))
  592. {
  593. ScBufQueueGetHead(BS->Q, &CB.Data, &datasize);
  594. ScBufQueueRemove(BS->Q);
  595. if (BS->Callback && CB.Data)
  596. {
  597. CB.Message = CB_RELEASE_BUFFER;
  598. CB.DataSize = datasize;
  599. CB.DataUsed = 0;
  600. CB.DataType = BS->DataType;
  601. CB.UserData = BS->UserData;
  602. CB.Action = CB_ACTION_CONTINUE;
  603. (*(BS->Callback))(BS->Sch, &CB, NULL);
  604. _SlibDebug(_VERBOSE_,
  605. printf("Callback: RELEASE_BUFFER. Addr = 0x%x, Client response = %d\n",
  606. CB.Data, CB.Action) );
  607. }
  608. }
  609. BS->buffp=0;
  610. BS->buff=NULL;
  611. if (CB.Action == CB_ACTION_END)
  612. {
  613. BS->EOI = TRUE;
  614. return(ScErrorClientEnd);
  615. }
  616. else
  617. {
  618. BS->buffstart=pos;
  619. BS->bufftop=0;
  620. BS->EOI = FALSE;
  621. }
  622. }
  623. break;
  624. case STREAM_USE_FILE:
  625. /*
  626. ** check if the desired position is within the
  627. ** current buffer
  628. */
  629. if (pos>=BS->buffstart && pos<(BS->buffstart+BS->bufftop))
  630. {
  631. _SlibDebug(_VERBOSE_, printf("pos is in BS->buff, BS->bufftop=%d\n",
  632. BS->bufftop) );
  633. BS->buffp=pos-BS->buffstart;
  634. BS->EOI = FALSE;
  635. }
  636. /* otherwise seek to it */
  637. else if (ScFileSeek(BS->FileFd, pos)==NoErrors)
  638. {
  639. _SlibDebug(_VERBOSE_, printf("seek(%d 0x%X)\n",pos,pos) );
  640. BS->buffstart=pos;
  641. BS->bufftop=0;
  642. BS->buffp=0;
  643. BS->EOI = FALSE;
  644. }
  645. else
  646. {
  647. _SlibDebug(_VERBOSE_, printf("seek(%d 0x%X) failed\n",pos,pos) );
  648. BS->buffstart=0;
  649. BS->bufftop=0;
  650. BS->buffp=0;
  651. BS->EOI = TRUE;
  652. }
  653. break;
  654. default:
  655. BS->buffstart=0;
  656. BS->EOI = FALSE;
  657. }
  658. BS->CurrentBit=pos<<3;
  659. _SlibDebug(_VERBOSE_, printf("ScBSSeekToPosition() done\n") );
  660. return(ScErrorNone);
  661. }
  662. /*
  663. ** Name: ScBSReset()
  664. ** Purpose: Reset the bitstream back to the beginning.
  665. */
  666. ScStatus_t ScBSReset(ScBitstream_t *BS)
  667. {
  668. _SlibDebug(_VERBOSE_, printf("ScBSReset()\n") );
  669. BS->EOI=FALSE;
  670. if (BS->DataSource==STREAM_USE_FILE)
  671. {
  672. /*
  673. ** for files always empty buffer and seek to beginning
  674. ** just in case the file descriptor was used for something else
  675. */
  676. _SlibDebug(_VERBOSE_, printf("seek(0)\n") );
  677. ScFileSeek(BS->FileFd, 0);
  678. BS->bufftop=0; /* empty buffer */
  679. BS->buffp=0;
  680. BS->buffstart=0;
  681. }
  682. BS->Flush=FALSE;
  683. return(ScBSSeekToPosition(BS, 0));
  684. }
  685. /*
  686. ** Name: sc_BSGetData()
  687. ** Purpose: Set the bitstream pointer to the next buffer in the buffer
  688. ** queue, or if we're using simple file IO, read from the file.
  689. ** Returns: TRUE if data read
  690. ** FALSE if none read (EOI)
  691. */
  692. static u_int sc_BSGetData(ScBitstream_t *BS)
  693. {
  694. int BufSize;
  695. _SlibDebug(_VERBOSE_, printf("sc_BSGetData\n") );
  696. BS->buffp = 0;
  697. if (BS->EOI)
  698. {
  699. BS->buff = NULL;
  700. BS->bufftop = 0;
  701. return(FALSE);
  702. }
  703. switch (BS->DataSource)
  704. {
  705. case STREAM_USE_BUFFER:
  706. if (BS->buff == BS->RdBuf)
  707. {
  708. BS->buff = NULL;
  709. BS->bufftop = 0;
  710. }
  711. else
  712. {
  713. BS->buff = BS->RdBuf;
  714. BS->bufftop = BS->RdBufSize;
  715. }
  716. break;
  717. case STREAM_USE_QUEUE:
  718. BS->buffstart+=BS->bufftop;
  719. _SlibDebug(_VERIFY_ && BS->buffstart<(BS->CurrentBit/8),
  720. printf("ScBSGetData() QUEUE buffstart(%d/0x%X) < currentbyte(%d/0x%X)\n",
  721. BS->buffstart, BS->buffstart, BS->CurrentBit/8, BS->CurrentBit/8);
  722. return(FALSE) );
  723. BS->buff = sc_GetNextBuffer(BS, &BufSize);
  724. BS->bufftop = BufSize;
  725. break;
  726. case STREAM_USE_NET:
  727. case STREAM_USE_NET_UDP:
  728. case STREAM_USE_FILE:
  729. BS->buff = BS->RdBuf;
  730. BS->buffstart+=BS->bufftop;
  731. _SlibDebug(_VERIFY_ && BS->buffstart<(BS->CurrentBit/8),
  732. printf("ScBSGetData() FILE buffstart(%d/0x%X) < currentbyte(%d/0x%X)\n",
  733. BS->buffstart, BS->buffstart, BS->CurrentBit/8, BS->CurrentBit/8);
  734. return(FALSE) );
  735. BufSize = ScFileRead(BS->FileFd, BS->buff, BS->RdBufSize);
  736. if (BufSize<0)
  737. BS->bufftop = 0;
  738. else
  739. BS->bufftop = BufSize;
  740. _SlibDebug(_VERBOSE_,
  741. printf("%d bytes read from fd %d: BytePosition=%d (0x%X) RdBufSize=%d\n buffstart=%d (0x%X)",
  742. BS->bufftop,BS->FileFd,ScBSBytePosition(BS),
  743. ScBSBytePosition(BS),BS->RdBufSize,
  744. BS->buffstart,BS->buffstart) );
  745. break;
  746. case STREAM_USE_NULL:
  747. BS->buff = NULL;
  748. BS->bufftop =10240;
  749. BS->buffstart+=10240;
  750. break;
  751. }
  752. _SlibDebug(_DUMP_ && BS->buff && BS->bufftop &&
  753. BS->DataSource==STREAM_USE_QUEUE,
  754. printf("sc_BSGetData():\n");
  755. ScDumpChar(BS->buff, BS->bufftop, BS->buffstart);
  756. if (BS->bufftop>0x8000) /* show end of buffer */
  757. ScDumpChar(BS->buff+BS->bufftop-0x500, 0x500,
  758. BS->buffstart+BS->bufftop-0x500) );
  759. if (BS->buff && BS->bufftop)
  760. return(TRUE);
  761. else
  762. return(FALSE);
  763. }
  764. /*
  765. ** Name: sc_BSPutData()
  766. ** Purpose: Set the bitstream pointer to the next buffer in the buffer
  767. ** queue, or if we're using simple file IO, read from the file.
  768. */
  769. static ScStatus_t sc_BSPutData(ScBitstream_t *BS)
  770. {
  771. ScStatus_t stat;
  772. int written;
  773. _SlibDebug(_VERBOSE_, printf("sc_BSPutData\n") );
  774. BS->Flush=FALSE;
  775. switch (BS->DataSource)
  776. {
  777. case STREAM_USE_BUFFER:
  778. stat=ScErrorEndBitstream;
  779. break;
  780. case STREAM_USE_QUEUE:
  781. if (BS->Callback)
  782. {
  783. ScCallbackInfo_t CB;
  784. if (BS->buff)
  785. {
  786. _SlibDebug(_VERBOSE_, printf("Callback CB_RELEASE_BUFFERS\n"));
  787. CB.Message = CB_RELEASE_BUFFER;
  788. CB.Data = BS->buff;
  789. CB.DataSize = BS->buffp;
  790. CB.DataUsed = CB.DataSize;
  791. CB.DataType = BS->DataType;
  792. CB.UserData = BS->UserData;
  793. CB.Action = CB_ACTION_CONTINUE;
  794. (*BS->Callback)(BS->Sch, &CB, NULL);
  795. BS->buff = 0;
  796. BS->bufftop = 0;
  797. BS->buffp=0;
  798. if (CB.Action == CB_ACTION_END)
  799. return(ScErrorClientEnd);
  800. }
  801. else
  802. BS->bufftop = 0;
  803. if (!BS->Q)
  804. stat=ScErrorEndBitstream;
  805. else
  806. {
  807. _SlibDebug(_DEBUG_, printf("Callback CB_END_BUFFERS\n") );
  808. CB.Message = CB_END_BUFFERS;
  809. CB.Data = NULL;
  810. CB.DataSize = 0;
  811. CB.DataUsed = 0;
  812. CB.DataType = BS->DataType;
  813. CB.UserData = BS->UserData;
  814. CB.Action = CB_ACTION_CONTINUE;
  815. (*BS->Callback)(BS->Sch, &CB, NULL);
  816. if (CB.Action != CB_ACTION_CONTINUE ||
  817. ScBufQueueGetNum(BS->Q)==0)
  818. stat=ScErrorEndBitstream;
  819. else
  820. {
  821. int size;
  822. ScBufQueueGetHead(BS->Q, &BS->buff, &size);
  823. BS->bufftop=size;
  824. ScBufQueueRemove(BS->Q);
  825. if (!BS->buff || size<=0)
  826. stat=ScErrorEndBitstream;
  827. else
  828. stat=NoErrors;
  829. }
  830. }
  831. }
  832. else
  833. {
  834. BS->buff = 0;
  835. BS->bufftop = 0;
  836. }
  837. BS->buffp=0;
  838. break;
  839. case STREAM_USE_FILE:
  840. case STREAM_USE_NET:
  841. case STREAM_USE_NET_UDP:
  842. if (BS->buffp>0)
  843. {
  844. written=ScFileWrite(BS->FileFd, BS->buff, BS->buffp);
  845. _SlibDebug(_VERBOSE_,
  846. printf("%d bytes written to fd %d (buffer=%d bytes)\n",
  847. written, BS->FileFd, BS->buffp) );
  848. _SlibDebug(_DUMP_,
  849. printf("sc_BSPutData():\n");
  850. ScDumpChar(BS->buff, BS->buffp, BS->buffstart));
  851. if (written<(int)BS->buffp)
  852. {
  853. BS->buff = BS->RdBuf;
  854. BS->buffp=0;
  855. BS->bufftop=0;
  856. stat=ScErrorEndBitstream;
  857. }
  858. else
  859. {
  860. BS->buff = BS->RdBuf;
  861. BS->buffp=0;
  862. BS->bufftop = BS->RdBufSize;
  863. stat=NoErrors;
  864. }
  865. }
  866. break;
  867. case STREAM_USE_NULL:
  868. BS->buff = NULL;
  869. BS->buffp=0;
  870. BS->bufftop = 10240;
  871. break;
  872. default:
  873. stat=ScErrorEndBitstream;
  874. }
  875. return(stat);
  876. }
  877. /*
  878. ** Name: sc_BSLoadDataWord
  879. ** Purpose: Copy a longword from the bitstream buffer into local working buffer
  880. */
  881. ScStatus_t sc_BSLoadDataWord(ScBitstream_t *BS)
  882. {
  883. int i, bcount;
  884. register ScBitBuff_t InBuff;
  885. const int shift=BS->shift;
  886. const u_int buffp=BS->buffp;
  887. register u_char *buff=BS->buff+buffp;
  888. _SlibDebug(_DEBUG_,
  889. printf("sc_BSLoadDataWord(BS=%p) shift=%d bit=%d byte=%d (0x%X)\n",
  890. BS, BS->shift, BS->CurrentBit, BS->CurrentBit/8, BS->CurrentBit/8) );
  891. /* If we have plenty of room, use fast path */
  892. if (BS->bufftop - buffp >= SC_BITBUFFSZ/8)
  893. {
  894. #if SC_BITBUFFSZ == 64
  895. InBuff=(ScBitBuff_t)buff[7];
  896. InBuff|=(ScBitBuff_t)buff[6]<<8;
  897. InBuff|=(ScBitBuff_t)buff[5]<<16;
  898. InBuff|=(ScBitBuff_t)buff[4]<<24;
  899. InBuff|=(ScBitBuff_t)buff[3]<<32;
  900. InBuff|=(ScBitBuff_t)buff[2]<<40;
  901. InBuff|=(ScBitBuff_t)buff[1]<<48;
  902. InBuff|=(ScBitBuff_t)buff[0]<<56;
  903. _SlibDebug(_VERIFY_ && (u_char)((InBuff>>24)&0xFF)!=buff[4],
  904. printf("sc_BSLoadDataWord(BS=%p) InBuff>>24(%X)!=buff[4](%X)\n",
  905. BS, (InBuff>>24)&0xFF, buff[4]) );
  906. _SlibDebug(_VERIFY_ && (u_char)(InBuff>>56)!=buff[0],
  907. printf("sc_BSLoadDataWord(BS=%p) InBuff>>56(%X)!=buff[0](%X)\n",
  908. BS, (InBuff>>56), buff[0]) );
  909. #elif SC_BITBUFFSZ == 32
  910. InBuff=(ScBitBuff_t)buff[3];
  911. InBuff|=(ScBitBuff_t)buff[2]<<8;
  912. InBuff|=(ScBitBuff_t)buff[1]<<16;
  913. InBuff|=(ScBitBuff_t)buff[0]<<24;
  914. _SlibDebug(_VERIFY_ && (InBuff>>24)!=buff[0],
  915. printf("sc_BSLoadDataWord(BS=%p) InBuff>>24(%X)!=buff[0](%X)\n",
  916. BS, InBuff>>24, buff[0]) );
  917. #else
  918. printf("SC_BITBUFFSZ <> 32\n");
  919. for (InBuff=0, i = SC_BITBUFFSZ/8; i > 0; i--, buff++)
  920. InBuff = (InBuff << 8) | (ScBitBuff_t)*buff;
  921. #endif
  922. BS->buffp=buffp+SC_BITBUFFSZ/8;
  923. bcount = SC_BITBUFFSZ/8;
  924. }
  925. /* Near or at end of buffer */
  926. else
  927. {
  928. /* Get remaining bytes */
  929. bcount = BS->bufftop - buffp;
  930. for (InBuff=0, i = bcount; i > 0; i--, buff++)
  931. InBuff = (InBuff << 8) | (ScBitBuff_t)*buff;
  932. BS->buffp=buffp+bcount;
  933. /* Attempt to get more data - if successful, shuffle rest of bytes */
  934. if (sc_BSGetData(BS))
  935. {
  936. BS->EOI = FALSE;
  937. i = (SC_BITBUFFSZ/8) - bcount;
  938. if (i>(int)BS->bufftop)
  939. {
  940. _SlibDebug(_WARN_,
  941. printf("ScBSLoadDataWord() Got small buffer. Expected %d bytes got %d bytes.\n",
  942. i, BS->bufftop) );
  943. i=BS->bufftop;
  944. bcount+=i;
  945. while (i > 0)
  946. {
  947. InBuff = (InBuff << 8) | (ScBitBuff_t)BS->buff[BS->buffp++];
  948. i--;
  949. }
  950. InBuff<<=SC_BITBUFFSZ-(bcount*8);
  951. }
  952. else
  953. {
  954. bcount = SC_BITBUFFSZ/8;
  955. while (i > 0)
  956. {
  957. InBuff = (InBuff << 8) | (ScBitBuff_t)BS->buff[BS->buffp++];
  958. i--;
  959. }
  960. }
  961. }
  962. else if (bcount==0)
  963. BS->EOI = TRUE;
  964. else
  965. InBuff <<= SC_BITBUFFSZ-bcount*8;
  966. }
  967. _SlibDebug(_VERIFY_ && BS->shift>SC_BITBUFFSZ,
  968. printf("sc_BSLoadDataWord(BS=%p) shift (%d) > SC_BITBUFFSZ (%d)\n",
  969. BS, BS->shift, SC_BITBUFFSZ) );
  970. if (!shift) /* OutBuff is empty */
  971. {
  972. BS->OutBuff = InBuff;
  973. BS->InBuff = 0;
  974. BS->shift=bcount*8;
  975. }
  976. else if (shift<SC_BITBUFFSZ)
  977. {
  978. BS->OutBuff |= InBuff >> shift;
  979. BS->InBuff = InBuff << (SC_BITBUFFSZ-shift);
  980. BS->shift=shift+(bcount*8);
  981. }
  982. else /* shift == SC_BITBUFFSZ - OutBuff is full */
  983. {
  984. BS->InBuff = InBuff;
  985. BS->shift=bcount*8;
  986. }
  987. _SlibDebug(_VERIFY_,
  988. if (BS->shift<SC_BITBUFFSZ)
  989. {
  990. if (BS->OutBuff & (SC_BITBUFFMASK>>BS->shift))
  991. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits to right of OutBuff: shift=%d\n", BS, BS->shift);
  992. else if (BS->InBuff)
  993. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits in InBuff: shift=%d\n",
  994. BS, BS->shift);
  995. }
  996. else if (BS->InBuff&(SC_BITBUFFMASK>>(BS->shift-SC_BITBUFFSZ)))
  997. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits to right of InBuff: shift=%d\n", BS->shift);
  998. if ((BS->CurrentBit%8) && !(BS->shift%8))
  999. printf("sc_BSLoadDataWord(BS=%p) CurrentBit (%d) and shift (%d) not aligned.\n", BS, BS->CurrentBit, BS->shift);
  1000. if ((BS->CurrentBit+BS->shift)/8!=BS->buffstart+BS->buffp)
  1001. {
  1002. printf("sc_BSLoadDataWord(BS=%p) (CurrentBit+shift)/8 (%d) <> buffstart+buffp (%d)\n", BS, (BS->CurrentBit+BS->shift)/8, BS->buffstart+BS->buffp);
  1003. BS->EOI = TRUE;
  1004. return(ScErrorEndBitstream);
  1005. }
  1006. );
  1007. return(NoErrors);
  1008. }
  1009. /*
  1010. ** Name: sc_BSLoadDataWordW
  1011. ** Purpose: Copy a longword from the bitstream buffer into local working buffer
  1012. ** ** This version operates a word at a time for Dolby **
  1013. */
  1014. ScStatus_t sc_BSLoadDataWordW(ScBitstream_t *BS)
  1015. {
  1016. int i, wcount;
  1017. register ScBitBuff_t InBuff;
  1018. const int shift=BS->shift;
  1019. const u_int buffp=BS->buffp;
  1020. register u_short *buff=(u_short *)BS->buff+(buffp/2);
  1021. _SlibDebug(_DEBUG_,
  1022. printf("sc_BSLoadDataWord(BS=%p) shift=%d bit=%d byte=%d (0x%X)\n",
  1023. BS, BS->shift, BS->CurrentBit, BS->CurrentBit/8, BS->CurrentBit/8) );
  1024. /* If we have plenty of room, use fast path */
  1025. if (BS->bufftop - buffp >= SC_BITBUFFSZ/8)
  1026. {
  1027. #if SC_BITBUFFSZ == 64
  1028. InBuff=(ScBitBuff_t)buff[3];
  1029. InBuff|=(ScBitBuff_t)buff[2]<<16;
  1030. InBuff|=(ScBitBuff_t)buff[1]<<32;
  1031. InBuff|=(ScBitBuff_t)buff[0]<<48;
  1032. _SlibDebug(_VERIFY_ && (InBuff>>24)&0xFFFF!=buff[4],
  1033. printf("sc_BSLoadDataWord(BS=%p) InBuff>>24(%X)!=buff[0](%X)\n",
  1034. BS, (InBuff>>24)&0xFF, buff[4]) );
  1035. _SlibDebug(_VERIFY_ && (InBuff>>56)!=buff[0],
  1036. printf("sc_BSLoadDataWord(BS=%p) InBuff>>56(%X)!=buff[0](%X)\n",
  1037. BS, (InBuff>>56), buff[0]) );
  1038. #elif SC_BITBUFFSZ == 32
  1039. InBuff=(ScBitBuff_t)buff[1];
  1040. InBuff|=(ScBitBuff_t)buff[0]<<16;
  1041. _SlibDebug(_VERIFY_ && (InBuff>>16)!=buff[0],
  1042. printf("sc_BSLoadDataWord(BS=%p) InBuff>>24(%X)!=buff[0](%X)\n",
  1043. BS, InBuff>>24, buff[0]) );
  1044. #else
  1045. printf("SC_BITBUFFSZ <> 32\n");
  1046. for (InBuff=0, i = SC_BITBUFFSZ/16; i > 0; i--, buff++)
  1047. InBuff = (InBuff << 16) | (ScBitBuff_t)*buff;
  1048. #endif
  1049. BS->buffp=buffp+SC_BITBUFFSZ/8;
  1050. wcount = SC_BITBUFFSZ/16;
  1051. }
  1052. /* Near or at end of buffer */
  1053. else
  1054. {
  1055. /* Get remaining bytes */
  1056. wcount = (BS->bufftop - buffp)/2;
  1057. for (InBuff=0, i = wcount; i > 0; i--, buff++)
  1058. InBuff = (InBuff << 16) | (ScBitBuff_t)*buff;
  1059. BS->buffp=buffp+wcount*2;
  1060. /* Attempt to get more data - if successful, shuffle rest of bytes */
  1061. if (sc_BSGetData(BS))
  1062. {
  1063. int wordp=BS->buffp/2; /* Pointer is stored as a byte count, but we need words */
  1064. BS->EOI = FALSE;
  1065. i = (SC_BITBUFFSZ/16) - wcount;
  1066. if (i>(int)BS->bufftop)
  1067. {
  1068. _SlibDebug(_WARN_,
  1069. printf("ScBSLoadDataWord() Got small buffer. Expected %d words got %d words.\n",
  1070. i, BS->bufftop) );
  1071. i=BS->bufftop;
  1072. wcount+=i;
  1073. while (i >= 0)
  1074. {
  1075. InBuff = (InBuff << 16) | (ScBitBuff_t)((u_short *)BS->buff)[wordp++];
  1076. i--;
  1077. }
  1078. InBuff<<=SC_BITBUFFSZ-(wcount*16);
  1079. }
  1080. else
  1081. {
  1082. wcount = SC_BITBUFFSZ/16;
  1083. while (i > 0)
  1084. {
  1085. InBuff = (InBuff << 16) | (ScBitBuff_t)((u_short *)BS->buff)[wordp++];
  1086. i--;
  1087. }
  1088. }
  1089. BS->buffp=wordp*2;
  1090. }
  1091. else
  1092. BS->EOI = TRUE;
  1093. }
  1094. _SlibDebug(_VERIFY_ && BS->shift>SC_BITBUFFSZ,
  1095. printf("sc_BSLoadDataWordW(BS=%p) shift (%d) > SC_BITBUFFSZ (%d)\n",
  1096. BS, BS->shift, SC_BITBUFFSZ) );
  1097. if (!shift) /* OutBuff is empty */
  1098. {
  1099. BS->OutBuff = InBuff;
  1100. BS->InBuff = 0;
  1101. BS->shift=wcount*16;
  1102. }
  1103. else if (shift<SC_BITBUFFSZ)
  1104. {
  1105. BS->OutBuff |= InBuff >> shift;
  1106. BS->InBuff = InBuff << (SC_BITBUFFSZ-shift);
  1107. BS->shift=shift+(wcount*16);
  1108. }
  1109. else /* shift == SC_BITBUFFSZ - OutBuff is full */
  1110. {
  1111. BS->InBuff = InBuff;
  1112. BS->shift=wcount*16;
  1113. }
  1114. _SlibDebug(_VERIFY_,
  1115. if (BS->shift<SC_BITBUFFSZ)
  1116. {
  1117. if (BS->OutBuff & (SC_BITBUFFMASK>>BS->shift))
  1118. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits to right of OutBuff: shift=%d\n", BS, BS->shift);
  1119. else if (BS->InBuff)
  1120. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits in InBuff: shift=%d\n",
  1121. BS, BS->shift);
  1122. }
  1123. else if (BS->InBuff&(SC_BITBUFFMASK>>(BS->shift-SC_BITBUFFSZ)))
  1124. printf("sc_BSLoadDataWord(BS=%p) Non-zero bits to right of InBuff: shift=%d\n", BS->shift);
  1125. if ((BS->CurrentBit%8) && !(BS->shift%8))
  1126. printf("sc_BSLoadDataWord(BS=%p) CurrentBit (%d) and shift (%d) not aligned.\n", BS, BS->CurrentBit, BS->shift);
  1127. if ((BS->CurrentBit+BS->shift)/8!=BS->buffstart+BS->buffp)
  1128. {
  1129. printf("sc_BSLoadDataWord(BS=%p) (CurrentBit+shift)/8 (%d) <> buffstart+buffp (%d)\n", BS, (BS->CurrentBit+BS->shift)/8, BS->buffstart+BS->buffp);
  1130. BS->EOI = TRUE;
  1131. return(ScErrorEndBitstream);
  1132. }
  1133. );
  1134. return(NoErrors);
  1135. }
  1136. /*
  1137. ** Name: sc_BSStoreDataWord
  1138. ** Purpose: Copy a longword from the local working buffer to the
  1139. ** bitstream buffer
  1140. */
  1141. ScStatus_t sc_BSStoreDataWord(ScBitstream_t *BS, ScBitBuff_t OutBuff)
  1142. {
  1143. int i, bcount, shift=SC_BITBUFFSZ-8;
  1144. ScStatus_t stat=NoErrors;
  1145. _SlibDebug(_VERBOSE_,
  1146. printf("sc_BSStoreDataWord(0x%lX 0x%lX) buffp=%d\n",
  1147. OutBuff>>32, OutBuff&0xFFFFFFFF, BS->buffp) );
  1148. if (BS->EOI)
  1149. return(ScErrorEndBitstream);
  1150. if (!BS->buff || BS->bufftop<=0)
  1151. {
  1152. if (BS->DataSource==STREAM_USE_QUEUE)
  1153. {
  1154. if (BS->Callback && BS->Q)
  1155. {
  1156. ScCallbackInfo_t CB;
  1157. _SlibDebug(_DEBUG_, printf("Callback CB_END_BUFFERS\n") );
  1158. CB.Message = CB_END_BUFFERS;
  1159. CB.Data = NULL;
  1160. CB.DataSize = 0;
  1161. CB.DataUsed = 0;
  1162. CB.DataType = BS->DataType;
  1163. CB.UserData = BS->UserData;
  1164. CB.Action = CB_ACTION_CONTINUE;
  1165. (*BS->Callback)(BS->Sch, &CB, NULL);
  1166. if (CB.Action != CB_ACTION_CONTINUE || ScBufQueueGetNum(BS->Q)==0)
  1167. {
  1168. BS->EOI = TRUE;
  1169. return(ScErrorEndBitstream);
  1170. }
  1171. else
  1172. {
  1173. int size;
  1174. ScBufQueueGetHead(BS->Q, &BS->buff, &size);
  1175. BS->bufftop=size;
  1176. ScBufQueueRemove(BS->Q);
  1177. if (!BS->buff || size<=0)
  1178. {
  1179. BS->EOI = TRUE;
  1180. return(ScErrorEndBitstream);
  1181. }
  1182. BS->EOI = FALSE;
  1183. }
  1184. }
  1185. else
  1186. {
  1187. BS->EOI = TRUE;
  1188. return(ScErrorEndBitstream);
  1189. }
  1190. }
  1191. else if (BS->RdBuf)
  1192. {
  1193. BS->buff=BS->RdBuf;
  1194. BS->bufftop=BS->RdBufSize;
  1195. }
  1196. }
  1197. bcount = BS->bufftop - BS->buffp;
  1198. /* If we have plenty of room, use fast path */
  1199. if (bcount >= SC_BITBUFFSZ>>3) {
  1200. u_char *buff=BS->buff+BS->buffp;
  1201. #if SC_BITBUFFSZ == 64
  1202. buff[0]=(unsigned char)(OutBuff>>56);
  1203. buff[1]=(unsigned char)(OutBuff>>48);
  1204. buff[2]=(unsigned char)(OutBuff>>40);
  1205. buff[3]=(unsigned char)(OutBuff>>32);
  1206. buff[4]=(unsigned char)(OutBuff>>24);
  1207. buff[5]=(unsigned char)(OutBuff>>16);
  1208. buff[6]=(unsigned char)(OutBuff>>8);
  1209. buff[7]=(unsigned char)OutBuff;
  1210. #elif SC_BITBUFFSZ == 32
  1211. buff[0]=(unsigned char)(OutBuff>>24);
  1212. buff[1]=(unsigned char)(OutBuff>>16);
  1213. buff[2]=(unsigned char)(OutBuff>>8);
  1214. buff[3]=(unsigned char)OutBuff;
  1215. #else
  1216. for (bcount = SC_BITBUFFSZ/8; bcount; shift-=8, bcount--, buff++)
  1217. *buff=(Buff>>shift)&0xFF;
  1218. #endif
  1219. BS->buffp+=SC_BITBUFFSZ/8;
  1220. if (BS->Flush && sc_BSPutData(BS)!=NoErrors)
  1221. BS->EOI=TRUE;
  1222. }
  1223. else /* Near end of buffer */
  1224. {
  1225. /* Fill up current buffer */
  1226. for (i=0; i<bcount; shift-=8, i++)
  1227. BS->buff[BS->buffp++]=(unsigned char)(OutBuff>>shift);
  1228. /* Commit the buffer */
  1229. if ((stat=sc_BSPutData(BS))==NoErrors)
  1230. {
  1231. /* Successful, so copy rest of bytes to new buffer */
  1232. bcount = (SC_BITBUFFSZ>>3) - bcount;
  1233. for (i=0; i<bcount; shift-=8, i++)
  1234. BS->buff[BS->buffp++]=(unsigned char)(OutBuff>>shift);
  1235. }
  1236. else
  1237. BS->EOI=TRUE;
  1238. }
  1239. BS->Mode='w';
  1240. return(stat);
  1241. }
  1242. /*
  1243. ** ScBSSkipBits()
  1244. ** Skip a certain number of bits
  1245. **
  1246. */
  1247. ScStatus_t ScBSSkipBits(ScBitstream_t *BS, u_int length)
  1248. {
  1249. register u_int skipbytes, skipbits;
  1250. register int shift;
  1251. _SlibDebug(_DEBUG_, printf("ScBSSkipBits(%d): Byte offset = 0x%X\n",length,
  1252. ScBSBytePosition(BS)) );
  1253. _SlibDebug(_WARN_ && length==0,
  1254. printf("ScBSSkipBits(%d) length==0\n", length) );
  1255. _SlibDebug(_WARN_ && length>SC_BITBUFFSZ,
  1256. printf("ScBSSkipBits(%d) length > SC_BITBUFFSZ (%d)\n",
  1257. length, SC_BITBUFFSZ) );
  1258. if (length<=SC_BITBUFFSZ)
  1259. ScBSPreLoad(BS, length);
  1260. if ((shift=BS->shift)>0)
  1261. {
  1262. if (length<=(u_int)shift) /* all the bits are already in OutBuff & InBuff */
  1263. {
  1264. if (length==SC_BITBUFFSZ)
  1265. {
  1266. BS->OutBuff=BS->InBuff;
  1267. BS->InBuff=0;
  1268. }
  1269. else
  1270. {
  1271. BS->OutBuff=(BS->OutBuff<<length)|(BS->InBuff>>(SC_BITBUFFSZ-length));
  1272. BS->InBuff<<=length;
  1273. }
  1274. BS->CurrentBit+=length;
  1275. BS->shift=shift-length;
  1276. return(NoErrors);
  1277. }
  1278. else /* discard all the bits in OutBuff & InBuff */
  1279. {
  1280. length-=shift;
  1281. BS->OutBuff=BS->InBuff=0;
  1282. BS->CurrentBit+=shift;
  1283. BS->shift=0;
  1284. }
  1285. }
  1286. _SlibDebug(_VERIFY_ && (BS->shift || BS->CurrentBit%8),
  1287. printf("ScBSSkipBits() Bad Alignment - shift=%d CurrentBit=%d\n",
  1288. BS->shift, BS->CurrentBit) );
  1289. skipbytes=length>>3;
  1290. skipbits=length%8;
  1291. _SlibDebug(_WARN_ && skipbits,
  1292. printf("ScBSSkipBits() Skipping odd amount: skipbytes=%d skipbits=%d\n",
  1293. skipbytes, skipbits) );
  1294. if (BS->EOI)
  1295. return(ScErrorEndBitstream);
  1296. while (skipbytes>=(BS->bufftop - BS->buffp))
  1297. {
  1298. /* discard current block of data */
  1299. BS->CurrentBit+=(BS->bufftop - BS->buffp)<<3;
  1300. skipbytes-=BS->bufftop - BS->buffp;
  1301. BS->buffp=0;
  1302. /* get another block */
  1303. if (sc_BSGetData(BS))
  1304. BS->EOI = FALSE;
  1305. else
  1306. {
  1307. BS->EOI = TRUE;
  1308. BS->shift=0;
  1309. return(ScErrorEndBitstream);
  1310. }
  1311. }
  1312. if (skipbytes)
  1313. {
  1314. /* skip forward in current block of data */
  1315. BS->buffp+=skipbytes;
  1316. BS->CurrentBit+=skipbytes<<3;
  1317. }
  1318. if (skipbits)
  1319. {
  1320. /* skip odd number of bits - between 0 and 7 bits */
  1321. ScBSPreLoad(BS, skipbits);
  1322. BS->OutBuff<<=skipbits;
  1323. BS->CurrentBit += skipbits;
  1324. BS->shift-=skipbits;
  1325. }
  1326. return(NoErrors);
  1327. }
  1328. /*
  1329. ** ScBSSkipBitsW()
  1330. ** Skip a certain number of bits
  1331. ** ** Dolby version **
  1332. */
  1333. ScStatus_t ScBSSkipBitsW(ScBitstream_t *BS, u_int length)
  1334. {
  1335. register u_int skipwords, skipbits;
  1336. register int shift;
  1337. _SlibDebug(_DEBUG_, printf("ScBSSkipBitsW(%d): Byte offset = 0x%X\n",length,
  1338. ScBSBytePosition(BS)) );
  1339. _SlibDebug(_WARN_ && length==0,
  1340. printf("ScBSSkipBitsW(%d) length==0\n", length) );
  1341. _SlibDebug(_WARN_ && length>SC_BITBUFFSZ,
  1342. printf("ScBSSkipBits(%d) length > SC_BITBUFFSZ (%d)\n",
  1343. length, SC_BITBUFFSZ) );
  1344. if (length<=SC_BITBUFFSZ)
  1345. ScBSPreLoadW(BS, length);
  1346. if ((shift=BS->shift)>0)
  1347. {
  1348. if (length<=(u_int)shift) /* all the bits are already in OutBuff & InBuff */
  1349. {
  1350. if (length==SC_BITBUFFSZ)
  1351. {
  1352. BS->OutBuff=BS->InBuff;
  1353. BS->InBuff=0;
  1354. }
  1355. else
  1356. {
  1357. BS->OutBuff=(BS->OutBuff<<length)|(BS->InBuff>>(SC_BITBUFFSZ-length));
  1358. BS->InBuff<<=length;
  1359. }
  1360. BS->CurrentBit+=length;
  1361. BS->shift=shift-length;
  1362. return(NoErrors);
  1363. }
  1364. else /* discard all the bits in OutBuff & InBuff */
  1365. {
  1366. length-=shift;
  1367. BS->OutBuff=BS->InBuff=0;
  1368. BS->CurrentBit+=shift;
  1369. BS->shift=0;
  1370. }
  1371. }
  1372. _SlibDebug(_VERIFY_ && (BS->shift || BS->CurrentBit%8),
  1373. printf("ScBSSkipBitsW() Bad Alignment - shift=%d CurrentBit=%d\n",
  1374. BS->shift, BS->CurrentBit) );
  1375. skipwords=length>>4;
  1376. skipbits=length%16;
  1377. _SlibDebug(_WARN_ && skipbits,
  1378. printf("ScBSSkipBitsW() Skipping odd amount: skipwords=%d skipbits=%d\n",
  1379. skipwords, skipbits) );
  1380. if (BS->EOI)
  1381. return(ScErrorEndBitstream);
  1382. while (skipwords>=(BS->bufftop - BS->buffp)/2)
  1383. {
  1384. /* discard current block of data */
  1385. BS->CurrentBit+=((BS->bufftop - BS->buffp)/2)<<4;
  1386. skipwords-=(BS->bufftop - BS->buffp)/2;
  1387. BS->buffp=0;
  1388. /* get another block */
  1389. if (sc_BSGetData(BS))
  1390. BS->EOI = FALSE;
  1391. else
  1392. {
  1393. BS->EOI = TRUE;
  1394. BS->shift=0;
  1395. return(ScErrorEndBitstream);
  1396. }
  1397. }
  1398. if (skipwords)
  1399. {
  1400. /* skip forward in current block of data */
  1401. BS->buffp+=skipwords*2;
  1402. BS->CurrentBit+=skipwords<<4;
  1403. }
  1404. if (skipbits)
  1405. {
  1406. /* skip odd number of bits - between 0 and 7 bits */
  1407. ScBSPreLoadW(BS, skipbits);
  1408. BS->OutBuff<<=skipbits;
  1409. BS->CurrentBit += skipbits;
  1410. BS->shift-=skipbits;
  1411. }
  1412. return(NoErrors);
  1413. }
  1414. /*
  1415. ** ScBSSkipBytes()
  1416. ** Skip a certain number of bytes
  1417. **
  1418. */
  1419. ScStatus_t ScBSSkipBytes(ScBitstream_t *BS, u_int length)
  1420. {
  1421. return(ScBSSkipBits(BS, length<<3));
  1422. }
  1423. /*
  1424. ** ScBSPeekBits()
  1425. ** Return the next length bits from the bitstream without
  1426. ** removing them.
  1427. */
  1428. ScBitString_t ScBSPeekBits(ScBitstream_t *BS, u_int length)
  1429. {
  1430. _SlibDebug(_DEBUG_,
  1431. printf("ScBSPeekBits(%d): Byte offset = 0x%X OutBuff=0x%lX\n",length,
  1432. ScBSBytePosition(BS),BS->OutBuff) );
  1433. _SlibDebug(_VERIFY_ && length>SC_BITBUFFSZ,
  1434. printf("ScBSPeekBits(%d) length > SC_BITBUFFSZ\n", length) );
  1435. _SlibDebug(_WARN_ && length==0,
  1436. printf("ScBSPeekBits(%d) length==0\n", length) );
  1437. if (length==0)
  1438. return(0);
  1439. ScBSPreLoad(BS, length);
  1440. _SlibDebug(_VERIFY_ && BS->shift<length,
  1441. printf("ScBSPeekBits(%d) shift (%d) < length (%d) at byte pos %d (0x%X)\n",
  1442. length, BS->shift, length, BS->CurrentBit/8, BS->CurrentBit/8) );
  1443. if (length == SC_BITBUFFSZ)
  1444. return(BS->OutBuff);
  1445. else
  1446. return(BS->OutBuff >> (SC_BITBUFFSZ-length));
  1447. }
  1448. /*
  1449. ** ScBSPeekBit()
  1450. ** Return the next bit from the bitstream without
  1451. ** removing it.
  1452. */
  1453. int ScBSPeekBit(ScBitstream_t *BS)
  1454. {
  1455. _SlibDebug(_DEBUG_,
  1456. printf("ScBSPeekBit(): Byte offset = 0x%X OutBuff=0x%lX\n",
  1457. ScBSBytePosition(BS),BS->OutBuff) );
  1458. ScBSPreLoad(BS, 1);
  1459. return((int)(BS->OutBuff >> (SC_BITBUFFSZ-1)));
  1460. }
  1461. /*
  1462. ** ScBSPeekBytes()
  1463. ** Return the next length bytes from the bitstream without
  1464. ** removing them.
  1465. */
  1466. ScBitString_t ScBSPeekBytes(ScBitstream_t *BS, u_int length)
  1467. {
  1468. if (length==0)
  1469. return(0);
  1470. length*=8;
  1471. ScBSPreLoad(BS, length);
  1472. if (length == SC_BITBUFFSZ)
  1473. return(BS->OutBuff);
  1474. else
  1475. return(BS->OutBuff >> (SC_BITBUFFSZ-length));
  1476. }
  1477. /*
  1478. ** ScBSGetBytes()
  1479. ** Return the next length bytes from the bitstream
  1480. */
  1481. ScStatus_t ScBSGetBytes(ScBitstream_t *BS, u_char *buffer, u_int length,
  1482. u_int *ret_length)
  1483. {
  1484. int i, shift;
  1485. unsigned int offset=0;
  1486. _SlibDebug(_VERBOSE_, printf("ScBSGetBytes(%d): Byte offset = 0x%X\n",
  1487. length, ScBSBytePosition(BS)) );
  1488. _SlibDebug(_WARN_ && length==0,
  1489. printf("ScBSGetBytes(%d) length==0\n", length) );
  1490. if (BS->EOI)
  1491. {
  1492. *ret_length=0;
  1493. return(ScErrorEndBitstream);
  1494. }
  1495. if (length<(SC_BITBUFFSZ>>3))
  1496. {
  1497. while (offset<length && !BS->EOI)
  1498. {
  1499. *(buffer+offset)=(unsigned char)ScBSGetBits(BS,8);
  1500. offset++;
  1501. }
  1502. *ret_length=offset;
  1503. if (BS->EOI)
  1504. return(ScErrorEndBitstream);
  1505. else
  1506. return(ScErrorNone);
  1507. }
  1508. else if (BS->bufftop>0)
  1509. {
  1510. ScBSByteAlign(BS);
  1511. shift=BS->shift;
  1512. /* remove bytes already in OutBuff and InBuff */
  1513. for (i=0; shift>0 && offset<length; i++, shift-=8, offset++)
  1514. {
  1515. *(buffer+offset)=(unsigned char)(BS->OutBuff>>(SC_BITBUFFSZ-8));
  1516. if (shift<=SC_BITBUFFSZ) /* only bits in OutBuff */
  1517. BS->OutBuff <<= 8;
  1518. else
  1519. {
  1520. BS->OutBuff=(BS->OutBuff<<8)|(BS->InBuff>>(SC_BITBUFFSZ-8));
  1521. BS->InBuff<<=8;
  1522. }
  1523. }
  1524. BS->shift=shift;
  1525. BS->CurrentBit+=i*8;
  1526. }
  1527. while (offset<length)
  1528. {
  1529. i=BS->bufftop-BS->buffp;
  1530. if (offset+i>length)
  1531. i=length-offset;
  1532. memcpy(buffer+offset, BS->buff+BS->buffp, i);
  1533. offset+=i;
  1534. BS->buffp+=i;
  1535. BS->CurrentBit+=i<<3;
  1536. _SlibDebug(_VERIFY_,
  1537. if ((BS->CurrentBit+BS->shift)/8!=BS->buffstart+BS->buffp)
  1538. {
  1539. printf("ScBSGetBytes() (CurrentBit+shift)/8 (%d) <> buffstart+buffp (%d)\n", (BS->CurrentBit+BS->shift)/8, BS->buffstart+BS->buffp);
  1540. BS->EOI = TRUE;
  1541. return(ScErrorEndBitstream);
  1542. } );
  1543. if (offset<length)
  1544. if (!sc_BSGetData(BS))
  1545. {
  1546. BS->EOI = TRUE;
  1547. *ret_length=offset;
  1548. return(ScErrorEndBitstream);
  1549. }
  1550. }
  1551. *ret_length=offset;
  1552. return(ScErrorNone);
  1553. }
  1554. /*
  1555. ** ScBSGetBits()
  1556. ** Return the next length bits from the bitstream
  1557. */
  1558. ScBitString_t ScBSGetBits(ScBitstream_t *BS, u_int length)
  1559. {
  1560. ScBitString_t val;
  1561. _SlibDebug(_DEBUG_ && _debug_getbits,
  1562. printf("ScBSGetBits(%d): Byte offset = 0x%X shift=%d ",
  1563. length, ScBSBytePosition(BS), BS->shift) );
  1564. _SlibDebug(_VERIFY_ && length>SC_BITBUFFSZ,
  1565. printf("ScBSPeekBits(%d) length > SC_BITBUFFSZ\n", length) );
  1566. _SlibDebug(_WARN_ && length==0,
  1567. printf("ScBSGetBits(%d) length==0\n", length) );
  1568. #if FILTER_SUPPORT
  1569. if (BS->FilterCallback && BS->InFilterCallback==FALSE
  1570. && BS->FilterBit<(BS->CurrentBit+length))
  1571. {
  1572. const int tmp=BS->FilterBit-BS->CurrentBit;
  1573. BS->InFilterCallback=TRUE;
  1574. _SlibDebug(_DEBUG_,
  1575. printf("FilterCallback at bitpos=0x%X bytepos=0x%X GetBits(%d/%d)\n",
  1576. ScBSBitPosition(BS), ScBSBytePosition(BS),
  1577. tmp, length-tmp) );
  1578. if (tmp>0)
  1579. {
  1580. length-=tmp;
  1581. val=ScBSGetBits(BS,tmp)<<length;
  1582. }
  1583. else
  1584. val=0;
  1585. _SlibDebug(_VERIFY_ && (BS->FilterBit != BS->CurrentBit),
  1586. printf("ScBSGetBits() FilterCallback not at FilterBit (%d) CurrentBit=%d\n", BS->FilterBit, BS->CurrentBit) );
  1587. BS->FilterBit=(BS->FilterCallback)(BS);
  1588. BS->InFilterCallback=FALSE;
  1589. }
  1590. else
  1591. val=0;
  1592. if (!length)
  1593. return(val);
  1594. #else
  1595. if (!length)
  1596. return(0);
  1597. #endif
  1598. ScBSPreLoad(BS, length);
  1599. if (BS->shift<length) /* End of Input - ran out of bits */
  1600. {
  1601. #if FILTER_SUPPORT
  1602. val |= BS->OutBuff >> (SC_BITBUFFSZ-length); /* return whatever's there */
  1603. #else
  1604. val = BS->OutBuff >> (SC_BITBUFFSZ-length); /* return whatever's there */
  1605. #endif
  1606. BS->shift=0;
  1607. BS->OutBuff=0;
  1608. return(val);
  1609. }
  1610. else
  1611. {
  1612. _SlibDebug(_VERIFY_ && BS->shift<length,
  1613. printf("ScBSGetBits(%d) shift (%d) < length (%d) at byte pos %d (0x%X)\n",
  1614. length, BS->shift, length, BS->CurrentBit/8, BS->CurrentBit/8) );
  1615. if (length!=SC_BITBUFFSZ)
  1616. {
  1617. const ScBitBuff_t OutBuff=BS->OutBuff;
  1618. const ScBitString_t InBuff=BS->InBuff;
  1619. const int shift=BS->shift;
  1620. #if FILTER_SUPPORT
  1621. val |= OutBuff >> (SC_BITBUFFSZ-length);
  1622. #else
  1623. val = OutBuff >> (SC_BITBUFFSZ-length);
  1624. #endif
  1625. BS->OutBuff=(OutBuff<<length)|(InBuff>>(SC_BITBUFFSZ-length));
  1626. BS->InBuff = InBuff<<length;
  1627. BS->shift=shift-length;
  1628. BS->CurrentBit += length;
  1629. }
  1630. else /* length == SC_BITBUFFSZ */
  1631. {
  1632. val = BS->OutBuff;
  1633. BS->OutBuff = BS->InBuff;
  1634. BS->InBuff = 0;
  1635. BS->shift-=SC_BITBUFFSZ;
  1636. BS->CurrentBit += SC_BITBUFFSZ;
  1637. }
  1638. }
  1639. _SlibDebug(_DEBUG_ && _debug_getbits, printf(" Return 0x%lX\n",val) );
  1640. return(val);
  1641. }
  1642. /*
  1643. ** ScBSGetBitsW()
  1644. ** Return the next length bits from the bitstream
  1645. */
  1646. ScBitString_t ScBSGetBitsW(ScBitstream_t *BS, u_int length)
  1647. {
  1648. ScBitString_t val;
  1649. _SlibDebug(_DEBUG_ && _debug_getbits,
  1650. printf("ScBSGetBitsW(%d): Byte offset = 0x%X shift=%d ",
  1651. length, ScBSBytePosition(BS), BS->shift) );
  1652. _SlibDebug(_VERIFY_ && length>SC_BITBUFFSZ,
  1653. printf("ScBSPeekBits(%d) length > SC_BITBUFFSZ\n", length) );
  1654. _SlibDebug(_WARN_ && length==0,
  1655. printf("ScBSGetBitsW(%d) length==0\n", length) );
  1656. #if FILTER_SUPPORT
  1657. if (BS->FilterCallback && BS->InFilterCallback==FALSE
  1658. && BS->FilterBit<(BS->CurrentBit+length))
  1659. {
  1660. const int tmp=BS->FilterBit-BS->CurrentBit;
  1661. BS->InFilterCallback=TRUE;
  1662. _SlibDebug(_DEBUG_,
  1663. printf("FilterCallback at bitpos=0x%X bytepos=0x%X GetBits(%d/%d)\n",
  1664. ScBSBitPosition(BS), ScBSBytePosition(BS),
  1665. tmp, length-tmp) );
  1666. if (tmp>0)
  1667. {
  1668. length-=tmp;
  1669. val=ScBSGetBitsW(BS,tmp)<<length;
  1670. }
  1671. else
  1672. val=0;
  1673. _SlibDebug(_VERIFY_ && (BS->FilterBit != BS->CurrentBit),
  1674. printf("ScBSGetBits() FilterCallback not at FilterBit (%d) CurrentBit=%d\n", BS->FilterBit, BS->CurrentBit) );
  1675. BS->FilterBit=(BS->FilterCallback)(BS);
  1676. BS->InFilterCallback=FALSE;
  1677. }
  1678. else
  1679. val=0;
  1680. if (!length)
  1681. return(val);
  1682. #else
  1683. if (!length)
  1684. return(0);
  1685. #endif
  1686. ScBSPreLoadW(BS, length);
  1687. if (BS->shift<length) /* End of Input - ran out of bits */
  1688. {
  1689. #if FILTER_SUPPORT
  1690. val |= BS->OutBuff >> (SC_BITBUFFSZ-length); /* return whatever's there */
  1691. #else
  1692. val = BS->OutBuff >> (SC_BITBUFFSZ-length); /* return whatever's there */
  1693. #endif
  1694. BS->shift=0;
  1695. BS->OutBuff=0;
  1696. return(val);
  1697. }
  1698. else
  1699. {
  1700. _SlibDebug(_VERIFY_ && BS->shift<length,
  1701. printf("ScBSGetBits(%d) shift (%d) < length (%d) at byte pos %d (0x%X)\n",
  1702. length, BS->shift, length, BS->CurrentBit/8, BS->CurrentBit/8) );
  1703. if (length!=SC_BITBUFFSZ)
  1704. {
  1705. const ScBitBuff_t OutBuff=BS->OutBuff;
  1706. const ScBitString_t InBuff=BS->InBuff;
  1707. const int shift=BS->shift;
  1708. #if FILTER_SUPPORT
  1709. val |= OutBuff >> (SC_BITBUFFSZ-length);
  1710. #else
  1711. val = OutBuff >> (SC_BITBUFFSZ-length);
  1712. #endif
  1713. BS->OutBuff=(OutBuff<<length)|(InBuff>>(SC_BITBUFFSZ-length));
  1714. BS->InBuff = InBuff<<length;
  1715. BS->shift=shift-length;
  1716. BS->CurrentBit += length;
  1717. }
  1718. else /* length == SC_BITBUFFSZ */
  1719. {
  1720. val = BS->OutBuff;
  1721. BS->OutBuff = BS->InBuff;
  1722. BS->InBuff = 0;
  1723. BS->shift-=SC_BITBUFFSZ;
  1724. BS->CurrentBit += SC_BITBUFFSZ;
  1725. }
  1726. }
  1727. _SlibDebug(_DEBUG_ && _debug_getbits, printf(" Return 0x%lX\n",val) );
  1728. return(val);
  1729. }
  1730. /*
  1731. ** ScBSGetBit()
  1732. ** Put a single bit onto the bitstream
  1733. */
  1734. int ScBSGetBit(ScBitstream_t *BS)
  1735. {
  1736. int val;
  1737. _SlibDebug(_DEBUG_ && _debug_getbits,
  1738. printf("ScBSGetBit(): Byte offset = 0x%X shift=%d ",
  1739. ScBSBytePosition(BS), BS->shift) );
  1740. #if FILTER_SUPPORT
  1741. if (BS->FilterCallback && BS->InFilterCallback==FALSE
  1742. && BS->FilterBit==BS->CurrentBit)
  1743. {
  1744. BS->InFilterCallback=TRUE;
  1745. _SlibDebug(_DEBUG_,
  1746. printf("FilterCallback at bitpos=0x%X bytepos=0x%X\n",
  1747. ScBSBitPosition(BS), ScBSBytePosition(BS)) );
  1748. BS->FilterBit=(BS->FilterCallback)(BS);
  1749. BS->InFilterCallback=FALSE;
  1750. }
  1751. #endif
  1752. ScBSPreLoad(BS, 1);
  1753. if (!BS->EOI)
  1754. {
  1755. const ScBitBuff_t OutBuff=BS->OutBuff;
  1756. val=(int)(OutBuff>>(SC_BITBUFFSZ-1));
  1757. if (--BS->shift>=SC_BITBUFFSZ)
  1758. {
  1759. const ScBitBuff_t InBuff=BS->InBuff;
  1760. BS->OutBuff = (OutBuff<<1)|(InBuff >> (SC_BITBUFFSZ-1));
  1761. BS->InBuff = InBuff<<1;
  1762. }
  1763. else
  1764. BS->OutBuff = OutBuff<<1;
  1765. BS->CurrentBit++;
  1766. }
  1767. else
  1768. val=0;
  1769. _SlibDebug(_DEBUG_ && _debug_getbits, printf(" Return 0x%lX\n",val) );
  1770. return(val);
  1771. }
  1772. /*
  1773. ** ScBSPutBits()
  1774. ** Put a number of bits onto the bitstream
  1775. */
  1776. ScStatus_t ScBSPutBits(ScBitstream_t *BS, ScBitString_t bits, u_int length)
  1777. {
  1778. ScStatus_t stat;
  1779. const int newshift=BS->shift+length;
  1780. if (length<SC_BITBUFFSZ)
  1781. bits &= ((ScBitString_t)1<<length)-1;
  1782. _SlibDebug(_DEBUG_, printf("ScBSPutBits(0x%lX, %d): Byte offset = 0x%X ",
  1783. bits, length, ScBSBytePosition(BS)) );
  1784. _SlibDebug(_VERIFY_&&length<SC_BITBUFFSZ && bits>=((ScBitString_t)1<<length),
  1785. printf("ScBSPutBits(%d): bits (0x%X) to large\n", length, bits) );
  1786. if (!length)
  1787. return(NoErrors);
  1788. else if (newshift < SC_BITBUFFSZ)
  1789. {
  1790. BS->OutBuff=(BS->OutBuff<<length) | bits;
  1791. BS->shift=newshift;
  1792. stat=NoErrors;
  1793. }
  1794. else if (newshift == SC_BITBUFFSZ)
  1795. {
  1796. stat=sc_BSStoreDataWord(BS, (BS->OutBuff<<length)|bits);
  1797. BS->OutBuff=0;
  1798. BS->shift=0;
  1799. }
  1800. else
  1801. {
  1802. const int bitsavail=SC_BITBUFFSZ-BS->shift;
  1803. const int bitsleft=length-bitsavail;
  1804. const ScBitString_t outbits=bits>>bitsleft;
  1805. _SlibDebug(_DEBUG_, printf("ScBSPutBits(%d) Storing 0x%lX\n",
  1806. length, (BS->OutBuff<<bitsavail)|outbits) );
  1807. stat=sc_BSStoreDataWord(BS, (BS->OutBuff<<bitsavail)|outbits);
  1808. _SlibDebug(_VERIFY_ && (bitsavail<=0 || bitsleft>=SC_BITBUFFSZ),
  1809. printf("ScBSPutBits(%d) bad bitsleft (%d)\n",
  1810. bitsleft) );
  1811. _SlibDebug(_VERIFY_ && (bitsavail<=0 || bitsavail>=SC_BITBUFFSZ),
  1812. printf("ScBSPutBits(%d) bad bitsavail (%d)\n", bitsavail) );
  1813. #if 1
  1814. BS->OutBuff=bits & (((ScBitBuff_t)1<<bitsleft)-1);
  1815. #else
  1816. BS->OutBuff=bits-(outbits<<bitsleft);
  1817. #endif
  1818. BS->shift=bitsleft;
  1819. }
  1820. BS->CurrentBit += length;
  1821. return(stat);
  1822. }
  1823. /*
  1824. ** ScBSPutBytes()
  1825. ** Put a number of bits onto the bitstream
  1826. */
  1827. ScStatus_t ScBSPutBytes(ScBitstream_t *BS, u_char *buffer, u_int length)
  1828. {
  1829. ScStatus_t stat=NoErrors;
  1830. _SlibDebug(_VERIFY_, printf("ScBSPutBytes(length=%d): Byte offset = 0x%X ",
  1831. length, ScBSBytePosition(BS)) );
  1832. while (stat==NoErrors && length>0)
  1833. {
  1834. stat=ScBSPutBits(BS, (ScBitString_t)*buffer, 8);
  1835. buffer++;
  1836. length--;
  1837. }
  1838. return(stat);
  1839. }
  1840. /*
  1841. ** ScBSPutBit()
  1842. ** Put a single bit onto the bitstream
  1843. */
  1844. ScStatus_t ScBSPutBit(ScBitstream_t *BS, char bit)
  1845. {
  1846. ScStatus_t stat;
  1847. const int shift=BS->shift;
  1848. _SlibDebug(_DEBUG_, printf("ScBSPutBit(0x%lX): Byte offset = 0x%X ",
  1849. bit, ScBSBytePosition(BS)) );
  1850. _SlibDebug(_VERIFY_ && bit>1, printf("ScBSPutBit(): bit>1") );
  1851. if (shift < (SC_BITBUFFSZ-1))
  1852. {
  1853. BS->OutBuff<<=1;
  1854. if (bit)
  1855. BS->OutBuff|=1;
  1856. BS->shift=shift+1;
  1857. stat=NoErrors;
  1858. }
  1859. else if (shift == SC_BITBUFFSZ-1)
  1860. {
  1861. if (bit)
  1862. stat=sc_BSStoreDataWord(BS, (BS->OutBuff<<1)+1);
  1863. else
  1864. stat=sc_BSStoreDataWord(BS, BS->OutBuff<<1);
  1865. BS->OutBuff=0;
  1866. BS->shift=0;
  1867. }
  1868. else
  1869. {
  1870. _SlibDebug(_DEBUG_, printf("BS Storing(0x%lX)\n", BS->OutBuff) );
  1871. stat=sc_BSStoreDataWord(BS, BS->OutBuff);
  1872. BS->OutBuff=bit;
  1873. BS->shift=1;
  1874. }
  1875. BS->CurrentBit++;
  1876. return(stat);
  1877. }
  1878. /*
  1879. ** Name: ScBSGetBitsVarLen()
  1880. ** Purpose: Return bits from the bitstream. # bits depends on table
  1881. */
  1882. int ScBSGetBitsVarLen(ScBitstream_t *BS, const int *table, int len)
  1883. {
  1884. int index, lookup;
  1885. index=(int)ScBSPeekBits(BS, len);
  1886. lookup = table[index];
  1887. _SlibDebug(_DEBUG_,
  1888. printf("ScBSGetBitsVarLen(len=%d): Byte offset=0x%X table[%d]=0x%X Return=%d\n",
  1889. len, ScBSBytePosition(BS), index, lookup, lookup >> 6) );
  1890. ScBSGetBits(BS, lookup & 0x3F);
  1891. return(lookup >> 6);
  1892. }
  1893. #ifndef ScBSBitPosition
  1894. /* Now is a macro in SC.h */
  1895. /*
  1896. ** Name: ScBSBitPosition()
  1897. ** Purpose: Return the absolute bit position in the stream
  1898. */
  1899. long ScBSBitPosition(ScBitstream_t *BS)
  1900. {
  1901. return(BS->CurrentBit);
  1902. }
  1903. #endif
  1904. #ifndef ScBSBytePosition
  1905. /* Now is a macro in SC.h */
  1906. /*
  1907. ** Name: ScBSBytePosition()
  1908. ** Purpose: Return the absolute byte position in the stream
  1909. */
  1910. long ScBSBytePosition(ScBitstream_t *BS)
  1911. {
  1912. return(BS->CurrentBit>>3);
  1913. }
  1914. #endif
  1915. /*
  1916. ** Name: ScBSSeekAlign()
  1917. ** Purpose: Seeks for a byte aligned word in the bit stream
  1918. ** and places the bit stream pointer right after its
  1919. ** found position.
  1920. ** Return: Returns TRUE if the sync was found otherwise it returns FALSE.
  1921. */
  1922. int ScBSSeekAlign(ScBitstream_t *BS, ScBitString_t seek_word, int word_len)
  1923. {
  1924. _SlibDebug(_VERBOSE_,
  1925. printf("ScBSSeekAlign(BS=%p, seek_word=0x%x, word_len=%d)\n",
  1926. BS, seek_word, word_len) );
  1927. _SlibDebug(_VERIFY_ && !word_len,
  1928. printf("ScBSSeekAlign(BS=%p) word_len=0\n", BS) );
  1929. ScBSByteAlign(BS)
  1930. _SlibDebug(_VERIFY_, _debug_start=BS->CurrentBit );
  1931. #if USE_FAST_SEEK
  1932. if (word_len%8==0 && word_len<=32 && !BS->EOI) /* do a fast seek */
  1933. {
  1934. unsigned char *buff, nextbyte;
  1935. const unsigned char byte1=(seek_word>>(word_len-8))&0xFF;
  1936. int bytesinbuff;
  1937. seek_word-=((ScBitString_t)byte1)<<word_len;
  1938. word_len-=8;
  1939. _SlibDebug(_VERIFY_ && seek_word >= (ScBitString_t)1<<word_len,
  1940. printf("ScBSSeekAlign(BS=%p) shift (%d) <> 0\n", BS, BS->shift) );
  1941. if (BS->buffp>=(BS->shift/8)) /* empty OutBuff & InBuff */
  1942. {
  1943. BS->shift=0;
  1944. BS->OutBuff=0;
  1945. BS->InBuff=0;
  1946. BS->buffp-=BS->shift/8;
  1947. }
  1948. else while (BS->shift) /* search whats in OutBuff & InBuff first */
  1949. {
  1950. _SlibDebug(_DEBUG_,
  1951. printf("ScBSSeekAlign() Fast searching OutBuff & InBuff\n") );
  1952. nextbyte=BS->OutBuff>>(SC_BITBUFFSZ-8);
  1953. BS->shift-=8;
  1954. BS->OutBuff=(BS->OutBuff<<8)|(BS->InBuff>>(SC_BITBUFFSZ-8));
  1955. BS->InBuff<<=8;
  1956. BS->CurrentBit+=8;
  1957. if (nextbyte==byte1
  1958. && (word_len==0 || ScBSPeekBits(BS, word_len)==seek_word))
  1959. {
  1960. /* found seek_word in buffer */
  1961. ScBSSkipBits(BS, word_len);
  1962. return(!BS->EOI);
  1963. }
  1964. }
  1965. _SlibDebug(_VERIFY_ && BS->shift,
  1966. printf("ScBSSeekAlign(BS=%p) shift (%d) <> 0\n", BS, BS->shift) );
  1967. _SlibDebug(_VERIFY_ && BS->OutBuff,
  1968. printf("ScBSSeekAlign(BS=%p) OutBuff (0x%lX) <> 0\n", BS, BS->OutBuff) );
  1969. _SlibDebug(_VERIFY_ && BS->InBuff,
  1970. printf("ScBSSeekAlign(BS=%p) InBuff (0x%lX) <> 0\n", BS, BS->InBuff) );
  1971. bytesinbuff=BS->bufftop-BS->buffp;
  1972. if (bytesinbuff<=0) /* Get more data if all out */
  1973. {
  1974. if (!sc_BSGetData(BS))
  1975. {
  1976. BS->EOI=TRUE;
  1977. return(FALSE);
  1978. }
  1979. bytesinbuff=BS->bufftop;
  1980. }
  1981. buff=BS->buff+BS->buffp;
  1982. switch (word_len/8)
  1983. {
  1984. case 0: /* word length = 1 byte */
  1985. while (1)
  1986. {
  1987. if (*buff++==byte1)
  1988. {
  1989. BS->buffp=buff-BS->buff;
  1990. BS->CurrentBit=(BS->buffstart+BS->buffp)*8;
  1991. _SlibDebug(_DEBUG_,
  1992. printf("ScBSSeekAlign() Found %X at pos %d (0x%X)\n",
  1993. byte1, BS->CurrentBit/8, BS->CurrentBit/8) );
  1994. _SlibDebug(_VERIFY_ && BS->buff[BS->buffp-1]!=byte1,
  1995. printf("ScBSSeekAlign() bad position for buffp\n") );
  1996. return(TRUE);
  1997. }
  1998. if ((--bytesinbuff)==0)
  1999. {
  2000. if (!sc_BSGetData(BS))
  2001. {
  2002. BS->EOI=TRUE;
  2003. return(FALSE);
  2004. }
  2005. buff=BS->buff;
  2006. bytesinbuff=BS->bufftop;
  2007. }
  2008. _SlibDebug(_VERIFY_ && bytesinbuff<=0,
  2009. printf("ScBSSeekAlign() bytesinbuff (%d)<=0\n", bytesinbuff) );
  2010. }
  2011. break;
  2012. case 1: /* word length = 2 bytes */
  2013. {
  2014. const unsigned char byte2=seek_word&0xFF;
  2015. while (1)
  2016. {
  2017. if (*buff++==byte1)
  2018. {
  2019. if ((--bytesinbuff)==0)
  2020. {
  2021. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2022. if (!sc_BSGetData(BS))
  2023. {
  2024. BS->EOI=TRUE;
  2025. return(FALSE);
  2026. }
  2027. buff=BS->buff;
  2028. bytesinbuff=BS->bufftop;
  2029. }
  2030. if (*buff++==byte2)
  2031. {
  2032. BS->buffp=buff-BS->buff;
  2033. BS->CurrentBit=(BS->buffstart+BS->buffp)*8;
  2034. _SlibDebug(_DEBUG_,
  2035. printf("ScBSSeekAlign() Found %X %X at pos %d (0x%X)\n",
  2036. byte1, byte2, BS->CurrentBit/8, BS->CurrentBit/8) );
  2037. _SlibDebug(_VERIFY_ && BS->buff[BS->buffp-1]!=byte2,
  2038. printf("ScBSSeekAlign() bad position for buffp\n") );
  2039. return(TRUE);
  2040. }
  2041. }
  2042. if ((--bytesinbuff)==0)
  2043. {
  2044. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2045. if (!sc_BSGetData(BS))
  2046. {
  2047. BS->EOI=TRUE;
  2048. return(FALSE);
  2049. }
  2050. buff=BS->buff;
  2051. bytesinbuff=BS->bufftop;
  2052. }
  2053. _SlibDebug(_VERIFY_ && bytesinbuff<=0,
  2054. printf("ScBSSeekAlign() bytesinbuff (%d)<=0\n", bytesinbuff) );
  2055. }
  2056. }
  2057. break;
  2058. case 2: /* word length = 3 bytes */
  2059. {
  2060. const unsigned char byte2=(seek_word>>8)&0xFF;
  2061. const unsigned char byte3=seek_word&0xFF;
  2062. while (1)
  2063. {
  2064. if (*buff++==byte1)
  2065. {
  2066. if ((--bytesinbuff)==0)
  2067. {
  2068. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2069. if (!sc_BSGetData(BS))
  2070. {
  2071. BS->EOI=TRUE;
  2072. return(FALSE);
  2073. }
  2074. buff=BS->buff;
  2075. bytesinbuff=BS->bufftop;
  2076. }
  2077. if (*buff++==byte2)
  2078. {
  2079. if ((--bytesinbuff)==0)
  2080. {
  2081. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2082. if (!sc_BSGetData(BS))
  2083. {
  2084. BS->EOI=TRUE;
  2085. return(FALSE);
  2086. }
  2087. buff=BS->buff;
  2088. bytesinbuff=BS->bufftop;
  2089. }
  2090. if (*buff++==byte3)
  2091. {
  2092. BS->buffp=buff-BS->buff;
  2093. BS->CurrentBit=(BS->buffstart+BS->buffp)*8;
  2094. _SlibDebug(_DEBUG_,
  2095. printf("ScBSSeekAlign() Found %X %X %X at pos %d (0x%X)\n",
  2096. byte1, byte2, byte3,
  2097. BS->CurrentBit/8, BS->CurrentBit/8) );
  2098. _SlibDebug(_VERIFY_ && BS->buff[BS->buffp-1]!=byte3,
  2099. printf("ScBSSeekAlign() bad position for buffp\n") );
  2100. return(TRUE);
  2101. }
  2102. }
  2103. }
  2104. if ((--bytesinbuff)==0)
  2105. {
  2106. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2107. if (!sc_BSGetData(BS))
  2108. {
  2109. BS->EOI=TRUE;
  2110. return(FALSE);
  2111. }
  2112. buff=BS->buff;
  2113. bytesinbuff=BS->bufftop;
  2114. }
  2115. _SlibDebug(_VERIFY_ && bytesinbuff<=0,
  2116. printf("ScBSSeekAlign() bytesinbuff (%d)<=0\n", bytesinbuff) );
  2117. }
  2118. }
  2119. break;
  2120. case 3: /* word length = 4 bytes */
  2121. {
  2122. const unsigned char byte2=(seek_word>>16)&0xFF;
  2123. const unsigned char byte3=(seek_word>>8)&0xFF;
  2124. const unsigned char byte4=seek_word&0xFF;
  2125. while (1)
  2126. {
  2127. if (*buff++==byte1)
  2128. {
  2129. if ((--bytesinbuff)==0)
  2130. {
  2131. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2132. if (!sc_BSGetData(BS))
  2133. {
  2134. BS->EOI=TRUE;
  2135. return(FALSE);
  2136. }
  2137. buff=BS->buff;
  2138. bytesinbuff=BS->bufftop;
  2139. }
  2140. if (*buff++==byte2)
  2141. {
  2142. if ((--bytesinbuff)==0)
  2143. {
  2144. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2145. if (!sc_BSGetData(BS))
  2146. {
  2147. BS->EOI=TRUE;
  2148. return(FALSE);
  2149. }
  2150. buff=BS->buff;
  2151. bytesinbuff=BS->bufftop;
  2152. }
  2153. if (*buff++==byte3)
  2154. {
  2155. if ((--bytesinbuff)==0)
  2156. {
  2157. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2158. if (!sc_BSGetData(BS))
  2159. {
  2160. BS->EOI=TRUE;
  2161. return(FALSE);
  2162. }
  2163. buff=BS->buff;
  2164. bytesinbuff=BS->bufftop;
  2165. }
  2166. if (*buff++==byte4)
  2167. {
  2168. BS->buffp=buff-BS->buff;
  2169. BS->CurrentBit=(BS->buffstart+BS->buffp)*8;
  2170. _SlibDebug(_DEBUG_,
  2171. printf("ScBSSeekAlign() Found %X %X %X %X at pos %d (0x%X)\n",
  2172. byte1, byte2, byte3, byte4,
  2173. BS->CurrentBit/8, BS->CurrentBit/8) );
  2174. _SlibDebug(_VERIFY_ && BS->buff[BS->buffp-1]!=byte4,
  2175. printf("ScBSSeekAlign() bad position for buffp\n") );
  2176. return(TRUE);
  2177. }
  2178. }
  2179. }
  2180. }
  2181. if ((--bytesinbuff)==0)
  2182. {
  2183. BS->CurrentBit=(BS->buffstart+buff-BS->buff)*8;
  2184. if (!sc_BSGetData(BS))
  2185. {
  2186. BS->EOI=TRUE;
  2187. return(FALSE);
  2188. }
  2189. buff=BS->buff;
  2190. bytesinbuff=BS->bufftop;
  2191. }
  2192. _SlibDebug(_VERIFY_ && bytesinbuff<=0,
  2193. printf("ScBSSeekAlign() bytesinbuff (%d)<=0\n", bytesinbuff) );
  2194. }
  2195. }
  2196. break;
  2197. default:
  2198. _SlibDebug(_VERIFY_,
  2199. printf("ScBSSeekAlign() Bad fast word length %d\n", word_len) );
  2200. break;
  2201. }
  2202. }
  2203. else
  2204. #endif
  2205. { /* a slow seek */
  2206. ScBitString_t val;
  2207. const ScBitString_t maxi = ((ScBitString_t)1 << word_len)-(ScBitString_t)1;
  2208. val = ScBSGetBits(BS, word_len);
  2209. _SlibDebug(_DEBUG_, _debug_getbits=FALSE );
  2210. while ((val&maxi)!=seek_word && !BS->EOI)
  2211. val = (val<<8)|ScBSGetBits(BS, 8);
  2212. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2213. }
  2214. _SlibDebug(_WARN_,
  2215. _debug_stop=BS->CurrentBit;
  2216. if ((_debug_stop-_debug_start)>word_len)
  2217. printf("ScBSSeekAlign() Moved %d bits (%d bytes) byte pos 0x%X->0x%X\n",
  2218. _debug_stop-_debug_start, (_debug_stop-_debug_start)/8,
  2219. _debug_start/8, _debug_stop/8)
  2220. );
  2221. _SlibDebug(_DEBUG_, printf("ScBSSeekAlign() Exit with %s\n",
  2222. BS->EOI ? "FALSE" : "TRUE") );
  2223. return(!BS->EOI);
  2224. }
  2225. /*
  2226. ** Name: ScBSSeekAlignStopAt()
  2227. ** Purpose: Seeks for a byte aligned word in the bit stream
  2228. ** and places the bit stream pointer right after its
  2229. ** found position.
  2230. ** Searches only until end_byte_pos is reached.
  2231. ** Return: Returns TRUE if the word was found otherwise it returns FALSE.
  2232. */
  2233. int ScBSSeekAlignStopAt(ScBitstream_t *BS, ScBitString_t seek_word,
  2234. int word_len, unsigned long end_byte_pos)
  2235. {
  2236. ScBSPosition_t end_bit_pos=end_byte_pos<<3;
  2237. ScBitString_t val;
  2238. const ScBitString_t maxi = ((ScBitString_t)1 << word_len) - 1;
  2239. _SlibDebug(_VERBOSE_,
  2240. printf("ScBSSeekAlignStopAt(seek_word=0x%x, word_len=%d, end=%d)\n",
  2241. seek_word, word_len, end_byte_pos) );
  2242. if (ScBSBytePosition(BS)>=end_byte_pos)
  2243. return(FALSE);
  2244. ScBSByteAlign(BS)
  2245. if (ScBSBytePosition(BS)>=end_byte_pos)
  2246. return(FALSE);
  2247. if ((BS->CurrentBit+word_len)>end_bit_pos)
  2248. {
  2249. ScBSSkipBits(BS, (unsigned int)(end_bit_pos-BS->CurrentBit));
  2250. return(FALSE);
  2251. }
  2252. val = ScBSGetBits(BS, word_len);
  2253. _SlibDebug(_DEBUG_, _debug_getbits=FALSE );
  2254. while ((val&maxi)!=seek_word && !BS->EOI)
  2255. {
  2256. if ((BS->CurrentBit+word_len)>end_bit_pos)
  2257. {
  2258. ScBSSkipBits(BS, (unsigned int)(end_bit_pos-BS->CurrentBit));
  2259. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2260. return(FALSE);
  2261. }
  2262. val <<= 8;
  2263. val |= ScBSGetBits(BS, 8);
  2264. }
  2265. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2266. _SlibDebug(_DEBUG_, printf("ScBSSeekAlignStopAt() Exit with %s\n",
  2267. BS->EOI ? "FALSE" : "TRUE") );
  2268. return(!BS->EOI);
  2269. }
  2270. /*
  2271. ** Name: ScBSSeekAlignStopBefore()
  2272. ** Purpose: Seeks for a byte aligned word in the bit stream,
  2273. ** if found, places the bit stream pointer right at the beginning
  2274. ** of the word.
  2275. ** Return: Returns TRUE if the word was found otherwise it returns FALSE.
  2276. */
  2277. int ScBSSeekAlignStopBefore(ScBitstream_t *BS, ScBitString_t seek_word,
  2278. int word_len)
  2279. {
  2280. const int iword_len=SC_BITBUFFSZ-word_len;
  2281. _SlibDebug(_VERBOSE_,
  2282. printf("ScBSSeekAlignStopBefore(seek_word=0x%x, word_len=%d)\n",
  2283. seek_word, word_len) );
  2284. _SlibDebug(_VERIFY_ && !word_len,
  2285. printf("ScBSSeekAlignStopBefore() word_len=0\n") );
  2286. ScBSByteAlign(BS)
  2287. _SlibDebug(_VERIFY_, _debug_start=BS->CurrentBit );
  2288. _SlibDebug(_DEBUG_, _debug_getbits=FALSE );
  2289. /* make sure there's at least word_len bits in OutBuff */
  2290. ScBSPreLoad(BS, word_len);
  2291. while ((BS->OutBuff>>iword_len)!=seek_word && !BS->EOI)
  2292. {
  2293. ScBSSkipBits(BS, 8);
  2294. ScBSPreLoad(BS, word_len);
  2295. }
  2296. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2297. _SlibDebug(_WARN_,
  2298. _debug_stop=BS->CurrentBit;
  2299. if ((_debug_stop-_debug_start)>word_len)
  2300. printf("ScBSSeekAlignStopBefore() Moved %d bits (%d bytes) byte pos 0x%X->0x%X\n",
  2301. _debug_stop-_debug_start, (_debug_stop-_debug_start)/8,
  2302. _debug_start/8, _debug_stop/8)
  2303. );
  2304. _SlibDebug(_DEBUG_, printf("ScBSSeekAlignStopBefore() Exit with %s\n",
  2305. BS->EOI ? "FALSE" : "TRUE") );
  2306. return(!BS->EOI);
  2307. }
  2308. /*
  2309. ** Name: ScBSSeekStopBefore()
  2310. ** Purpose: Seeks for a word in the bit stream,
  2311. ** if found, places the bit stream pointer right at the beginning
  2312. ** of the word.
  2313. ** Return: Returns TRUE if the word was found otherwise it returns FALSE.
  2314. */
  2315. int ScBSSeekStopBefore(ScBitstream_t *BS, ScBitString_t seek_word,
  2316. int word_len)
  2317. {
  2318. const int iword_len=SC_BITBUFFSZ-word_len;
  2319. _SlibDebug(_VERBOSE_,
  2320. printf("ScBSSeekStopBefore(seek_word=0x%x, word_len=%d)\n",
  2321. seek_word, word_len) );
  2322. _SlibDebug(_VERIFY_ && !word_len,
  2323. printf("ScBSSeekStopBefore() word_len=0\n") );
  2324. _SlibDebug(_VERIFY_, _debug_start=BS->CurrentBit );
  2325. _SlibDebug(_DEBUG_, _debug_getbits=FALSE );
  2326. /* make sure there's at least word_len bits in OutBuff */
  2327. ScBSPreLoad(BS, word_len);
  2328. while ((BS->OutBuff>>iword_len)!=seek_word && !BS->EOI)
  2329. {
  2330. ScBSSkipBits(BS, 1);
  2331. ScBSPreLoad(BS, word_len);
  2332. }
  2333. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2334. _SlibDebug(_WARN_,
  2335. _debug_stop=BS->CurrentBit;
  2336. if ((_debug_stop-_debug_start)>word_len)
  2337. printf("ScBSSeekAlignStopBefore() Moved %d bits (%d bytes) byte pos 0x%X->0x%X\n",
  2338. _debug_stop-_debug_start, (_debug_stop-_debug_start)/8,
  2339. _debug_start/8, _debug_stop/8)
  2340. );
  2341. _SlibDebug(_DEBUG_, printf("ScBSSeekStopBefore() Exit with %s\n",
  2342. BS->EOI ? "FALSE" : "TRUE") );
  2343. return(!BS->EOI);
  2344. }
  2345. /*
  2346. ** Name: ScBSSeekAlignStopBeforeW()
  2347. ** Purpose: Seeks for a byte aligned word in the bit stream,
  2348. ** if found, places the bit stream pointer right at the beginning
  2349. ** of the word.
  2350. ** Return: Returns TRUE if the word was found otherwise it returns FALSE.
  2351. **
  2352. ** NB: This version uses Dolby style word loading for bitstream
  2353. */
  2354. int ScBSSeekAlignStopBeforeW(ScBitstream_t *BS, ScBitString_t seek_word,
  2355. int word_len)
  2356. {
  2357. const int iword_len=SC_BITBUFFSZ-word_len;
  2358. _SlibDebug(_VERBOSE_,
  2359. printf("ScBSSeekAlignStopBeforeW(seek_word=0x%x, word_len=%d)\n",
  2360. seek_word, word_len) );
  2361. _SlibDebug(_VERIFY_ && !word_len,
  2362. printf("ScBSSeekAlignStopBeforeW() word_len=0\n") );
  2363. ScBSByteAlign(BS)
  2364. _SlibDebug(_VERIFY_, _debug_start=BS->CurrentBit );
  2365. _SlibDebug(_DEBUG_, _debug_getbits=FALSE );
  2366. /* make sure there's at least word_len bits in OutBuff */
  2367. ScBSPreLoadW(BS, word_len);
  2368. while ((BS->OutBuff>>iword_len)!=seek_word && !BS->EOI)
  2369. {
  2370. ScBSSkipBitsW(BS, 8);
  2371. ScBSPreLoadW(BS, word_len);
  2372. }
  2373. _SlibDebug(_DEBUG_, _debug_getbits=TRUE );
  2374. _SlibDebug(_WARN_,
  2375. _debug_stop=BS->CurrentBit;
  2376. if ((_debug_stop-_debug_start)>word_len)
  2377. printf("ScBSSeekAlignStopBeforeW() Moved %d bits (%d bytes) byte pos 0x%X->0x%X\n",
  2378. _debug_stop-_debug_start, (_debug_stop-_debug_start)/8,
  2379. _debug_start/8, _debug_stop/8)
  2380. );
  2381. _SlibDebug(_DEBUG_, printf("ScBSSeekAlignStopBeforeW() Exit with %s\n",
  2382. BS->EOI ? "FALSE" : "TRUE") );
  2383. return(!BS->EOI);
  2384. }
  2385. /*
  2386. ** Name: ScBSGetBytesStopBefore()
  2387. ** Purpose: Gets all the bytes until seek_word (byte aligned)
  2388. ** is encountered.
  2389. ** Searches only until 'length' bytes are read.
  2390. ** Return: Returns TRUE if the word was found otherwise it returns FALSE.
  2391. */
  2392. int ScBSGetBytesStopBefore(ScBitstream_t *BS, u_char *buffer, u_int length,
  2393. u_int *ret_length, ScBitString_t seek_word,
  2394. int word_len)
  2395. {
  2396. unsigned long offset=0;
  2397. const int iword_len=SC_BITBUFFSZ-word_len;
  2398. _SlibDebug(_VERBOSE_,
  2399. printf("ScBSGetBytesStopBefore(seek_word=0x%x, word_len=%d)\n",
  2400. seek_word, word_len) );
  2401. ScBSByteAlign(BS)
  2402. ScBSPreLoad(BS, word_len);
  2403. while ((BS->OutBuff>>iword_len) != seek_word &&
  2404. offset<length && !BS->EOI)
  2405. {
  2406. *buffer = (unsigned char)ScBSGetBits(BS, 8);
  2407. buffer++;
  2408. offset++;
  2409. ScBSPreLoad(BS, word_len);
  2410. }
  2411. *ret_length=offset;
  2412. _SlibDebug(_DEBUG_,
  2413. printf("ScBSGetBytesStopBefore(ret_length=%d) Exit with %s\n",
  2414. *ret_length, (BS->EOI||offset>=length) ? "FALSE" : "TRUE") );
  2415. if (BS->EOI || offset>=length)
  2416. return(FALSE);
  2417. else
  2418. return(TRUE);
  2419. }
  2420. /*
  2421. ** Name: ScBSFlush()
  2422. ** Purpose: Flushes data from the buffers
  2423. */
  2424. ScStatus_t ScBSFlush(ScBitstream_t *BS)
  2425. {
  2426. ScStatus_t stat=NoErrors;
  2427. _SlibDebug(_VERBOSE_, printf("ScBSFlush() In\n") );
  2428. if (!BS)
  2429. return(ScErrorBadPointer);
  2430. if ((BS->Mode=='w' || BS->Mode=='b') && BS->buffp>0)
  2431. {
  2432. if (BS->shift>0) /* some remaining bits in internal buffers */
  2433. {
  2434. /* byte align last bits */
  2435. ScBSAlignPutBits(BS);
  2436. if (BS->buffp>=BS->bufftop)
  2437. stat=sc_BSPutData(BS);
  2438. /* Copy the remaining bytes in OutBuff to the current buffer */
  2439. while (BS->shift>0 && BS->buffp<BS->bufftop)
  2440. {
  2441. BS->shift-=8;
  2442. BS->buff[BS->buffp++]=(unsigned char)(BS->OutBuff>>BS->shift);
  2443. }
  2444. stat=sc_BSPutData(BS);
  2445. if (BS->shift>0) /* still some bytes left */
  2446. {
  2447. while (BS->shift>0 && BS->buffp<BS->bufftop)
  2448. {
  2449. BS->shift-=8;
  2450. BS->buff[BS->buffp++]=(unsigned char)(BS->OutBuff>>BS->shift);
  2451. }
  2452. stat=sc_BSPutData(BS);
  2453. }
  2454. }
  2455. else
  2456. stat=sc_BSPutData(BS);
  2457. }
  2458. ScBSReset(BS); /* release and re-initialize buffer pointers */
  2459. _SlibDebug(_VERBOSE_, printf("ScBSFlush() Out\n") );
  2460. return(stat);
  2461. }
  2462. /*
  2463. ** Name: ScBSResetCounters()
  2464. ** Purpose: Resets the bit position counters to zero
  2465. */
  2466. ScStatus_t ScBSResetCounters(ScBitstream_t *BS)
  2467. {
  2468. if (!BS)
  2469. return(ScErrorBadPointer);
  2470. BS->CurrentBit=0;
  2471. return(NoErrors);
  2472. }
  2473. /*
  2474. ** Name: ScBSFlushSoon()
  2475. ** Purpose: Flushes data from the buffers at the next
  2476. ** 32 or 64 bit boundary
  2477. */
  2478. ScStatus_t ScBSFlushSoon(ScBitstream_t *BS)
  2479. {
  2480. ScStatus_t stat=NoErrors;
  2481. _SlibDebug(_VERBOSE_, printf("ScBSFlushSoon()\n") );
  2482. if (!BS)
  2483. return(ScErrorBadPointer);
  2484. if (BS->Mode=='w' || BS->Mode=='b')
  2485. BS->Flush=TRUE;
  2486. return(stat);
  2487. }
  2488. /*
  2489. ** Name: ScBSDestroy()
  2490. ** Purpose: Destroys a bitstream (Closes and frees associated memory)
  2491. ** created using ScBSCreateFromBufferQueue() or
  2492. ** ScBSCreateFromFile()
  2493. */
  2494. ScStatus_t ScBSDestroy(ScBitstream_t *BS)
  2495. {
  2496. ScStatus_t stat=NoErrors;
  2497. _SlibDebug(_VERBOSE_, printf("ScBSDestroy\n") );
  2498. if (!BS)
  2499. return(ScErrorBadPointer);
  2500. /* We won't flush automatically
  2501. if (BS->Mode=='w' || BS->Mode=='b')
  2502. ScBSFlush(BS);
  2503. */
  2504. if (BS->RdBufAllocated)
  2505. ScFree(BS->RdBuf);
  2506. ScFree(BS);
  2507. return(stat);
  2508. }
  2509. /*********************** Buffer/Image Queue Management ***********************/
  2510. /* */
  2511. /* ScBufQueueCreate() - Create a buffer queue */
  2512. /* ScBufQueueDestroy() - Destroy a buffer queue */
  2513. /* ScBufQueueAdd() - Add a buffer to tail of a queue */
  2514. /* ScBufQueueRemove() - Remove the buffer at the head of a queue */
  2515. /* ScBufQueueGetNum() - Return number of buffers in a queue */
  2516. /* ScBufQueueGetHead() - Return info about buffer at head of a queue */
  2517. /* */
  2518. /*****************************************************************************/
  2519. ScStatus_t ScBufQueueCreate(ScQueue_t **Q)
  2520. {
  2521. if ((*Q = (ScQueue_t *)ScAlloc(sizeof(ScQueue_t))) == NULL)
  2522. return(ScErrorMemory);
  2523. (*Q)->NumBufs = 0;
  2524. (*Q)->head = (*Q)->tail = NULL;
  2525. _SlibDebug(_QUEUE_, printf("ScBufQueueCreate() Q=%p\n",*Q) );
  2526. return(NoErrors);
  2527. }
  2528. ScStatus_t ScBufQueueDestroy(ScQueue_t *Q)
  2529. {
  2530. _SlibDebug(_QUEUE_, printf("ScBufQueueDestroy(Q=%p)\n",Q) );
  2531. if (!Q)
  2532. return(ScErrorBadArgument);
  2533. _SlibDebug(_QUEUE_, printf("ScBufQueueDestroy()\n") );
  2534. while (ScBufQueueGetNum(Q))
  2535. ScBufQueueRemove(Q);
  2536. ScFree(Q);
  2537. return(NoErrors);
  2538. }
  2539. ScStatus_t ScBufQueueAdd(ScQueue_t *Q, u_char *Data, int Size)
  2540. {
  2541. struct ScBuf_s *b;
  2542. if (!Q)
  2543. return(ScErrorBadPointer);
  2544. if ((b = (struct ScBuf_s *)ScAlloc(sizeof(struct ScBuf_s))) == NULL)
  2545. return(ScErrorMemory);
  2546. _SlibDebug(_QUEUE_, printf("ScBufQueueAdd(Q=%p, Data=0x%p, Size=%d)\n",
  2547. Q,Data,Size) );
  2548. b->Data = Data;
  2549. b->Size = Size;
  2550. b->Prev = NULL;
  2551. if (!Q->tail)
  2552. Q->tail = Q->head = b;
  2553. else {
  2554. Q->tail->Prev = b;
  2555. Q->tail = b;
  2556. }
  2557. Q->NumBufs++;
  2558. return(NoErrors);
  2559. }
  2560. ScStatus_t ScBufQueueAddExt(ScQueue_t *Q, u_char *Data, int Size, int Type)
  2561. {
  2562. struct ScBuf_s *b;
  2563. if (!Q)
  2564. return(ScErrorBadPointer);
  2565. if ((b = (struct ScBuf_s *)ScAlloc(sizeof(struct ScBuf_s))) == NULL)
  2566. return(ScErrorMemory);
  2567. _SlibDebug(_QUEUE_, printf("ScBufQueueAdd(Q=%p, Data=0x%p, Size=%d)\n",
  2568. Q,Data,Size) );
  2569. b->Data = Data;
  2570. b->Size = Size;
  2571. b->Type = Type;
  2572. b->Prev = NULL;
  2573. if (!Q->tail)
  2574. Q->tail = Q->head = b;
  2575. else {
  2576. Q->tail->Prev = b;
  2577. Q->tail = b;
  2578. }
  2579. Q->NumBufs++;
  2580. return(NoErrors);
  2581. }
  2582. ScStatus_t ScBufQueueRemove(ScQueue_t *Q)
  2583. {
  2584. struct ScBuf_s *head;
  2585. _SlibDebug(_QUEUE_, printf("ScBufQueueRemove(Q=%p)\n",Q) );
  2586. if (!Q)
  2587. return(ScErrorBadPointer);
  2588. if (!(head = Q->head))
  2589. return(ScErrorBadQueueEmpty);
  2590. _SlibDebug(_QUEUE_, printf("ScBufQueueRemove() Data=%p Size=%d\n",
  2591. Q->head->Data,Q->head->Size) );
  2592. Q->head = head->Prev;
  2593. if (!Q->head)
  2594. Q->tail = NULL;
  2595. Q->NumBufs--;
  2596. ScFree(head);
  2597. return(NoErrors);
  2598. }
  2599. int ScBufQueueGetNum(ScQueue_t *Q)
  2600. {
  2601. _SlibDebug(_QUEUE_, printf("ScBufQueueGetNum(Q=%p) num=%d\n",
  2602. Q, Q ? Q->NumBufs : 0) );
  2603. return(Q ? Q->NumBufs : 0);
  2604. }
  2605. ScStatus_t ScBufQueueGetHead(ScQueue_t *Q, u_char **Data, int *Size)
  2606. {
  2607. if (!Q || !Q->head) {
  2608. if (Data) *Data = NULL;
  2609. if (Size) *Size = 0;
  2610. return(NoErrors);
  2611. }
  2612. _SlibDebug(_QUEUE_, printf("ScBufQueueGetHead() Data=%p Size=%d\n",
  2613. Q->head->Data,Q->head->Size) );
  2614. if (Data) *Data = Q->head->Data;
  2615. if (Size) *Size = Q->head->Size;
  2616. return(NoErrors);
  2617. }
  2618. ScStatus_t ScBufQueueGetHeadExt(ScQueue_t *Q, u_char **Data, int *Size,
  2619. int *Type)
  2620. {
  2621. if (!Q || !Q->head) {
  2622. if (Data) *Data = NULL;
  2623. if (Size) *Size = 0;
  2624. if (Type) *Type = 0;
  2625. return(NoErrors);
  2626. }
  2627. _SlibDebug(_QUEUE_, printf("ScBufQueueGetHeadExt() Data=%p Size=%d Type=%d\n",
  2628. Q->head->Data,Q->head->Size,Q->head->Type) );
  2629. if (Data) *Data = Q->head->Data;
  2630. if (Size) *Size = Q->head->Size;
  2631. if (Type) *Type = Q->head->Type;
  2632. return(NoErrors);
  2633. }