aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/gfx/image/pngloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/gfx/image/pngloader.cpp')
-rw-r--r--engines/sword25/gfx/image/pngloader.cpp360
1 files changed, 155 insertions, 205 deletions
diff --git a/engines/sword25/gfx/image/pngloader.cpp b/engines/sword25/gfx/image/pngloader.cpp
index 1c896a7675..3f892c7af1 100644
--- a/engines/sword25/gfx/image/pngloader.cpp
+++ b/engines/sword25/gfx/image/pngloader.cpp
@@ -85,209 +85,170 @@ bool BS_PNGLoader::DoDecodeImage(const char *FileDataPtr, unsigned int FileSize,
return false;
}
- try {
- // PNG Signatur überprüfen
- if (!png_check_sig(reinterpret_cast<png_bytep>(const_cast<char *>(FileDataPtr)), 8)) {
- throw(0);
- }
-
- // Die beiden PNG Strukturen erstellen
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr) {
- BS_LOG_ERRORLN("Could not create libpng read struct.");
- throw(0);
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- BS_LOG_ERRORLN("Could not create libpng info struct.");
- throw(0);
- }
+ // PNG Signatur überprüfen
+ if (!png_check_sig(reinterpret_cast<png_bytep>(const_cast<char *>(FileDataPtr)), 8)) {
+ error("png_check_sig failed");
+ }
- // Rücksprungpunkt setzen. Wird im Falle eines Fehlers angesprungen.
- if (setjmp(png_jmpbuf(png_ptr))) throw(0);
+ // Die beiden PNG Strukturen erstellen
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ error("Could not create libpng read struct.");
+ }
- // Alternative Lesefunktion benutzen
- png_set_read_fn(png_ptr, (void *)FileDataPtr, png_user_read_data);
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ error("Could not create libpng info struct.");
+ }
- // PNG Header einlesen
- png_read_info(png_ptr, info_ptr);
+ // Alternative Lesefunktion benutzen
+ png_set_read_fn(png_ptr, (void *)FileDataPtr, png_user_read_data);
- // PNG Informationen auslesen
- png_get_IHDR(png_ptr, info_ptr, (unsigned long *)&Width, (unsigned long *)&Height, &BitDepth, &ColorType, &InterlaceType, NULL, NULL);
+ // PNG Header einlesen
+ png_read_info(png_ptr, info_ptr);
- // Pitch des Ausgabebildes berechnen
- Pitch = BS_GraphicEngine::CalcPitch(ColorFormat, Width);
+ // PNG Informationen auslesen
+ png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)&Width, (png_uint_32 *)&Height, &BitDepth, &ColorType, &InterlaceType, NULL, NULL);
- // Speicher für die endgültigen Bilddaten reservieren
- // Dieses geschieht vor dem reservieren von Speicher für temporäre Bilddaten um die Fragmentierung des Speichers gering zu halten
- UncompressedDataPtr = new char[Pitch * Height];
- if (!UncompressedDataPtr) {
- BS_LOG_ERRORLN("Could not allocate memory for output image.");
- throw(0);
- }
+ // Pitch des Ausgabebildes berechnen
+ Pitch = BS_GraphicEngine::CalcPitch(ColorFormat, Width);
- // Bilder jeglicher Farbformate werden zunächst in ARGB Bilder umgewandelt
- if (BitDepth == 16)
- png_set_strip_16(png_ptr);
- if (ColorType == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
- if (BitDepth < 8)
- png_set_expand(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
- if (ColorType == PNG_COLOR_TYPE_GRAY ||
- ColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
- png_set_bgr(png_ptr);
-
- if (ColorType != PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
-
- // Nachdem die Transformationen registriert wurden, werden die Bilddaten erneut eingelesen
- png_read_update_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, (unsigned long *)&Width, (unsigned long *)&Height, &BitDepth, &ColorType, NULL, NULL, NULL);
-
- // PNGs ohne Interlacing werden Zeilenweise eingelesen
- if (InterlaceType == PNG_INTERLACE_NONE) {
- // Speicher für eine Bildzeile reservieren
- RawDataBuffer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
- if (!RawDataBuffer) {
- BS_LOG_ERRORLN("Could not allocate memory for row buffer.");
- throw(0);
- }
+ // Speicher für die endgültigen Bilddaten reservieren
+ // Dieses geschieht vor dem reservieren von Speicher für temporäre Bilddaten um die Fragmentierung des Speichers gering zu halten
+ UncompressedDataPtr = new char[Pitch * Height];
+ if (!UncompressedDataPtr) {
+ error("Could not allocate memory for output image.");
+ }
- // Bilddaten zeilenweise einlesen und in das gewünschte Zielformat konvertieren
- for (i = 0; i < Height; i++) {
- // Zeile einlesen
- png_read_row(png_ptr, RawDataBuffer, NULL);
-
- // Zeile konvertieren
- switch (ColorFormat) {
- case BS_GraphicEngine::CF_RGB16:
- RowARGB32ToRGB16((unsigned char *)RawDataBuffer,
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
- break;
-
- case BS_GraphicEngine::CF_RGB15:
- RowARGB32ToRGB15((unsigned char *)RawDataBuffer,
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
- break;
-
- case BS_GraphicEngine::CF_RGB16_INTERLEAVED:
- RowARGB32ToRGB16_INTERLEAVED((unsigned char *)RawDataBuffer,
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
- break;
-
- case BS_GraphicEngine::CF_RGB15_INTERLEAVED:
- RowARGB32ToRGB15_INTERLEAVED((unsigned char *)RawDataBuffer,
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
- break;
-
- case BS_GraphicEngine::CF_ARGB32:
- memcpy(&UncompressedDataPtr[i * Pitch],
- RawDataBuffer,
- Pitch);
- break;
-
- case BS_GraphicEngine::CF_ABGR32:
- RowARGB32ToABGR32((unsigned char *)RawDataBuffer,
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
- break;
-
- default:
- BS_ASSERT(false);
- }
- }
+ // Bilder jeglicher Farbformate werden zunächst in ARGB Bilder umgewandelt
+ if (BitDepth == 16)
+ png_set_strip_16(png_ptr);
+ if (ColorType == PNG_COLOR_TYPE_PALETTE)
+ png_set_expand(png_ptr);
+ if (BitDepth < 8)
+ png_set_expand(png_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_expand(png_ptr);
+ if (ColorType == PNG_COLOR_TYPE_GRAY ||
+ ColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb(png_ptr);
+
+ png_set_bgr(png_ptr);
+
+ if (ColorType != PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ // Nachdem die Transformationen registriert wurden, werden die Bilddaten erneut eingelesen
+ png_read_update_info(png_ptr, info_ptr);
+ png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)&Width, (png_uint_32 *)&Height, &BitDepth, &ColorType, NULL, NULL, NULL);
+
+ // PNGs ohne Interlacing werden Zeilenweise eingelesen
+ if (InterlaceType == PNG_INTERLACE_NONE) {
+ // Speicher für eine Bildzeile reservieren
+ RawDataBuffer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
+ if (!RawDataBuffer) {
+ error("Could not allocate memory for row buffer.");
}
- // PNGs mit Interlacing werden an einem Stück eingelesen
- else {
- // Speicher für das komplette Bild reservieren
- RawDataBuffer = new png_byte[png_get_rowbytes(png_ptr, info_ptr) * Height];
- if (!RawDataBuffer) {
- BS_LOG_ERRORLN("Could not allocate memory for raw image buffer.");
- throw(0);
- }
-
- // Speicher für die Rowpointer reservieren
- pRowPtr = new png_bytep[Height];
- if (!pRowPtr) {
- BS_LOG_ERRORLN("Could not allocate memory for row pointers.");
- throw(0);
- }
-
- // Alle Rowpointer mit den richtigen Offsets initialisieren
- for (i = 0; i < Height; i++)
- pRowPtr[i] = RawDataBuffer + i * png_get_rowbytes(png_ptr, info_ptr);
- // Bild einlesen
- png_read_image(png_ptr, pRowPtr);
+ // Bilddaten zeilenweise einlesen und in das gewünschte Zielformat konvertieren
+ for (i = 0; i < Height; i++) {
+ // Zeile einlesen
+ png_read_row(png_ptr, RawDataBuffer, NULL);
- // Bilddaten zeilenweise in das gewünschte Ausgabeformat konvertieren
+ // Zeile konvertieren
switch (ColorFormat) {
case BS_GraphicEngine::CF_RGB16:
- for (i = 0; i < Height; i++)
- RowARGB32ToRGB16((unsigned char *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
+ RowARGB32ToRGB16((byte *)RawDataBuffer, (byte *)&UncompressedDataPtr[i * Pitch], Width);
break;
case BS_GraphicEngine::CF_RGB15:
- for (i = 0; i < Height; i++)
- RowARGB32ToRGB15((unsigned char *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
+ RowARGB32ToRGB15((byte *)RawDataBuffer, (byte *)&UncompressedDataPtr[i * Pitch], Width);
break;
case BS_GraphicEngine::CF_RGB16_INTERLEAVED:
- for (i = 0; i < Height; i++)
- RowARGB32ToRGB16_INTERLEAVED((unsigned char *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
+ RowARGB32ToRGB16_INTERLEAVED((byte *)RawDataBuffer, (byte *)&UncompressedDataPtr[i * Pitch], Width);
break;
case BS_GraphicEngine::CF_RGB15_INTERLEAVED:
- for (i = 0; i < Height; i++)
- RowARGB32ToRGB15_INTERLEAVED((unsigned char *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
- (unsigned char *)&UncompressedDataPtr[i * Pitch],
- Width);
+ RowARGB32ToRGB15_INTERLEAVED((byte *)RawDataBuffer,
+ (byte *)&UncompressedDataPtr[i * Pitch], Width);
break;
case BS_GraphicEngine::CF_ARGB32:
- for (i = 0; i < Height; i++)
- memcpy(&UncompressedDataPtr[i * Pitch],
- &RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)],
- Pitch);
+ memcpy(&UncompressedDataPtr[i * Pitch], RawDataBuffer, Pitch);
+ break;
+
+ case BS_GraphicEngine::CF_ABGR32:
+ RowARGB32ToABGR32((byte *)RawDataBuffer, (byte *)&UncompressedDataPtr[i * Pitch], Width);
break;
+
+ default:
+ assert(0);
}
}
+ } else {
+ // PNGs mit Interlacing werden an einem Stück eingelesen
+ // Speicher für das komplette Bild reservieren
+ RawDataBuffer = new png_byte[png_get_rowbytes(png_ptr, info_ptr) * Height];
+ if (!RawDataBuffer) {
+ error("Could not allocate memory for raw image buffer.");
+ }
- // Die zusätzlichen Daten am Ende des Bildes lesen
- png_read_end(png_ptr, NULL);
+ // Speicher für die Rowpointer reservieren
+ pRowPtr = new png_bytep[Height];
+ if (!pRowPtr) {
+ error("Could not allocate memory for row pointers.");
+ }
- // Die Strukturen freigeben
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ // Alle Rowpointer mit den richtigen Offsets initialisieren
+ for (i = 0; i < Height; i++)
+ pRowPtr[i] = RawDataBuffer + i * png_get_rowbytes(png_ptr, info_ptr);
- // Temporäre Buffer freigeben
- delete[] pRowPtr;
- delete[] RawDataBuffer;
- }
+ // Bild einlesen
+ png_read_image(png_ptr, pRowPtr);
+
+ // Bilddaten zeilenweise in das gewünschte Ausgabeformat konvertieren
+ switch (ColorFormat) {
+ case BS_GraphicEngine::CF_RGB16:
+ for (i = 0; i < Height; i++)
+ RowARGB32ToRGB16((byte *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
+ (byte *)&UncompressedDataPtr[i * Pitch], Width);
+ break;
- catch (int) {
- delete[] pRowPtr;
- delete[] RawDataBuffer;
- if (png_ptr) png_destroy_read_struct(&png_ptr, NULL, NULL);
- if (info_ptr) png_destroy_read_struct(NULL, &info_ptr, NULL);
+ case BS_GraphicEngine::CF_RGB15:
+ for (i = 0; i < Height; i++)
+ RowARGB32ToRGB15((byte *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
+ (byte *)&UncompressedDataPtr[i * Pitch], Width);
+ break;
- // Der Funktionsaufruf war nicht erfolgreich
- return false;
+ case BS_GraphicEngine::CF_RGB16_INTERLEAVED:
+ for (i = 0; i < Height; i++)
+ RowARGB32ToRGB16_INTERLEAVED((byte *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
+ (byte *)&UncompressedDataPtr[i * Pitch], Width);
+ break;
+
+ case BS_GraphicEngine::CF_RGB15_INTERLEAVED:
+ for (i = 0; i < Height; i++)
+ RowARGB32ToRGB15_INTERLEAVED((byte *)(&RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)]),
+ (byte *)&UncompressedDataPtr[i * Pitch], Width);
+ break;
+
+ case BS_GraphicEngine::CF_ARGB32:
+ for (i = 0; i < Height; i++)
+ memcpy(&UncompressedDataPtr[i * Pitch], &RawDataBuffer[i * png_get_rowbytes(png_ptr, info_ptr)], Pitch);
+ break;
+ }
}
+
+ // Die zusätzlichen Daten am Ende des Bildes lesen
+ png_read_end(png_ptr, NULL);
+
+ // Die Strukturen freigeben
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+ // Temporäre Buffer freigeben
+ delete[] pRowPtr;
+ delete[] RawDataBuffer;
// Der Funktionsaufruf war erfolgreich
return true;
@@ -308,48 +269,37 @@ bool BS_PNGLoader::DoImageProperties(const char *FileDataPtr, unsigned int FileS
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
- try {
- // Die beiden PNG Strukturen erstellen
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr) {
- BS_LOG_ERRORLN("Could not create libpng read struct.");
- throw(0);
- }
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- BS_LOG_ERRORLN("Could not create libpng info struct.");
- throw(0);
- }
-
- // Alternative Lesefunktion benutzen
- png_set_read_fn(png_ptr, (void *)FileDataPtr, png_user_read_data);
+ // Die beiden PNG Strukturen erstellen
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ error("Could not create libpng read struct.");
+ }
- // PNG Header einlesen
- png_read_info(png_ptr, info_ptr);
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ error("Could not create libpng info struct.");
+ }
- // PNG Informationen auslesen
- int BitDepth;
- int ColorType;
- png_get_IHDR(png_ptr, info_ptr, (unsigned long *)&Width, (unsigned long *)&Height, &BitDepth, &ColorType, NULL, NULL, NULL);
+ // Alternative Lesefunktion benutzen
+ png_set_read_fn(png_ptr, (void *)FileDataPtr, png_user_read_data);
- // PNG-ColorType in BS ColorFormat konvertieren.
- if (ColorType & PNG_COLOR_MASK_ALPHA || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- ColorFormat = BS_GraphicEngine::CF_ARGB32;
- else
- ColorFormat = BS_GraphicEngine::CF_RGB24;
+ // PNG Header einlesen
+ png_read_info(png_ptr, info_ptr);
- // Die Strukturen freigeben
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- }
+ // PNG Informationen auslesen
+ int BitDepth;
+ int ColorType;
+ png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)&Width, (png_uint_32 *)&Height, &BitDepth, &ColorType, NULL, NULL, NULL);
- catch (int) {
- if (png_ptr) png_destroy_read_struct(&png_ptr, NULL, NULL);
- if (info_ptr) png_destroy_read_struct(NULL, &info_ptr, NULL);
+ // PNG-ColorType in BS ColorFormat konvertieren.
+ if (ColorType & PNG_COLOR_MASK_ALPHA || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ ColorFormat = BS_GraphicEngine::CF_ARGB32;
+ else
+ ColorFormat = BS_GraphicEngine::CF_RGB24;
- // Der Funktionsaufruf war nicht erfolgreich
- return false;
- }
+ // Die Strukturen freigeben
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return true;
@@ -367,7 +317,7 @@ bool BS_PNGLoader::ImageProperties(const char *FileDataPtr, unsigned int FileSiz
bool BS_PNGLoader::DoIsCorrectImageFormat(const char *FileDataPtr, unsigned int FileSize) {
if (FileSize > 8)
- return png_check_sig((unsigned char *)FileDataPtr, 8) ? true : false;
+ return png_check_sig((byte *)FileDataPtr, 8) ? true : false;
else
return false;
}