WRITEPCX.CPP (7427B)
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 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /*************************************************************************** 17 ** 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 ** 18 *************************************************************************** 19 * * 20 * Project Name : iff * 21 * * 22 * File Name : WRITEPCX.CPP * 23 * * 24 * Programmer : Julio R. Jerez * 25 * * 26 * Start Date : May 2, 1995 * 27 * * 28 * Last Update : May 2, 1995 [JRJ] * 29 * * 30 *-------------------------------------------------------------------------* 31 * Functions: * 32 * int Save_PCX_File (char* name, GraphicViewPortClass& pic, char* palette)* 33 *= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ 34 35 #include <wwlib32.h> 36 #include "filepcx.h" 37 #include <wwmem.h> 38 static void Write_Pcx_ScanLine ( int file_handle , int scansize , unsigned char * ptr ); 39 40 41 /*************************************************************************** 42 * WRITE_PCX_FILE -- Write the data in ViewPort to a pcx file * 43 * * 44 * * 45 * * 46 * INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] * 47 * pic is a pointer to a GraphicViewPortClass or to a * 48 * GraphicBufferClass holding the picture. * 49 * palette is a pointer the the memry block holding the color * * 50 * palette of the picture. * 51 * * 52 * OUTPUT: FALSE if the function fails zero otherwise * 53 * * 54 * WARNINGS: * 55 * * 56 * HISTORY: * 57 * 05/04/1995 JRJ : Created. * 58 * 08/01/1995 SKB : Copy the palette so it is not modified. * 59 *=========================================================================*/ 60 int Write_PCX_File (char* name, GraphicViewPortClass& pic, unsigned char* palette ) 61 { 62 unsigned char palcopy[256 * 3]; 63 unsigned i ; 64 //unsigned width ; 65 int file_handle ; 66 int VP_Scan_Line ; 67 char * ptr ; 68 RGB * pal ; 69 GraphicBufferClass * Graphic_Buffer ; 70 PCX_HEADER header = { 10 , 5 , 1 , 8 , 0 , 0 , 319 , 199 , 71 320 , 200 , { 0 } , 0 , 1 , 320 , 1 , {0} } ; 72 73 // Open file name 74 file_handle = Open_File ( name , WRITE ) ; 75 if ( file_handle == WW_ERROR ) return FALSE ; 76 77 78 header.width = pic.Get_Width() - 1 ; 79 header.height = pic.Get_Height() - 1 ; 80 header.byte_per_line = pic.Get_Width() ; 81 Write_File ( file_handle, & header , sizeof (PCX_HEADER)) ; 82 83 VP_Scan_Line = pic.Get_Width() + pic.Get_XAdd(); 84 Graphic_Buffer = pic.Get_Graphic_Buffer() ; 85 ptr = ( char * ) Graphic_Buffer->Get_Buffer() ; 86 ptr += ( (pic.Get_YPos() * VP_Scan_Line) + pic.Get_XPos() ); 87 88 for ( i = 0 ; i < (unsigned)header.height + 1 ; i ++ ) 89 Write_Pcx_ScanLine ( file_handle , header.byte_per_line, (unsigned char*)ptr + i * VP_Scan_Line ) ; 90 91 Mem_Copy(palette, palcopy, 256 * 3); 92 pal = ( RGB * ) palcopy ; 93 for ( i = 0 ; i < 256 ; i ++ ) { 94 pal -> red <<= 2 ; 95 pal -> green <<= 2 ; 96 pal -> blue <<= 2 ; 97 pal ++ ; 98 } 99 i = 0x0c ; 100 Write_File ( file_handle, & i , 1 ) ; 101 Write_File ( file_handle, palcopy , 256 * sizeof (RGB) ) ; 102 Close_File (file_handle) ; 103 return 0 ; 104 } 105 106 107 108 109 /*************************************************************************** 110 * WRITE_PCX_SCANLINE -- function to write a single pcx scanline to a file * 111 * * 112 * * 113 * INPUT: * 114 * * 115 * OUTPUT: * 116 * * 117 * WARNINGS: * 118 * * 119 * HISTORY: * 120 * 05/04/1995 JRJ : Created. * 121 *=========================================================================*/ 122 123 #define POOL_SIZE 2048 124 #define WRITE_CHAR(x) { \ 125 * file_ptr ++ = x ; \ 126 if ( file_ptr >= & pool [ POOL_SIZE ] ) { \ 127 Write_File ( file_handle, pool , POOL_SIZE ) ; \ 128 file_ptr = pool ; \ 129 } } 130 131 132 void Write_Pcx_ScanLine ( int file_handle , int scansize , unsigned char * ptr ) 133 { 134 unsigned i ; 135 unsigned rle ; 136 unsigned color ; 137 unsigned last ; 138 unsigned char * file_ptr ; 139 unsigned char pool [ POOL_SIZE ] ; 140 141 file_ptr = pool ; 142 last = * ptr ; 143 rle = 1 ; 144 145 for ( i = 1 ; i < (unsigned)scansize ; i ++ ) { 146 color = 0xff & * ++ ptr ; 147 if ( color == last ) { 148 rle ++ ; 149 if ( rle == 63 ) { 150 WRITE_CHAR ( 255 ) ; 151 WRITE_CHAR ( color ) ; 152 rle = 0 ; 153 } 154 } else { 155 if ( rle ) { 156 if ( rle == 1 && ( 192 != ( 192 & last ))) { 157 WRITE_CHAR ( last ) ; 158 } else { 159 WRITE_CHAR ( rle | 192 ) ; 160 WRITE_CHAR ( last ) ; 161 } 162 } 163 last = color ; 164 rle = 1 ; 165 } 166 } 167 if ( rle ) { 168 if ( rle == 1 && ( 192 != ( 192 & last ))) { 169 WRITE_CHAR ( last ) ; 170 } else { 171 WRITE_CHAR ( rle | 192 ) ; 172 WRITE_CHAR ( last) ; 173 } 174 } 175 176 Write_File ( file_handle, pool , ( int ) file_ptr - ( int ) pool ) ; 177 }