From 4392fa5e2d42f3021f6eff5fbf8fb85de2c39379 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Mar 2022 20:00:36 -0700 Subject: [PATCH] AGS: Simplified savecompressed_allegro() and renamed for clarity From upstream 9a6b55bfe78bf0e9f24b2e3c2d1b073f850fae50 --- engines/ags/shared/game/room_file.cpp | 20 ++--- engines/ags/shared/util/compress.cpp | 105 ++++++++++---------------- engines/ags/shared/util/compress.h | 6 +- 3 files changed, 55 insertions(+), 76 deletions(-) diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index f52bfb9c615..9d74ec0e3b7 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -298,28 +298,28 @@ HError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { if (data_ver >= kRoomVersion_pre114_5) load_lzw(in, &mask, room->BackgroundBPP, room->Palette); else - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); room->BgFrames[0].Graphic.reset(mask); update_polled_stuff_if_runtime(); // Mask bitmaps if (data_ver >= kRoomVersion_255b) { - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); } else if (data_ver >= kRoomVersion_114) { // an old version - clear the 'shadow' area into a blank regions bmp - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); delete mask; mask = nullptr; } room->RegionMask.reset(mask); update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); room->WalkAreaMask.reset(mask); update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); room->WalkBehindMask.reset(mask); update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); + mask = load_rle_bitmap8(in); room->HotspotMask.reset(mask); return HError::None(); } @@ -748,10 +748,10 @@ void WriteMainBlock(const RoomStruct *room, Stream *out) { out->WriteInt32(room->Regions[i].Tint); save_lzw(out, room->BgFrames[0].Graphic.get(), room->Palette); - savecompressed_allegro(out, room->RegionMask.get(), room->Palette); - savecompressed_allegro(out, room->WalkAreaMask.get(), room->Palette); - savecompressed_allegro(out, room->WalkBehindMask.get(), room->Palette); - savecompressed_allegro(out, room->HotspotMask.get(), room->Palette); + save_rle_bitmap8(out, room->RegionMask.get()); + save_rle_bitmap8(out, room->WalkAreaMask.get()); + save_rle_bitmap8(out, room->WalkBehindMask.get()); + save_rle_bitmap8(out, room->HotspotMask.get()); } void WriteCompSc3Block(const RoomStruct *room, Stream *out) { diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index 268f3fb51c2..8b93d3e1203 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -151,36 +151,6 @@ static void cpackbitl32(const uint32_t *line, size_t size, Stream *out) { } // end while } - -void csavecompressed(Stream *out, const unsigned char *tobesaved, const RGB pala[256]) { - int widt, hit; - widt = *tobesaved++; - widt += (*tobesaved++) * 256; - hit = *tobesaved++; - hit += (*tobesaved++) * 256; - // Those were originally written as shorts, although they are ints - out->WriteInt16(widt); - out->WriteInt16(hit); - - unsigned char *ress = (unsigned char *)malloc(widt + 1); - int ww; - - for (ww = 0; ww < hit; ww++) { - for (int ss = 0; ss < widt; ss++) - (*ress++) = (*tobesaved++); - - ress -= widt; - cpackbitl(ress, widt, out); - } - - for (ww = 0; ww < 256; ww++) { - out->WriteInt8(pala[ww].r); - out->WriteInt8(pala[ww].g); - out->WriteInt8(pala[ww].b); - } - free(ress); -} - static int cunpackbitl(uint8_t *line, size_t size, Stream *in) { size_t n = 0; // number of bytes decoded @@ -310,6 +280,46 @@ void rle_decompress(uint8_t *data, size_t data_sz, int image_bpp, Stream *in) { } } +void save_rle_bitmap8(Stream *out, const Bitmap *bmp, const RGB(*pal)[256]) { + assert(bmp->GetBPP() == 1); + out->WriteInt16(static_cast(bmp->GetWidth())); + out->WriteInt16(static_cast(bmp->GetHeight())); + // Pack the pixels + cpackbitl(bmp->GetData(), bmp->GetWidth() * bmp->GetHeight(), out); + // Save palette + if (!pal) { // if no pal, write dummy palette, because we have to + out->WriteByteCount(0, 256 * 3); + return; + } + const RGB *ppal = *pal; + for (int i = 0; i < 256; ++i) { + out->WriteInt8(ppal[i].r); + out->WriteInt8(ppal[i].g); + out->WriteInt8(ppal[i].b); + } +} + +Shared::Bitmap *load_rle_bitmap8(Stream *in, RGB(*pal)[256]) { + int w = in->ReadInt16(); + int h = in->ReadInt16(); + Bitmap *bmp = BitmapHelper::CreateBitmap(w, h, 8); + if (!bmp) return nullptr; + // Unpack the pixels + cunpackbitl(bmp->GetDataForWriting(), w * h, in); + // Load or skip the palette + if (!pal) { + in->Seek(3 * 256); + return bmp; + } + RGB *ppal = *pal; + for (int i = 0; i < 256; ++i) { + ppal[i].r = in->ReadInt8(); + ppal[i].g = in->ReadInt8(); + ppal[i].b = in->ReadInt8(); + } + return bmp; +} + //----------------------------------------------------------------------------- // LZW //----------------------------------------------------------------------------- @@ -399,7 +409,7 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, RGB *pall) { Bitmap *bmm = BitmapHelper::CreateBitmap((loptr[0] / dst_bpp), loptr[1], dst_bpp * 8); if (bmm == nullptr) - quit("!load_room: not enough memory to load room background"); + quit("load_room: not enough memory to load room background"); update_polled_stuff_if_runtime(); @@ -418,37 +428,4 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, RGB *pall) { *dst_bmp = bmm; } -void savecompressed_allegro(Stream *out, const Bitmap *bmpp, const RGB *pall) { - unsigned char *wgtbl = (unsigned char *)malloc(bmpp->GetWidth() * bmpp->GetHeight() + 4); - short *sss = (short *)wgtbl; - - sss[0] = bmpp->GetWidth(); - sss[1] = bmpp->GetHeight(); - - memcpy(&wgtbl[4], bmpp->GetData(), bmpp->GetWidth() * bmpp->GetHeight()); - - csavecompressed(out, wgtbl, pall); - free(wgtbl); -} - -void loadcompressed_allegro(Stream *in, Bitmap **bimpp, RGB *pall) { - short widd, hitt; - int ii; - - widd = in->ReadInt16(); - hitt = in->ReadInt16(); - Bitmap *bim = BitmapHelper::CreateBitmap(widd, hitt, 8); - if (bim == nullptr) - quit("!load_room: not enough memory to decompress masks"); - - for (ii = 0; ii < hitt; ii++) { - cunpackbitl(&bim->GetScanLineForWriting(ii)[0], widd, in); - if (ii % 20 == 0) - update_polled_stuff_if_runtime(); - } - - in->Seek(768); // skip palette - *bimpp = bim; -} - } // namespace AGS3 diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index d9472c69c7e..01f4e039375 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -38,12 +38,14 @@ using namespace AGS; // FIXME later void rle_compress(const uint8_t *data, size_t data_sz, int image_bpp, Shared::Stream *out); void rle_decompress(uint8_t *data, size_t data_sz, int image_bpp, Shared::Stream *in); +// Packs a 8-bit bitmap using RLE compression, and writes into stream along with the palette +void save_rle_bitmap8(Shared::Stream *out, const Shared::Bitmap *bmp, const RGB(*pal)[256] = nullptr); +// Reads a 8-bit bitmap with palette from the stream and unpacks from RLE +Shared::Bitmap *load_rle_bitmap8(Shared::Stream *in, RGB(*pal)[256] = nullptr); // LZW compression void save_lzw(Shared::Stream *out, const Shared::Bitmap *bmpp, const RGB *pall); void load_lzw(Shared::Stream *in, Shared::Bitmap **bmm, int dst_bpp, RGB *pall); -void savecompressed_allegro(Shared::Stream *out, const Shared::Bitmap *bmpp, const RGB *pall); -void loadcompressed_allegro(Shared::Stream *in, Shared::Bitmap **bimpp, RGB *pall); } // namespace AGS3