@@ -70,21 +70,15 @@ void GolBmpFile::VTable0x00()
7070 LegoU32 i;
7171 LegoU32 bpp = 0 ;
7272 LegoU32 compression = 0 ;
73+ LegoU8* paletteBuffer;
7374 LegoS32 result = m_file.BufferedRead (0 , header, sizeof (header), &amountRead);
7475 if (result != GolStream::e_ioSuccess) {
7576 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
7677 }
7778 if (BUF_U16LE (header, 0 ) != TWOCC (' B' , ' M' )) {
7879 bpp = header[0 ] & 0x3c ;
79- switch (bpp) {
80- default :
80+ if (bpp != 4 && bpp != 8 && bpp != 24 && bpp != 32 ) {
8181 GOL_FATALERROR_MESSAGE (" Invalid BMP file" );
82- break ;
83- case 4 :
84- case 8 :
85- case 24 :
86- case 32 :
87- break ;
8882 }
8983 if (bpp > 8 || (header[0x0 ] & 0x80 )) {
9084 m_paletteSize = 0 ;
@@ -96,36 +90,35 @@ void GolBmpFile::VTable0x00()
9690 m_width = BUF_U16LE (header, 0x2 );
9791 m_height = BUF_U16LE (header, 0x4 );
9892 if (bpp <= 8 ) {
99- LegoU8* paletteBuffer;
100- LegoU32 paletteByteSize = 3 * m_paletteSize;
101- if (paletteByteSize > sizeof (m_unk0x5f0)) {
102- paletteBuffer = new LegoU8[paletteByteSize];
93+ if (3 * m_paletteSize > sizeof (m_unk0x5f0)) {
94+ paletteBuffer = new LegoU8[3 * m_paletteSize];
10395 }
10496 else {
10597 paletteBuffer = m_unk0x5f0;
10698 }
10799 if (paletteBuffer == NULL ) {
108100 GOL_FATALERROR (c_golErrorOutOfMemory);
109101 }
110- result = m_file.BufferedRead (6 , paletteBuffer, paletteByteSize , &amountRead);
102+ result = m_file.BufferedRead (6 , paletteBuffer, 3 * m_paletteSize , &amountRead);
111103 if (result != GolStream::e_ioSuccess) {
112104 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
113105 }
114- imageOffset += paletteByteSize ;
106+ imageOffset += 3 * m_paletteSize ;
115107 LegoU8* palettePtr;
116- for (palettePtr = paletteBuffer, i = 0 ; i < m_paletteSize; i++, palettePtr += 3 ) {
117- m_palette[i].m_blu = palettePtr[0 ];
118- m_palette[i].m_grn = palettePtr[1 ];
119- m_palette[i].m_red = palettePtr[2 ];
120- m_palette[i].m_alp = 0xff ;
108+ ColorRGBA* paletteColor;
109+ for (palettePtr = paletteBuffer, paletteColor = m_palette, i = 0 ; i < m_paletteSize; i++, paletteColor++) {
110+ paletteColor->m_blu = *palettePtr++;
111+ paletteColor->m_grn = *palettePtr++;
112+ paletteColor->m_red = *palettePtr++;
113+ paletteColor->m_alp = 0xff ;
121114 }
122115 if (paletteBuffer != m_unk0x5f0) {
123116 delete[] paletteBuffer;
124117 }
125118 }
126119 m_bitmapOffset = imageOffset;
127120 m_unk0xed4 = 0x80 ;
128- m_rowByteStride = (m_height * bpp + 31 ) >> 3 ;
121+ m_rowByteStride = ((m_width * bpp + 31 ) >> 3 ) & 0x1ffffffc ;
129122 m_imageByteSize = m_rowByteStride * m_height;
130123 }
131124 else {
@@ -135,9 +128,9 @@ void GolBmpFile::VTable0x00()
135128 if (result != GolStream::e_ioSuccess) {
136129 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
137130 }
138- LegoU32 header2Size = BUF_U32LE (header2, 0 );
139- LegoU32 dataOffset = 0xe + header2Size ;
140- if (header2Size == 0xc ) {
131+ result = BUF_U32LE (header2, 0 );
132+ LegoU32 dataOffset = 0xe + result ;
133+ if (result == 0xc ) {
141134 m_width = BUF_U16LE (header2, 0x4 ); // bcWidth
142135 m_height = BUF_U16LE (header2, 0x6 ); // bcHeight
143136 bpp = BUF_U16LE (header2, 0xa );
@@ -147,27 +140,27 @@ void GolBmpFile::VTable0x00()
147140 if (m_paletteSize > 256 ) {
148141 GOL_FATALERROR_MESSAGE (" Palettes larger than 256 colors not supported" );
149142 }
150- LegoU32 paletteByteSize = 3 * m_paletteSize;
151- LegoU8* paletteBuffer;
152- if (paletteByteSize > sizeof (m_unk0x5f0)) {
153- paletteBuffer = new LegoU8[paletteByteSize];
143+ if (3 * m_paletteSize > sizeof (m_unk0x5f0)) {
144+ paletteBuffer = new LegoU8[3 * m_paletteSize];
154145 }
155146 else {
156147 paletteBuffer = m_unk0x5f0;
157148 }
158149 if (paletteBuffer == NULL ) {
159150 GOL_FATALERROR (c_golErrorOutOfMemory);
160151 }
161- result = m_file.BufferedRead (dataOffset, paletteBuffer, paletteByteSize , &amountRead);
152+ result = m_file.BufferedRead (dataOffset, paletteBuffer, 3 * m_paletteSize , &amountRead);
162153 if (result != GolStream::e_ioSuccess) {
163154 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
164155 }
165156 LegoU8* palettePtr;
166- for (palettePtr = paletteBuffer, i = 0 ; i < m_paletteSize; i++, palettePtr += 3 ) {
167- m_palette[i].m_blu = palettePtr[0 ];
168- m_palette[i].m_grn = palettePtr[1 ];
169- m_palette[i].m_red = palettePtr[2 ];
170- m_palette[i].m_alp = 0xff ;
157+ ColorRGBA* paletteColor;
158+ for (palettePtr = paletteBuffer, paletteColor = m_palette, i = 0 ; i < m_paletteSize;
159+ i++, paletteColor++) {
160+ paletteColor->m_blu = *palettePtr++;
161+ paletteColor->m_grn = *palettePtr++;
162+ paletteColor->m_red = *palettePtr++;
163+ paletteColor->m_alp = 0xff ;
171164 }
172165 if (paletteBuffer != m_unk0x5f0) {
173166 delete[] paletteBuffer;
@@ -176,10 +169,10 @@ void GolBmpFile::VTable0x00()
176169 ::memset (&m_palette[m_paletteSize], 0 , sizeof (ColorRGBA) * (256 - m_paletteSize));
177170 }
178171 }
179- m_rowByteStride = (m_width * bpp + 31 ) >> 3 ;
172+ m_rowByteStride = (( m_width * bpp + 31 ) >> 3 ) & 0x1ffffffc ;
180173 m_imageByteSize = m_height * m_rowByteStride;
181174 }
182- else if (header2Size == 0x28 ) {
175+ else if (result == 0x28 ) {
183176 m_width = BUF_U32LE (header2, 0x4 ); // biWidth
184177 m_height = BUF_U32LE (header2, 0x8 ); // biHeight
185178 bpp = BUF_U16LE (header2, 0xe ); // biBitCount
@@ -190,10 +183,8 @@ void GolBmpFile::VTable0x00()
190183 if (m_paletteSize == 0 ) {
191184 m_paletteSize = 1 << (header2[0xc ] * bpp); // biPlanes
192185 }
193- LegoU32 paletteByteSize = m_paletteSize * 4 ;
194- LegoU8* paletteBuffer;
195- if (paletteByteSize > sizeof (m_unk0x5f0)) {
196- paletteBuffer = new LegoU8[paletteByteSize];
186+ if (m_paletteSize * 4 > sizeof (m_unk0x5f0)) {
187+ paletteBuffer = new LegoU8[m_paletteSize * 4 ];
197188 }
198189 else {
199190 paletteBuffer = m_unk0x5f0;
@@ -206,11 +197,14 @@ void GolBmpFile::VTable0x00()
206197 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
207198 }
208199 LegoU8* palettePtr;
209- for (palettePtr = paletteBuffer, i = 0 ; i < m_paletteSize; i++, palettePtr += 4 ) {
210- m_palette[i].m_blu = palettePtr[0 ];
211- m_palette[i].m_grn = palettePtr[1 ];
212- m_palette[i].m_red = palettePtr[2 ];
213- m_palette[i].m_alp = 0xff ;
200+ ColorRGBA* paletteColor;
201+ for (palettePtr = paletteBuffer, paletteColor = m_palette, i = 0 ; i < m_paletteSize;
202+ i++, paletteColor++) {
203+ paletteColor->m_blu = *palettePtr++;
204+ paletteColor->m_grn = *palettePtr++;
205+ paletteColor->m_red = *palettePtr++;
206+ palettePtr++;
207+ paletteColor->m_alp = 0xff ;
214208 }
215209 if (paletteBuffer != m_unk0x5f0) {
216210 delete[] paletteBuffer;
@@ -219,9 +213,9 @@ void GolBmpFile::VTable0x00()
219213 ::memset (m_palette + m_paletteSize, 0 , sizeof (ColorRGBA) * (256 - m_paletteSize));
220214 }
221215 }
222- m_rowByteStride = (m_width * bpp + 31 ) >> 3 ;
216+ m_rowByteStride = (( m_width * bpp + 31 ) >> 3 ) & 0x1ffffffc ;
223217 }
224- else if (header2Size == 0x40 ) {
218+ else if (result == 0x40 ) {
225219 m_width = BUF_U32LE (header2, 0x4 );
226220 m_height = BUF_U32LE (header2, 0x8 );
227221 bpp = BUF_U16LE (header2, 0xe );
@@ -232,28 +226,28 @@ void GolBmpFile::VTable0x00()
232226 if (m_paletteSize == 0 ) {
233227 m_paletteSize = 1 << (header2[0xc ] * bpp);
234228 }
235- LegoU32 paletteByteSize = 3 * m_paletteSize;
236- LegoU8* paletteBuffer;
237- if (paletteByteSize > sizeof (m_unk0x5f0)) {
238- paletteBuffer = new LegoU8[paletteByteSize];
229+ if (3 * m_paletteSize > sizeof (m_unk0x5f0)) {
230+ paletteBuffer = new LegoU8[3 * m_paletteSize];
239231 }
240232 else {
241233 paletteBuffer = m_unk0x5f0;
242234 }
243235 if (paletteBuffer == NULL ) {
244236 GOL_FATALERROR (c_golErrorOutOfMemory);
245237 }
246- // BUG: buffer might be too small (3 vs 4)
247238 result = m_file.BufferedRead (dataOffset, paletteBuffer, 4 * m_paletteSize, &amountRead);
248239 if (result != GolStream::e_ioSuccess) {
249240 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
250241 }
251242 LegoU8* palettePtr;
252- for (palettePtr = paletteBuffer, i = 0 ; i < m_paletteSize; i++, palettePtr += 4 ) {
253- m_palette[i].m_blu = palettePtr[0 ];
254- m_palette[i].m_grn = palettePtr[1 ];
255- m_palette[i].m_red = palettePtr[2 ];
256- m_palette[i].m_alp = 0xff ;
243+ ColorRGBA* paletteColor;
244+ for (palettePtr = paletteBuffer, paletteColor = m_palette, i = 0 ; i < m_paletteSize;
245+ i++, paletteColor++) {
246+ paletteColor->m_blu = *palettePtr++;
247+ paletteColor->m_grn = *palettePtr++;
248+ paletteColor->m_red = *palettePtr++;
249+ palettePtr++;
250+ paletteColor->m_alp = 0xff ;
257251 }
258252 if (paletteBuffer != m_unk0x5f0) {
259253 delete[] paletteBuffer;
@@ -262,7 +256,7 @@ void GolBmpFile::VTable0x00()
262256 ::memset (m_palette + m_paletteSize, 0 , sizeof (ColorRGBA) * (256 - m_paletteSize));
263257 }
264258 }
265- m_rowByteStride = (m_width * bpp + 31 ) >> 3 ;
259+ m_rowByteStride = (( m_width * bpp + 31 ) >> 3 ) & 0x1ffffffc ;
266260 }
267261 m_unk0xed4 = compression;
268262 if (m_unk0xed4 != 0 ) {
@@ -389,8 +383,8 @@ void GolBmpFile::VTable0x18(LegoU8* p_buffer)
389383 GOL_FATALERROR_MESSAGE (GolStream::ErrorCodeToString (result));
390384 }
391385 fileOffset += 4 ;
392- LegoU32 decompressedSize = BUF_U16LE ( m_unk0x8f0, 0 );
393- LegoU32 compressedSize = BUF_U16LE ( m_unk0x8f0, 2 );
386+ LegoU32 decompressedSize = static_cast <LegoU16>(( m_unk0x8f0[ 0 ] << 0 ) | (m_unk0x8f0[ 1 ] << 8 ) );
387+ LegoU32 compressedSize = static_cast <LegoU16>(( m_unk0x8f0[ 2 ] << 0 ) | (m_unk0x8f0[ 3 ] << 8 ) );
394388 if (compressedSize < decompressedSize) {
395389 result = m_file.BufferedRead (
396390 fileOffset,
0 commit comments