home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1997 June / PC_Shareware-1997-06.iso / manga / mp2win95 / _setup.1 / IBITSTR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-31  |  9.6 KB  |  355 lines

  1. /*
  2.  *  @(#) ibitstream.cc 1.8, last edit: 6/15/94 16:51:45
  3.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  4.  *  @(#) Berlin University of Technology
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  *  Changes from version 1.1 to 1.2:
  23.  *    - third argument in open syscall added
  24.  *    - minor bug in get_header() fixed
  25.  */
  26.  
  27. /* Modified for Windows file handles by Jeff Tsay. Last edit 1/26/96. */
  28.  
  29. /* Added syncword detection for compatibility with streams produced by
  30.    DALET. Changed at the request of Wilfried Solbach, thanks for the
  31.    donation in advance! However Layer I MPP files playback jerkily.
  32.    Last edit : 11/29/96. */
  33.  
  34. /* Added a routine to read layer III side info. Also not mentioned
  35.    previously are several routines that allow seeking in a stream.
  36.    Last edit : 01/31/97. */
  37.  
  38. #define STRICT
  39. #define WIN32_LEAN_AND_MEAN
  40. #define NOMCX
  41. #define NOIME
  42. // #define NOGDI
  43. // #define NOUSER
  44. #define NOSOUND
  45. #define NOCOMM
  46. #define NODRIVERS
  47. #define OEMRESOURCE
  48. #define NONLS
  49. #define NOSERVICE
  50. #define NOKANJI
  51. #define NOMINMAX
  52. #define NOLOGERROR
  53. #define NOPROFILER
  54. #define NOMEMMGR
  55. #define NOLFILEIO
  56. #define NOOPENFILE
  57. #define NORESOURCE
  58. #define NOATOM
  59. #define NOLANGUAGE
  60. #define NOLSTRING
  61. #define NODBCS
  62. #define NOKEYBOARDINFO
  63. #define NOGDICAPMASKS
  64. #define NOCOLOR
  65. #define NOGDIOBJ
  66. #define NODRAWTEXT
  67. #define NOTEXTMETRIC
  68. #define NOSCALABLEFONT
  69. #define NOBITMAP
  70. #define NORASTEROPS
  71. #define NOMETAFILE
  72. #define NOSYSMETRICS
  73. #define NOSYSTEMPARAMSINFO
  74. #define NOMSG
  75. #define NOWINSTYLES
  76. #define NOWINOFFSETS
  77. #define NOSHOWWINDOW
  78. #define NODEFERWINDOWPOS
  79. #define NOVIRTUALKEYCODES
  80. #define NOKEYSTATES
  81. #define NOWH
  82. #define NOMENUS
  83. #define NOSCROLL
  84. #define NOCLIPBOARD
  85. #define NOICONS
  86. // #define NOMB
  87. #define NOSYSCOMMANDS
  88. #define NOMDI
  89. #define NOCTLMGR
  90. #define NOWINMESSAGES
  91. #define NOHELP
  92. // #define _WINUSER_
  93. #define __oleidl_h__
  94. #define _OLE2_H_
  95. #include <windows.h>
  96.  
  97. #include "all.h"
  98. #include "ibitstr.h"
  99. #include "header.h"
  100. #include "l3type.h"
  101.  
  102. #define swap_int32(int_32) (((int_32) << 24) | (((int_32) << 8) & 0x00ff0000) | \
  103.                 (((int_32) >> 8) & 0x0000ff00) | ((int_32) >> 24))
  104.  
  105. Ibitstream::Ibitstream (const char *filename, HWND hWnd0)        // constructor
  106. {
  107.  
  108.   char bad_file_msg[256];
  109.   hWnd=hWnd0;
  110.  
  111.   security.nLength=sizeof(SECURITY_ATTRIBUTES);
  112.   security.lpSecurityDescriptor=NULL;
  113.   security.bInheritHandle=FALSE;
  114.  
  115.   FH=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
  116.                      &security, OPEN_EXISTING, NULL, NULL);
  117.  
  118.   if (FH==INVALID_HANDLE_VALUE) {
  119.     lstrcpy(bad_file_msg, "Error opening file: ");
  120.     MessageBox(hWnd, strcat(bad_file_msg, filename) , "Invalid handle", MB_OK);
  121.   }
  122.  
  123.   wordpointer = buffer;
  124.   bitindex = 0;
  125.  
  126.   // Seeking variables
  127.   offset = NULL;
  128.   current_frame = -1;
  129.   last_frame_number = -1;
  130. }
  131.  
  132. Ibitstream::~Ibitstream (void)                // destructor
  133. {
  134.   delete [] offset;
  135.   CloseHandle(FH);
  136. }
  137.  
  138. BOOL Ibitstream::get_header (uint32 *headerstring)
  139. {
  140.   BOOL result, sync;
  141.   DWORD numread;
  142.  
  143.   do {
  144.  
  145.    // This part assumes idiotic Intel byte order
  146.    result=(BOOL) ReadFile(FH, (char*)headerstring, 4, &numread, NULL);
  147.  
  148.    if (!(result && (numread==4)))
  149.       return (FALSE);
  150.  
  151.    sync = ((*headerstring & 0xF8FF) == 0xF8FF);
  152.  
  153.    if (!sync)
  154.       result = (BOOL) SetFilePointer(FH, -3, NULL, FILE_CURRENT);
  155.  
  156.   } while (!sync && result);
  157.  
  158.   if (!result)
  159.      return (FALSE);
  160.  
  161.   register uint32 header = *headerstring;
  162.   *headerstring = swap_int32 (header);
  163.  
  164.   if (last_frame_number < ++current_frame)
  165.     last_frame_number = current_frame;
  166.  
  167.   return (TRUE);
  168. }
  169.  
  170. BOOL Ibitstream::read_frame (uint32 bytesize)
  171. {
  172.  
  173.     DWORD numread;
  174.     BOOL result=ReadFile(FH, buffer, bytesize, &numread, NULL);
  175.  
  176. /*  if (bytesize > (bufferintsize << 2))
  177.   {
  178.      cerr << "Internal error: framelength > bufferlength?!\n";
  179.      exit (1);
  180.   } */
  181.  
  182.   wordpointer = buffer;
  183.   bitindex = 0;
  184.   framesize = bytesize;
  185. // #ifdef DAMN_INTEL_BYTE_ORDER
  186.   register uint32 *wordp, word;
  187.   for (wordp = buffer + ((bytesize - 1) >> 2); wordp >= buffer; --wordp)
  188.   {
  189.      word = *wordp;
  190.      *wordp = swap_int32 (word);
  191.   }
  192. // #endif
  193.  
  194.   return ((BOOL) (result && (numread==framesize)));
  195. }
  196.  
  197. uint32 Ibitstream::get_bits (uint32 number_of_bits)
  198. {
  199.   static uint32 bitmask[17] =
  200.   {
  201.      0,    // dummy
  202.      0x00000001, 0x00000003, 0x00000007, 0x0000000F,
  203.      0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
  204.      0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
  205.      0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF
  206.   };
  207.   uint32 returnvalue;
  208.   uint32 sum = bitindex + number_of_bits;
  209.  
  210.   if (sum <= 32)
  211.   {
  212.      // all bits contained in *wordpointer
  213.      returnvalue = (*wordpointer >> (32 - sum)) & bitmask[number_of_bits];
  214.      if ((bitindex += number_of_bits) == 32)
  215.      {
  216.         bitindex = 0;
  217.  
  218. /*        if ((char *)++wordpointer > (char *)buffer + framesize)
  219.         {
  220.     cerr << "Ibitstream::get_bits(): no more bits in buffer!\n";
  221.     exit (1);
  222.         } */
  223.         wordpointer++; // added by me!
  224.      }
  225.      return returnvalue;
  226.   }
  227.  
  228.   *((int16 *)&returnvalue + 1) = *(int16 *)wordpointer;
  229.  
  230.   wordpointer++; // Added by me!
  231.   *(int16 *)&returnvalue = *((int16 *)wordpointer + 1);
  232.  
  233.   returnvalue >>= 48 - sum;    // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
  234.   returnvalue &= bitmask[number_of_bits];
  235.   bitindex = sum - 32;
  236.   return returnvalue;
  237. }
  238.  
  239.  
  240. BOOL Ibitstream::get_side_info(uint32 channels,
  241.                                          III_side_info_t *side_info)
  242. // Reads the side info from the stream, assuming the entire
  243. // frame has been read already. Adopted from the public c code.
  244.  
  245. // Mono   : 136 bits (= 17 bytes)
  246. // Stereo : 256 bits (= 32 bytes)
  247.  
  248. {
  249.     int ch, gr;
  250.  
  251.     side_info->main_data_begin = get_bits(9);
  252.     if (channels == 1)
  253.         side_info->private_bits = get_bits(5);
  254.     else side_info->private_bits = get_bits(3);
  255.  
  256.     for (ch=0; ch<channels; ch++) {
  257.         side_info->ch[ch].scfsi[0] = get_bits(1);
  258.         side_info->ch[ch].scfsi[1] = get_bits(1);
  259.         side_info->ch[ch].scfsi[2] = get_bits(1);
  260.         side_info->ch[ch].scfsi[3] = get_bits(1);
  261.    }
  262.  
  263.     for (gr=0; gr<2; gr++) {
  264.         for (ch=0; ch<channels; ch++) {
  265.             side_info->ch[ch].gr[gr].part2_3_length = get_bits(12);
  266.             side_info->ch[ch].gr[gr].big_values = get_bits(9);
  267.             side_info->ch[ch].gr[gr].global_gain = get_bits(8);
  268.             side_info->ch[ch].gr[gr].scalefac_compress = get_bits(4);
  269.             side_info->ch[ch].gr[gr].window_switching_flag = get_bits(1);
  270.             if (side_info->ch[ch].gr[gr].window_switching_flag) {
  271.                 side_info->ch[ch].gr[gr].block_type = get_bits(2);
  272.                 side_info->ch[ch].gr[gr].mixed_block_flag = get_bits(1);
  273.  
  274.                 side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);
  275.                 side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);
  276.  
  277.                 side_info->ch[ch].gr[gr].subblock_gain[0] = get_bits(3);
  278.                 side_info->ch[ch].gr[gr].subblock_gain[1] = get_bits(3);
  279.                 side_info->ch[ch].gr[gr].subblock_gain[2] = get_bits(3);
  280.  
  281.                 /* Set region_count parameters since they are implicit in this case. */
  282.  
  283.                 if (side_info->ch[ch].gr[gr].block_type == 0) {
  284. /*                    printf("Side info bad: block_type == 0 in split block.\n");
  285.                     exit(0); */
  286.                     return(FALSE);
  287.                 } else if (side_info->ch[ch].gr[gr].block_type == 2
  288.                             && side_info->ch[ch].gr[gr].mixed_block_flag == 0)
  289.                     side_info->ch[ch].gr[gr].region0_count = 8; /* MI 9; */
  290.                 else side_info->ch[ch].gr[gr].region0_count = 7; /* MI 8; */
  291.                 side_info->ch[ch].gr[gr].region1_count = 20 -
  292.                         side_info->ch[ch].gr[gr].region0_count;
  293.                 }
  294.             else {
  295.  
  296.                 side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);
  297.                 side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);
  298.                 side_info->ch[ch].gr[gr].table_select[2] = get_bits(5);
  299.                 side_info->ch[ch].gr[gr].region0_count = get_bits(4);
  300.                 side_info->ch[ch].gr[gr].region1_count = get_bits(3);
  301.                 side_info->ch[ch].gr[gr].block_type = 0;
  302.                 }
  303.             side_info->ch[ch].gr[gr].preflag = get_bits(1);
  304.             side_info->ch[ch].gr[gr].scalefac_scale = get_bits(1);
  305.             side_info->ch[ch].gr[gr].count1table_select = get_bits(1);
  306.             }
  307.         }
  308.         return(TRUE);
  309. }
  310.  
  311. DWORD Ibitstream::file_size()
  312. {
  313.     return (GetFileSize(FH, NULL));
  314. }
  315.  
  316. DWORD Ibitstream::seek(int32 frame, int32 frame_size)
  317. {
  318.     current_frame = frame - 1;
  319.     return (SetFilePointer(FH, frame * (frame_size + 4), NULL, FILE_BEGIN));
  320. }
  321.  
  322. DWORD Ibitstream::seek_pad(int32 frame, int32 base_frame_size)
  323. {
  324.     // base_frame_size is the frame size _without_ padding.
  325.  
  326.     Header header;
  327.     Crc16 *crc;
  328.  
  329.     int32 total_frame_size = base_frame_size + 4;
  330.     int32 diff;
  331.  
  332.     if (last_frame_number < frame - 1) {
  333.         diff = (last_frame_number >= 0) ?  offset[last_frame_number] : 0;
  334.         SetFilePointer(FH, (last_frame_number + 1) * total_frame_size +
  335.                             diff, NULL, FILE_BEGIN);
  336.  
  337.         current_frame = last_frame_number;
  338.  
  339.         do {
  340.             if (!header.read_header(this, &crc)) // will increment last_frame_number
  341.                 return(0L);
  342.         } while (last_frame_number < frame -1);
  343.  
  344.  
  345.     } else {
  346.         diff = (frame > 0) ? offset[frame - 1] : 0;
  347.         SetFilePointer(FH, frame * total_frame_size + diff, NULL, FILE_BEGIN);
  348.         current_frame = frame - 1;
  349.     }
  350.  
  351.     return (1L);
  352. }
  353.  
  354.  
  355.