pcx.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/Library/PCX.cpp $*
  25. * *
  26. * $Author:: Greg_h $*
  27. * *
  28. * $Modtime:: 9/28/98 12:06p $*
  29. * *
  30. * $Revision:: 2 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "always.h"
  36. #include "pcx.h"
  37. #include <stdlib.h>
  38. /***************************************************************************
  39. * READ_PCX_FILE -- read a pcx file into a Graphic Buffer *
  40. * *
  41. * GraphicBufferClass* Read_PCX_File (char* name, char* palette,void *Buff, long size ); *
  42. * *
  43. * *
  44. * INPUT: name is a NULL terminated string of the format [xxxx.pcx] *
  45. * palette is optional, if palette != NULL the the color palette of *
  46. * the pcx file will be place in the memory block pointed *
  47. * by palette. *
  48. * Buff is optional, if Buff == NULL a new memory Buffer *
  49. * will be allocated, otherwise the file will be placed *
  50. * at location pointed by Buffer; *
  51. * Size is the size in bytes of the memory block pointed by Buff *
  52. * is also optional; * *
  53. * OUTPUT: on success a pointer to a GraphicBufferClass containing the *
  54. * pcx file, NULL otherwise. *
  55. * *
  56. * WARNINGS: *
  57. * Appears to be a comment-free zone *
  58. * *
  59. * HISTORY: *
  60. * 05/03/1995 JRJ : Created. *
  61. * 04/30/1996 ST : Tidied up and modified to use CCFileClass *
  62. *=========================================================================*/
  63. #define POOL_SIZE 2048
  64. #define READ_CHAR() *file_ptr++ ; \
  65. if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
  66. file_handle.Read (pool, POOL_SIZE ); \
  67. file_ptr = pool ; \
  68. }
  69. #define READ_CHARx() *file_ptr++ ; \
  70. if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
  71. file_handle.Read (pool, POOL_SIZE ); \
  72. }
  73. Surface * Read_PCX_File(FileClass & file_handle, PaletteClass * palette, void * Buff, long Size)
  74. {
  75. unsigned i, j;
  76. unsigned rle;
  77. unsigned color;
  78. unsigned scan_pos;
  79. char *file_ptr;
  80. unsigned width;
  81. unsigned height;
  82. char *buffer;
  83. PCX_HEADER header;
  84. char pool [POOL_SIZE];
  85. BSurface * pic;
  86. if (!file_handle.Is_Available()) return (NULL);
  87. file_handle.Open(FileClass::READ);
  88. file_handle.Read (&header, sizeof (PCX_HEADER));
  89. if (header.id != 10 && header.version != 5 && header.pixelsize != 8 ) return NULL ;
  90. width = header.width - header.x + 1;
  91. height = header.height - header.y + 1;
  92. if (Buff != NULL) {
  93. i = Size / width;
  94. height = MIN ((int)(i - 1), (int)height);
  95. Buffer b(Buff, Size);
  96. pic = new BSurface(width, height, 1, &b);
  97. if (pic == NULL) return NULL ;
  98. } else {
  99. pic = new BSurface(width, height, 1);
  100. if (pic == NULL) return NULL ;
  101. }
  102. buffer = (char *)pic->Lock();
  103. if (buffer != NULL) {
  104. file_ptr = pool ;
  105. file_handle.Read (pool, POOL_SIZE);
  106. if ( header.byte_per_line != width ) {
  107. i = 0;
  108. rle = 0;
  109. for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) {
  110. for ( i = 0 ; i < width ; ) {
  111. rle = READ_CHAR ();
  112. if ( rle > 192 ) {
  113. rle -= 192 ;
  114. color = READ_CHAR (); ;
  115. memset ( buffer + scan_pos + i, color, rle );
  116. i += rle;
  117. } else {
  118. *(buffer+scan_pos + i++ ) = (char)rle;
  119. }
  120. }
  121. }
  122. if ( i == width ) rle = READ_CHAR ();
  123. if ( rle > 192 ) READ_CHARx();
  124. } else {
  125. for ( i = 0 ; i < width * height ; ) {
  126. rle = READ_CHAR ();
  127. rle &= 0xff;
  128. if ( rle > 192 ) {
  129. rle -= 192 ;
  130. color = READ_CHAR ();
  131. memset ( buffer + i, color, rle );
  132. i += rle ;
  133. } else {
  134. *(buffer + i++) = (char)rle;
  135. }
  136. }
  137. }
  138. pic->Unlock();
  139. }
  140. if ( palette ) {
  141. file_handle.Seek (- (256 * (int)sizeof(RGB)), SEEK_END );
  142. file_handle.Read (palette, 256L * sizeof ( RGB ));
  143. }
  144. file_handle.Close();
  145. return pic;
  146. }