LOAD.CPP 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: g:/library/wwlib32/file/rcs/load.cpp 1.4 1994/04/22 12:42:21 scott_bowen Exp $ */
  15. /***************************************************************************
  16. ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  17. ***************************************************************************
  18. * *
  19. * Project Name : LIBRARY *
  20. * *
  21. * File Name : LOAD.C *
  22. * *
  23. * Programmer : Christopher Yates *
  24. * *
  25. * Last Update : September 17, 1993 [JLB] *
  26. * *
  27. *-------------------------------------------------------------------------*
  28. * Functions: *
  29. * Load_Uncompress -- Load and uncompress the given file. *
  30. * Uncompress_Data -- Uncompress standard CPS buffer. *
  31. * Load_Data -- Loads a data file from disk. *
  32. * Load_Alloc_Data -- Loads and allocates buffer for a file. *
  33. * Write_Data -- Writes a block of data as a file to disk. *
  34. * Uncompress_Data -- Uncompresses data from one buffer to another. *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #include "iff.h"
  37. #include "file.h"
  38. #include <misc.h>
  39. #include <wwstd.h>
  40. #include <dos.h>
  41. #include <wwmem.h>
  42. /*=========================================================================*/
  43. /* The following PRIVATE functions are in this file: */
  44. /*=========================================================================*/
  45. /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
  46. /***************************************************************************
  47. * LOAD_DATA -- Loads a data file from disk. *
  48. * *
  49. * This routine will load a data file from disk. It does no translation*
  50. * on the data. *
  51. * *
  52. * INPUT: name -- Pointer to ASCII filename of the data file. *
  53. * *
  54. * ptr -- Buffer to load the data file into. *
  55. * *
  56. * size -- Maximum size of the buffer (in bytes). *
  57. * *
  58. * OUTPUT: Returns with the number of bytes read. *
  59. * *
  60. * WARNINGS: none *
  61. * *
  62. * HISTORY: *
  63. * 06/24/1991 JLB : Created. *
  64. *=========================================================================*/
  65. unsigned long __cdecl Load_Data(char const *name, void *ptr, unsigned long size)
  66. {
  67. int fd;
  68. fd = Open_File(name, READ);
  69. size = Read_File(fd, ptr, size);
  70. Close_File(fd);
  71. return(size);
  72. }
  73. /***************************************************************************
  74. * WRITE_DATA -- Writes a block of data as a file to disk. *
  75. * *
  76. * This routine will write a block of data as a file to the disk. It *
  77. * is the compliment of Load_Data. *
  78. * *
  79. * INPUT: name -- Name of the file to create. *
  80. * *
  81. * ptr -- Pointer to the block of data to write. *
  82. * *
  83. * size -- Size of the data block to be written. *
  84. * *
  85. * OUTPUT: Returns with the number of bytes actually written. *
  86. * *
  87. * WARNINGS: none *
  88. * *
  89. * HISTORY: *
  90. * 07/05/1992 JLB : Created. *
  91. *=========================================================================*/
  92. unsigned long __cdecl Write_Data(char const *name, void *ptr, unsigned long size)
  93. {
  94. int fd;
  95. fd = Open_File(name, WRITE);
  96. size = Write_File(fd, ptr, size);
  97. Close_File(fd);
  98. return(size);
  99. }
  100. /***************************************************************************
  101. * LOAD_ALLOC_DATA -- Loads and allocates buffer for a file. *
  102. * *
  103. * The routine will allocate a buffer and load the specified file into *
  104. * it. The kind of memory used for the buffer is determined by the *
  105. * memory allocation flags passed in. *
  106. * *
  107. * INPUT: name -- Name of the file to load. *
  108. * *
  109. * flags -- Memory allocation flags to use when allocating. *
  110. * *
  111. * OUTPUT: Returns with a pointer to the buffer that contains the file's *
  112. * data. *
  113. * *
  114. * WARNINGS: A memory error could occur if regular memory flags are *
  115. * specified. If XMS memory is specified, then this routine *
  116. * could likely return NULL. *
  117. * *
  118. * HISTORY: *
  119. * 05/28/1992 JLB : Created. *
  120. *=========================================================================*/
  121. void * __cdecl Load_Alloc_Data(char const *name, MemoryFlagType flags)
  122. {
  123. int fd; // Working file handle.
  124. unsigned long size; // Size of the file to load.
  125. void *buffer; // Buffer to hold the file.
  126. fd = Open_File(name, READ);
  127. size = File_Size(fd);
  128. buffer = Alloc(size, flags);
  129. if (buffer) {
  130. Read_File(fd, buffer, size);
  131. }
  132. Close_File(fd);
  133. return(buffer);
  134. }
  135. /***************************************************************************
  136. * LOAD_UNCOMPRESS -- Load and uncompress the given file. *
  137. * *
  138. * INPUT: char * - file name to uncompress *
  139. * GraphicBufferClass& - to load the source data into *
  140. * GraphicBufferClass& - for the picture *
  141. * void * - ptr for header uncompressed data *
  142. * *
  143. * OUTPUT: unsigned long size of uncompressed data *
  144. * *
  145. * WARNINGS: none *
  146. * *
  147. * HISTORY: *
  148. * 05/28/1991 CY : Created. *
  149. * 06/26/1991 JLB : Handles load & uncompress to same buffer. *
  150. *=========================================================================*/
  151. unsigned long __cdecl Load_Uncompress(char const *file, BufferClass& uncomp_buff, BufferClass& dest_buff, void *reserved_data)
  152. {
  153. int fd; // Source file handle.
  154. unsigned int isize=0; // Size of the file.
  155. unsigned int skipsize; // Size of the skip data bytes.
  156. void *uncomp_ptr; // Source buffer pointer.
  157. char *newuncomp_ptr; // Adjusted source pointer.
  158. uncomp_ptr = uncomp_buff.Get_Buffer(); // get a pointer to buffer
  159. /*======================================================================*/
  160. /* Read the file into the uncompression buffer. */
  161. /*======================================================================*/
  162. fd = Open_File(file, READ); // Open up the file to read from
  163. Read_File(fd, (char *) &isize, 2L); // Read the file size
  164. Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in.
  165. isize -= 8; // Remaining data in file.
  166. /*======================================================================*/
  167. /* Check for and read in the skip data block. */
  168. /*======================================================================*/
  169. skipsize = *(((short *)uncomp_ptr) + 3);
  170. if (reserved_data && skipsize) {
  171. Read_File(fd, reserved_data, (unsigned long) skipsize);
  172. } else {
  173. Seek_File(fd, skipsize, SEEK_CUR);
  174. }
  175. *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value.
  176. isize -= skipsize;
  177. /*======================================================================*/
  178. /* If the source and dest buffer are the same, we adjust the pointer so */
  179. /* that the compressed data is loaded into the end of the buffer. In */
  180. /* this way the uncompress code can write to the same buffer. */
  181. /*======================================================================*/
  182. newuncomp_ptr = (char *)Add_Long_To_Pointer(uncomp_buff.Get_Buffer(), uncomp_buff.Get_Size() - (isize+8L));
  183. /*======================================================================*/
  184. /* Duplicate the header bytes. */
  185. /*======================================================================*/
  186. Mem_Copy(uncomp_ptr,newuncomp_ptr,8);
  187. /*======================================================================*/
  188. /* Read in the main compressed part of the file. */
  189. /*======================================================================*/
  190. Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize);
  191. Close_File(fd);
  192. /*======================================================================*/
  193. /* Uncompress the file into the destination buffer (which may very well */
  194. /* be the source buffer). */
  195. /*======================================================================*/
  196. return(Uncompress_Data(newuncomp_ptr, dest_buff.Get_Buffer()));
  197. }
  198. #if(0)
  199. /***************************************************************************
  200. * LOAD_UNCOMPRESS -- Load and uncompress the given file. *
  201. * *
  202. * INPUT: char *file name to uncompress, BuffType uncomp_buff to load *
  203. * the source data into, BuffType dest_buff for the picture, *
  204. * void *reserved_data pointer for header uncompressed data *
  205. * *
  206. * OUTPUT: unsigned long size of uncompressed data *
  207. * *
  208. * WARNINGS: none *
  209. * *
  210. * HISTORY: *
  211. * 05/28/1991 CY : Created. *
  212. * 06/26/1991 JLB : Handles load & uncompress to same buffer. *
  213. *=========================================================================*/
  214. unsigned long __cdecl Load_Uncompress(char const *file, BuffType uncomp_buff, BuffType dest_buff, void *reserved_data)
  215. {
  216. int fd; // Source file handle.
  217. unsigned int isize; // Size of the file.
  218. unsigned int skipsize; // Size of the skip data bytes.
  219. void *uncomp_ptr; // Source buffer pointer.
  220. char *newuncomp_ptr; // Adjusted source pointer.
  221. uncomp_ptr = Get_Buff(uncomp_buff); /* Get pointer to uncomp buffer */
  222. /* Read the file into the uncomp_buff */
  223. fd = Open_File(file, READ);
  224. Read_File(fd, (char *) &isize, 2L); /* Read the file size */
  225. #if(AMIGA)
  226. isize = Reverse_Word(isize);
  227. #endif
  228. Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in.
  229. isize -= 8; // Remaining data in file.
  230. /*
  231. ** Check for and read in the skip data block.
  232. */
  233. skipsize = *(((short*)uncomp_ptr) + 3);
  234. #if(AMIGA)
  235. skipsize = Reverse_Word(skipsize);
  236. #endif
  237. if (reserved_data && skipsize) {
  238. Read_File(fd, reserved_data, (unsigned long) skipsize);
  239. } else {
  240. Seek_File(fd, skipsize, SEEK_CUR);
  241. }
  242. *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value.
  243. isize -= skipsize;
  244. /*
  245. ** If the source and dest buffer are the same, we
  246. ** adjust the pointer so that the compressed data is
  247. ** loaded into the end of the buffer. In this way the
  248. ** uncompress code can write to the same buffer.
  249. */
  250. #if(IBM)
  251. newuncomp_ptr = (char *)Add_Long_To_Pointer(Get_Buff(uncomp_buff), PageArraySize[uncomp_buff] - (isize+8L));
  252. #else
  253. newuncomp_ptr = Get_Buff(uncomp_buff);
  254. newuncomp_ptr += PageArraySize[uncomp_buff] - ((isize+10) & 0xFFFE);
  255. #endif
  256. /*
  257. ** Duplicate the header bytes.
  258. */
  259. Mem_Copy(uncomp_ptr,newuncomp_ptr,8);
  260. /*
  261. ** Read in the main compressed part of the file.
  262. */
  263. Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize);
  264. Close_File(fd);
  265. return(Uncompress_Data(newuncomp_ptr, Get_Buff(dest_buff)));
  266. }
  267. #endif
  268. /***************************************************************************
  269. * Uncompress_Data -- Uncompresses data from one buffer to another. *
  270. * *
  271. * This routine takes data from a compressed file (sans the first two *
  272. * size bytes) and uncompresses it to a destination buffer. The source *
  273. * data MUST have the CompHeaderType at its start. *
  274. * *
  275. * INPUT: src -- Source compressed data pointer. *
  276. * *
  277. * dst -- Destination (paragraph aligned) pointer. *
  278. * *
  279. * OUTPUT: Returns with the size of the uncompressed data. *
  280. * *
  281. * WARNINGS: If LCW compression is used, the destination buffer must *
  282. * be paragraph aligned. *
  283. * *
  284. * HISTORY: *
  285. * 09/17/1993 JLB : Created. *
  286. *=========================================================================*/
  287. unsigned long __cdecl Uncompress_Data(void const *src, void *dst)
  288. {
  289. unsigned int skip; // Number of leading data to skip.
  290. CompressionType method; // Compression method used.
  291. unsigned long uncomp_size=NULL;
  292. if (!src || !dst) return(NULL);
  293. /*
  294. ** Interpret the data block header structure to determine
  295. ** compression method, size, and skip data amount.
  296. */
  297. uncomp_size = ((CompHeaderType*)src)->Size;
  298. #if(AMIGA)
  299. uncomp_size = Reverse_Long(uncomp_size);
  300. #endif
  301. skip = ((CompHeaderType*)src)->Skip;
  302. #if(AMIGA)
  303. skip = Reverse_Word(skip);
  304. #endif
  305. method = (CompressionType) ((CompHeaderType*)src)->Method;
  306. src = Add_Long_To_Pointer((void *)src, (long)sizeof(CompHeaderType) + (long)skip);
  307. switch (method) {
  308. default:
  309. case NOCOMPRESS:
  310. Mem_Copy((void *) src, dst, uncomp_size);
  311. break;
  312. case HORIZONTAL:
  313. #if LIB_EXTERNS_RESOLVED
  314. RLE_Uncompress((void *) src, dst, uncomp_size);
  315. #endif
  316. break;
  317. case LCW:
  318. LCW_Uncompress((void *) src, (void *) dst, (unsigned long) uncomp_size);
  319. break;
  320. }
  321. return(uncomp_size);
  322. }