AGS: Removed lzwexpand_to_mem(), tidied load_lzw()

From upstream 2b9f130e119f9cfc81d0257a446edc4e31df19c0
This commit is contained in:
Paul Gilbert 2022-03-30 20:26:01 -07:00
parent 02540a3b47
commit dc7609a79c
6 changed files with 48 additions and 88 deletions

View File

@ -1054,7 +1054,7 @@ public:
char *_lzbuffer = nullptr;
int *_node = nullptr;
int _pos = 0;
long _outbytes = 0, _maxsize = 0, _putbytes = 0;
size_t _outbytes = 0, _maxsize = 0, _putbytes = 0;
/**@}*/

View File

@ -359,79 +359,42 @@ void save_lzw(Stream *out, const Bitmap *bmpp, const RGB(*pal)[256]) {
}
void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, RGB(*pal)[256]) {
soff_t uncompsiz;
int *loptr;
unsigned char *membuffer;
int arin;
*dst_bmp = nullptr;
// NOTE: old format saves full RGB struct here (4 bytes, including the filler)
if (pal)
in->Read(*pal, sizeof(RGB) * 256);
else
in->Seek(sizeof(RGB) * 256);
_G(maxsize) = in->ReadInt32();
uncompsiz = in->ReadInt32();
const size_t uncomp_sz = in->ReadInt32();
const size_t comp_sz = in->ReadInt32();
const soff_t end_pos = in->GetPosition() + comp_sz;
uncompsiz += in->GetPosition();
_G(outbytes) = 0; _G(putbytes) = 0;
update_polled_stuff_if_runtime();
membuffer = lzwexpand_to_mem(in);
update_polled_stuff_if_runtime();
loptr = (int *)&membuffer[0];
membuffer += 8;
#if AGS_PLATFORM_ENDIAN_BIG
loptr[0] = BBOp::SwapBytesInt32(loptr[0]);
loptr[1] = BBOp::SwapBytesInt32(loptr[1]);
int bitmapNumPixels = loptr[0] * loptr[1] / dst_bpp;
switch (dst_bpp) // bytes per pixel!
// First decompress data into the memory buffer
std::vector<uint8_t> membuf;
{
case 1:
{
// all done
break;
MemoryStream memws(membuf, kStream_Write);
lzwexpand(in, &memws, uncomp_sz);
}
case 2:
{
short *sp = (short *)membuffer;
for (int i = 0; i < bitmapNumPixels; ++i) {
sp[i] = BBOp::SwapBytesInt16(sp[i]);
}
// all done
break;
}
case 4:
{
int *ip = (int *)membuffer;
for (int i = 0; i < bitmapNumPixels; ++i) {
ip[i] = BBOp::SwapBytesInt32(ip[i]);
}
// all done
break;
}
}
#endif // AGS_PLATFORM_ENDIAN_BIG
update_polled_stuff_if_runtime();
Bitmap *bmm = BitmapHelper::CreateBitmap((loptr[0] / dst_bpp), loptr[1], dst_bpp * 8);
// Open same buffer for reading and get params and pixels
MemoryStream mem_in(membuf);
int stride = mem_in.ReadInt32(); // width * bpp
int height = mem_in.ReadInt32();
Bitmap *bmm = BitmapHelper::CreateBitmap((stride / dst_bpp), height, dst_bpp * 8);
if (bmm == nullptr)
quit("load_room: not enough memory to load room background");
return; // out of mem?
update_polled_stuff_if_runtime();
size_t num_pixels = stride * height / dst_bpp;
uint8_t *bmp_data = bmm->GetDataForWriting();
switch (dst_bpp) {
case 1: mem_in.Read(bmp_data, num_pixels); break;
case 2: mem_in.ReadArrayOfInt16(reinterpret_cast<int16_t *>(bmp_data), num_pixels); break;
case 4: mem_in.ReadArrayOfInt32(reinterpret_cast<int32_t *>(bmp_data), num_pixels); break;
default: assert(0); break;
}
for (arin = 0; arin < loptr[1]; arin++)
memcpy(&bmm->GetScanLineForWriting(arin)[0], &membuffer[arin * loptr[0]], loptr[0]);
update_polled_stuff_if_runtime();
free(membuffer - 8);
if (in->GetPosition() != uncompsiz)
in->Seek(uncompsiz, kSeekBegin);
update_polled_stuff_if_runtime();
if (in->GetPosition() != end_pos)
in->Seek(end_pos, kSeekBegin);
*dst_bmp = bmm;
}

View File

@ -195,8 +195,6 @@ void lzwcompress(Stream *lzw_in, Stream *out) {
free(_G(lzbuffer));
}
int expand_to_mem = 0;
unsigned char *membfptr = nullptr;
void myputc(int ccc, Stream *out) {
if (_G(maxsize) > 0) {
_G(putbytes)++;
@ -205,21 +203,17 @@ void myputc(int ccc, Stream *out) {
}
_G(outbytes)++;
if (expand_to_mem) {
membfptr[0] = ccc;
membfptr++;
} else
out->WriteInt8(ccc);
out->WriteInt8(ccc);
}
void lzwexpand(Stream *lzw_in, Stream *out) {
void lzwexpand(Stream *lzw_in, Stream *out, size_t out_size) {
int bits, ch, i, j, len, mask;
char *buf;
// printf(" UnShrinking: %s ",filena);
_G(putbytes) = 0;
char *lzbuffer;
_G(outbytes) = 0; _G(putbytes) = 0;
_G(maxsize) = out_size;
buf = (char *)malloc(N);
if (buf == nullptr) {
lzbuffer = (char *)malloc(N);
if (lzbuffer == nullptr) {
quit("compress.cpp: unable to decompress: insufficient memory");
}
i = N - F;
@ -237,13 +231,13 @@ void lzwexpand(Stream *lzw_in, Stream *out) {
j = (i - j - 1) & (N - 1);
while (len--) {
myputc(buf[i] = buf[j], out);
myputc(lzbuffer[i] = lzbuffer[j], out);
j = (j + 1) & (N - 1);
i = (i + 1) & (N - 1);
}
} else {
ch = lzw_in->ReadByte();
myputc(buf[i] = ch, out);
myputc(lzbuffer[i] = ch, out);
i = (i + 1) & (N - 1);
}
@ -258,16 +252,7 @@ void lzwexpand(Stream *lzw_in, Stream *out) {
break;
}
free(buf);
expand_to_mem = 0;
}
unsigned char *lzwexpand_to_mem(Stream *in) {
unsigned char *membuff = (unsigned char *)malloc(_G(maxsize) + 10);
expand_to_mem = 1;
membfptr = membuff;
lzwexpand(in, nullptr);
return membuff;
free(lzbuffer);
}
} // namespace AGS3

View File

@ -33,7 +33,7 @@ class Stream;
using namespace AGS; // FIXME later
void lzwcompress(Shared::Stream *lzw_in, Shared::Stream *out);
unsigned char *lzwexpand_to_mem(Shared::Stream *in);
void lzwexpand(Shared::Stream *lzw_in, Shared::Stream *out, size_t out_size);
} // namespace AGS3

View File

@ -35,6 +35,15 @@ MemoryStream::MemoryStream(const std::vector<uint8_t> &cbuf, DataEndianess strea
, _pos(0) {
}
MemoryStream::MemoryStream(const uint8_t *cbuf, size_t buf_sz, DataEndianess stream_endianess)
: DataStream(stream_endianess)
, _cbuf(cbuf)
, _len(buf_sz)
, _buf(nullptr)
, _mode(kStream_Read)
, _pos(0) {
}
MemoryStream::MemoryStream(const String &cbuf, DataEndianess stream_endianess)
: DataStream(stream_endianess)
, _cbuf(reinterpret_cast<const uint8_t *>(cbuf.GetCStr()))

View File

@ -47,6 +47,9 @@ public:
// Construct memory stream in the read-only mode over a const std::vector;
// vector must persist in memory until the stream is closed.
MemoryStream(const std::vector<uint8_t> &cbuf, DataEndianess stream_endianess = kLittleEndian);
// Construct memory stream in the read-only mode over a const C-buffer;
// buffer must persist in memory until the stream is closed.
MemoryStream(const uint8_t *cbuf, size_t buf_sz, DataEndianess stream_endianess = kLittleEndian);
// Construct memory stream in the read-only mode over a const String;
// String object must persist in memory until the stream is closed.
MemoryStream(const String &cbuf, DataEndianess stream_endianess = kLittleEndian);