[Scummvm-git-logs] scummvm master -> 20d6034a0640f18dbeb028aab040576a5d6fe616

npjg noreply at scummvm.org
Sun Jan 12 20:52:32 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
20d6034a06 MEDIASTATION: Refactor bitmap decompression to use stream interface


Commit: 20d6034a0640f18dbeb028aab040576a5d6fe616
    https://github.com/scummvm/scummvm/commit/20d6034a0640f18dbeb028aab040576a5d6fe616
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2025-01-12T15:51:16-05:00

Commit Message:
MEDIASTATION: Refactor bitmap decompression to use stream interface

As well as making sure we explicitly read some bytes
at the end of the compressed image data that were left
un-read before and were causing problems with now reading everything from the stream.

Changed paths:
    engines/mediastation/bitmap.cpp


diff --git a/engines/mediastation/bitmap.cpp b/engines/mediastation/bitmap.cpp
index 8a43ff7232a..66d1836c9b7 100644
--- a/engines/mediastation/bitmap.cpp
+++ b/engines/mediastation/bitmap.cpp
@@ -57,9 +57,12 @@ Bitmap::Bitmap(Chunk &chunk, BitmapHeader *bitmapHeader) :
 	uint8 *pixels = (uint8 *)_surface.getPixels();
 	if (_bitmapHeader->isCompressed()) {
 		// DECOMPRESS THE IMAGE.
-		// chunk.skip(chunk.bytesRemaining());
-		debugC(5, kDebugLoading, "Bitmap::Bitmap(): Decompressing bitmap");
+		debugC(5, kDebugLoading, "Bitmap::Bitmap(): Decompressing bitmap (@0x%llx)", static_cast<long long int>(chunk.pos()));
 		decompress(chunk);
+		debugC(5, kDebugLoading, "Bitmap::Bitmap(): Finished decompressing bitmap (@0x%llx) [%d remaining bytes]", static_cast<long long int>(chunk.pos()), chunk.bytesRemaining());
+		// TODO: Make sure there is nothing important in here. They are likely
+		// just zeroes.
+		chunk.skip(chunk.bytesRemaining());
 	} else {
 		// READ THE UNCOMPRESSED IMAGE DIRECTLY.
 		// TODO: Understand why we need to ignore these 2 bytes.
@@ -82,27 +85,23 @@ uint16 Bitmap::height() {
 }
 
 void Bitmap::decompress(Chunk &chunk) {
-	// GET THE COMPRESSED DATA.
-	uint compressedImageDataSizeInBytes = chunk.bytesRemaining();
-	char *compressedImageStart = new char[compressedImageDataSizeInBytes];
-	char *compressedImage = compressedImageStart;
-	chunk.read(compressedImage, compressedImageDataSizeInBytes);
-
 	// MAKE SURE WE READ PAST THE FIRST 2 BYTES.
-	char *compressedImageDataStart = compressedImage;
-	if ((*compressedImage++ == 0) && (*compressedImage++ == 0)) {
-		// This condition is empty, we just put it first since this is the expected case
-		// and the negated logic would be not as readable.
+	uint unk1 = chunk.readByte();
+	uint unk2 = chunk.readByte();
+	if ((unk1 == 0) && (unk2 == 0)) {
+		if (chunk.bytesRemaining() == 0) {
+			// Sometimes there are compressed images that actually have no
+			// contents! If we've hit this case, exit the decompression now.
+			return;
+		}
 	} else {
-		compressedImage = compressedImageDataStart;
+		chunk.seek(chunk.pos() - 2);
 	}
-	char *compressedImageDataEnd = compressedImage + compressedImageDataSizeInBytes;
 
 	// GET THE DECOMPRESSED PIXELS BUFFER.
 	// Media Station has 8 bits per pixel, so the decompression buffer is
 	// simple.
-	// TODO: Do we have to set the pixels ourselves?
-	char *decompressedImage = (char *)_surface.getPixels();
+	char *decompressedImage = static_cast<char *>(_surface.getPixels());
 
 	// DECOMPRESS THE RLE-COMPRESSED BITMAP STREAM.
 	// TODO: Comemnted out becuase transparency runs not supported yet,
@@ -116,14 +115,14 @@ void Bitmap::decompress(Chunk &chunk) {
 		size_t currentXCoordinate = 0;
 		bool readingTransparencyRun = false;
 		while (true) {
-			uint8_t operation = *compressedImage++;
+			byte operation = chunk.readByte();
 			if (operation == 0x00) {
 				// ENTER CONTROL MODE.
-				operation = *compressedImage++;
+				operation = chunk.readByte();
 				if (operation == 0x00) {
 					// MARK THE END OF THE LINE.
 					// Also check if the image is finished being read.
-					if (compressedImage >= compressedImageDataEnd) {
+					if (chunk.bytesRemaining() == 0) {
 						imageFullyRead = true;
 					}
 					break;
@@ -159,22 +158,25 @@ void Bitmap::decompress(Chunk &chunk) {
 					// So to skip 10 pixels using this approach, you would encode 00 03 0a 00.
 					// But to "skip" 10 pixels by encoding them as blank (0xff), you would encode 0a ff.
 					// What gives? I'm not sure.
-					uint8_t x_change = *compressedImage++;
+					byte x_change = chunk.readByte();
 					currentXCoordinate += x_change;
-					uint8_t y_change = *compressedImage++;
+					byte y_change = chunk.readByte();
 					currentYCoordinate += y_change;
 				} else if (operation >= 0x04) {
 					// READ A RUN OF UNCOMPRESSED PIXELS.
 					size_t yOffset = currentYCoordinate * width();
 					size_t runStartingOffset = yOffset + currentXCoordinate;
 					char *runStartingPointer = decompressedImage + runStartingOffset;
-					uint8_t runLength = operation;
-					memcpy(runStartingPointer, compressedImage, runLength);
-					compressedImage += operation;
-					currentXCoordinate += operation;
+					byte runLength = operation;
+					// TODO: Is there a better way to do this than just copying?
+					char *uncompressedPixels = new char[runLength];
+					chunk.read(uncompressedPixels, runLength);
+					memcpy(runStartingPointer, uncompressedPixels, runLength);
+					delete[] uncompressedPixels;
 
-					if (((uintptr_t)compressedImage) % 2 == 1) {
-						compressedImage++;
+					currentXCoordinate += operation;
+					if (chunk.pos() % 2 == 1) {
+						chunk.readByte();
 					}
 				}
 			} else {
@@ -182,8 +184,8 @@ void Bitmap::decompress(Chunk &chunk) {
 				size_t yOffset = currentYCoordinate * width();
 				size_t runStartingOffset = yOffset + currentXCoordinate;
 				char *runStartingPointer = decompressedImage + runStartingOffset;
-				uint8_t colorIndexToRepeat = *compressedImage++;
-				uint8_t repetitionCount = operation;
+				byte colorIndexToRepeat = chunk.readByte();
+				byte repetitionCount = operation;
 				memset(runStartingPointer, colorIndexToRepeat, repetitionCount);
 				currentXCoordinate += repetitionCount;
 
@@ -214,7 +216,6 @@ void Bitmap::decompress(Chunk &chunk) {
 			break;
 		}
 	}
-	delete[] compressedImageStart;
 }
 
 }




More information about the Scummvm-git-logs mailing list