MCPcopy Create free account
hub / github.com/BohemiaInteractive/CWR / DecodePAABuffer

Function DecodePAABuffer

engine/Poseidon/Graphics/Textures/PAADecoder.cpp:403–546  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

401}
402
403DecodedImage DecodePAABuffer(const void* data, size_t size, bool isPaa)
404{
405 DecodedImage img;
406 QIStream in(static_cast<const char*>(data), static_cast<int>(size));
407
408 int desc = fgetiw(in);
409 bool alpha = false;
410 PacFormat format = PacFormatFromDesc(desc, alpha);
411 if (format == PacFormatN)
412 {
413 in.seekg(-2, QIOS::cur);
414 format = isPaa ? PacARGB4444 : PacP8;
415 }
416
417 PacPalette pal;
418 int offsets[16];
419 for (int i = 0; i < 16; i++)
420 offsets[i] = -1;
421 if (pal.Load(in, offsets, 16))
422 return img;
423
424 PacLevelMem mip;
425 if (offsets[0] >= 0)
426 mip.SetStart(offsets[0]);
427 if (mip.Init(in, format) != 0)
428 return img;
429
430 img.width = mip._w;
431 img.height = mip._h;
432 // Dimensions come from the mip header; reject absurd sizes before width*height*4
433 // overflows int (a tiny rgba alloc the decoders then overrun) or drives a huge
434 // allocation. PAA textures are far below this cap.
435 if (img.width <= 0 || img.height <= 0 || img.width > 8192 || img.height > 8192)
436 {
437 return img;
438 }
439 img.rgba.resize(img.width * img.height * 4);
440
441 bool isDXT = (format >= PacDXT1 && format <= PacDXT5);
442
443 if (format == PacARGB8888)
444 {
445 // ARGB8888: raw data, no LZSS. Convert ARGB → RGBA.
446 mip.SeekLevel(in);
447 int mw = fgetiw(in), mh = fgetiw(in);
448 if (mw == 0 && mh == 0)
449 {
450 img.rgba.clear();
451 return img;
452 }
453 int dSize = fgeti24(in);
454 std::vector<uint8_t> rawData(dSize);
455 in.read(reinterpret_cast<char*>(rawData.data()), dSize);
456 // The conversion loop below reads width*height*4 raw bytes; reject a payload
457 // too small to cover them rather than read past rawData (heap over-read).
458 if (static_cast<int>(rawData.size()) < img.width * img.height * 4)
459 {
460 img.rgba.clear();

Callers 6

LLVMFuzzerTestOneInputFunction · 0.85
pf_vfs_image_loadFunction · 0.85
DecodePAAFileMipFunction · 0.85
PreviewFontFromDataFunction · 0.85
AUTO_STATIC_ARRAYFunction · 0.85

Calls 15

fgetiwFunction · 0.85
PacFormatFromDescFunction · 0.85
fgeti24Function · 0.85
seekgMethod · 0.80
SetStartMethod · 0.80
SeekLevelMethod · 0.80
clearMethod · 0.80
sizeMethod · 0.80
SetDestFormatMethod · 0.80
LoadPaaMethod · 0.80
LoadPacMethod · 0.80
PitchMethod · 0.80

Tested by

no test coverage detected