void DrasculaEngine::showFrame(Common::SeekableReadStream *stream, bool firstFrame) { int dataSize = stream->readSint32LE(); byte *pcxData = (byte *)malloc(dataSize); stream->read(pcxData, dataSize); for (int i = 0; i < 256; i++) { cPal[i * 3 + 0] = stream->readByte(); cPal[i * 3 + 1] = stream->readByte(); cPal[i * 3 + 2] = stream->readByte(); } byte *prevFrame = (byte *)malloc(64000); byte *screenBuffer = (byte *)_system->lockScreen()->pixels; memcpy(prevFrame, screenBuffer, 64000); decodeRLE(pcxData, screenBuffer); free(pcxData); if (!firstFrame) mixVideo(screenBuffer, prevFrame); _system->unlockScreen(); _system->updateScreen(); if (firstFrame) setPalette(cPal); free(prevFrame); }
void DrasculaEngine::loadPic(const char *NamePcc, byte *targetSurface, int colorCount) { debug(5, "loadPic(%s)", NamePcc); uint dataSize = 0; byte *pcxData; Common::SeekableReadStream *stream = _archives.open(NamePcc); if (!stream) error("missing game data %s %c", NamePcc, 7); dataSize = stream->size() - 128 - (256 * 3); pcxData = (byte *)malloc(dataSize); stream->seek(128, SEEK_SET); stream->read(pcxData, dataSize); decodeRLE(pcxData, targetSurface); free(pcxData); for (int i = 0; i < 256; i++) { cPal[i * 3 + 0] = stream->readByte(); cPal[i * 3 + 1] = stream->readByte(); cPal[i * 3 + 2] = stream->readByte(); } delete stream; setRGB((byte *)cPal, colorCount); }
void DrasculaEngine::showFrame(Common::SeekableReadStream *stream, bool firstFrame) { int dataSize = stream->readSint32LE(); byte *pcxData = (byte *)malloc(dataSize); stream->read(pcxData, dataSize); for (int i = 0; i < 256; i++) { cPal[i * 3 + 0] = stream->readByte(); cPal[i * 3 + 1] = stream->readByte(); cPal[i * 3 + 2] = stream->readByte(); } byte *prevFrame = (byte *)malloc(64000); Graphics::Surface *screenSurf = _system->lockScreen(); byte *screenBuffer = (byte *)screenSurf->getPixels(); uint16 screenPitch = screenSurf->pitch; for (int y = 0; y < 200; y++) { memcpy(prevFrame+y*320, screenBuffer+y*screenPitch, 320); } decodeRLE(pcxData, screenBuffer, screenPitch); free(pcxData); if (!firstFrame) mixVideo(screenBuffer, prevFrame, screenPitch); _system->unlockScreen(); _system->updateScreen(); if (firstFrame) setPalette(cPal); free(prevFrame); }
void showBootLogo() { uint8_t *bootImageData = NULL; uint8_t *appleBootLogo = (uint8_t *) decodeRLE(appleLogoRLE, 686, 16384); setVideoMode(GRAPHICS_MODE); // Fill the background to 75% grey (same as BootX). drawColorRectangle(0, 0, VIDEO(width), VIDEO(height), 0x01); convertImage(APPLE_LOGO_WIDTH, APPLE_LOGO_HEIGHT, appleBootLogo, &bootImageData); drawDataRectangle(APPLE_LOGO_X, APPLE_LOGO_Y, APPLE_LOGO_WIDTH, APPLE_LOGO_HEIGHT, bootImageData); free(bootImageData); free(appleBootLogo); }
int DrasculaEngine::playFrameSSN(Common::SeekableReadStream *stream) { int Exit = 0; uint32 length; byte *BufferSSN; byte CHUNK = stream->readByte(); switch (CHUNK) { case kFrameSetPal: { byte dacSSN[768]; stream->read(dacSSN, 768); setPalette(dacSSN); break; } case kFrameEmptyFrame: waitFrameSSN(); break; case kFrameInit: { byte CMP = stream->readByte(); length = stream->readUint32LE(); if (CMP == kFrameCmpRle) { BufferSSN = (byte *)malloc(length); stream->read(BufferSSN, length); decodeRLE(BufferSSN, screenSurface); free(BufferSSN); waitFrameSSN(); Graphics::Surface *screenSurf = _system->lockScreen(); byte *screenBuffer = (byte *)screenSurf->getPixels(); uint16 screenPitch = screenSurf->pitch; if (FrameSSN) mixVideo(screenBuffer, screenSurface, screenPitch); else for (int y = 0; y < 200; y++) memcpy(screenBuffer+y*screenPitch, screenSurface+y*320, 320); _system->unlockScreen(); _system->updateScreen(); FrameSSN++; } else { if (CMP == kFrameCmpOff) { BufferSSN = (byte *)malloc(length); stream->read(BufferSSN, length); decodeOffset(BufferSSN, screenSurface, length); free(BufferSSN); waitFrameSSN(); Graphics::Surface *screenSurf = _system->lockScreen(); byte *screenBuffer = (byte *)screenSurf->getPixels(); uint16 screenPitch = screenSurf->pitch; if (FrameSSN) mixVideo(screenBuffer, screenSurface, screenPitch); else for (int y = 0; y < 200; y++) memcpy(screenBuffer+y*screenPitch, screenSurface+y*320, 320); _system->unlockScreen(); _system->updateScreen(); FrameSSN++; } } break; } case kFrameEndAnim: Exit = 1; break; default: Exit = 1; break; } return (!Exit); }
bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) { destroy(); if (stream.readByte() != 0x0a) // ZSoft PCX return false; byte version = stream.readByte(); // 0 - 5 if (version > 5) return false; bool compressed = stream.readByte(); // encoding, 1 = run length encoding byte bitsPerPixel = stream.readByte(); // 1, 2, 4 or 8 // Window uint16 xMin = stream.readUint16LE(); uint16 yMin = stream.readUint16LE(); uint16 xMax = stream.readUint16LE(); uint16 yMax = stream.readUint16LE(); uint16 width = xMax - xMin + 1; uint16 height = yMax - yMin + 1; if (xMax < xMin || yMax < yMin) { warning("Invalid PCX image dimensions"); return false; } stream.skip(4); // HDpi, VDpi // Read the EGA palette (colormap) _palette = new byte[16 * 3]; for (uint16 i = 0; i < 16; i++) { _palette[i * 3 + 0] = stream.readByte(); _palette[i * 3 + 1] = stream.readByte(); _palette[i * 3 + 2] = stream.readByte(); } if (stream.readByte() != 0) // reserved, should be set to 0 return false; byte nPlanes = stream.readByte(); uint16 bytesPerLine = stream.readUint16LE(); uint16 bytesPerscanLine = nPlanes * bytesPerLine; if (bytesPerscanLine < width * bitsPerPixel * nPlanes / 8) { warning("PCX data is corrupted"); return false; } stream.skip(60); // PaletteInfo, HscreenSize, VscreenSize, Filler _surface = new Graphics::Surface(); byte *scanLine = new byte[bytesPerscanLine]; byte *dst; int x, y; if (nPlanes == 3 && bitsPerPixel == 8) { // 24bpp Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); _surface->create(width, height, format); dst = (byte *)_surface->getPixels(); _paletteColorCount = 0; for (y = 0; y < height; y++) { decodeRLE(stream, scanLine, bytesPerscanLine, compressed); for (x = 0; x < width; x++) { byte b = scanLine[x]; byte g = scanLine[x + bytesPerLine]; byte r = scanLine[x + (bytesPerLine << 1)]; uint32 color = format.RGBToColor(r, g, b); *((uint32 *)dst) = color; dst += format.bytesPerPixel; } } } else if (nPlanes == 1 && bitsPerPixel == 8) { // 8bpp indexed _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); dst = (byte *)_surface->getPixels(); _paletteColorCount = 16; for (y = 0; y < height; y++, dst += _surface->pitch) { decodeRLE(stream, scanLine, bytesPerscanLine, compressed); memcpy(dst, scanLine, width); } if (version == 5) { if (stream.readByte() != 12) { warning("Expected a palette after the PCX image data"); delete[] scanLine; return false; } // Read the VGA palette delete[] _palette; _palette = new byte[256 * 3]; for (uint16 i = 0; i < 256; i++) { _palette[i * 3 + 0] = stream.readByte(); _palette[i * 3 + 1] = stream.readByte(); _palette[i * 3 + 2] = stream.readByte(); } _paletteColorCount = 256; } } else if ((nPlanes == 2 || nPlanes == 3 || nPlanes == 4) && bitsPerPixel == 1) { // planar, 4, 8 or 16 colors _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); dst = (byte *)_surface->getPixels(); _paletteColorCount = 16; for (y = 0; y < height; y++, dst += _surface->pitch) { decodeRLE(stream, scanLine, bytesPerscanLine, compressed); for (x = 0; x < width; x++) { int m = 0x80 >> (x & 7), v = 0; for (int i = nPlanes - 1; i >= 0; i--) { v <<= 1; v += (scanLine[i * bytesPerLine + (x >> 3)] & m) == 0 ? 0 : 1; } dst[x] = v; } } } else {
void DecompressorLZW::reorderView(byte *src, byte *dest) { byte *cellengths; int loopheaders; int lh_present; int lh_mask; int pal_offset; int cel_total; int unknown; byte *seeker = src; char celcounts[100]; byte *writer = dest; byte *lh_ptr; byte *rle_ptr, *pix_ptr; int l, lb, c, celindex, lh_last = -1; int chptr; int w; int *cc_lengths; byte **cc_pos; /* Parse the main header */ cellengths = src + READ_LE_UINT16(seeker) + 2; seeker += 2; loopheaders = *seeker++; lh_present = *seeker++; lh_mask = READ_LE_UINT16(seeker); seeker += 2; unknown = READ_LE_UINT16(seeker); seeker += 2; pal_offset = READ_LE_UINT16(seeker); seeker += 2; cel_total = READ_LE_UINT16(seeker); seeker += 2; cc_pos = (byte **) malloc(sizeof(byte *) * cel_total); cc_lengths = (int *) malloc(sizeof(int) * cel_total); for (c = 0; c < cel_total; c++) cc_lengths[c] = READ_LE_UINT16(cellengths + 2 * c); *writer++ = loopheaders; *writer++ = VIEW_HEADER_COLORS_8BIT; WRITE_LE_UINT16(writer, lh_mask); writer += 2; WRITE_LE_UINT16(writer, unknown); writer += 2; WRITE_LE_UINT16(writer, pal_offset); writer += 2; lh_ptr = writer; writer += 2 * loopheaders; /* Make room for the loop offset table */ pix_ptr = writer; memcpy(celcounts, seeker, lh_present); seeker += lh_present; lb = 1; celindex = 0; rle_ptr = pix_ptr = cellengths + (2 * cel_total); w = 0; for (l = 0; l < loopheaders; l++) { if (lh_mask & lb) { /* The loop is _not_ present */ if (lh_last == -1) { warning("Error: While reordering view: Loop not present, but can't re-use last loop"); lh_last = 0; } WRITE_LE_UINT16(lh_ptr, lh_last); lh_ptr += 2; } else { lh_last = writer - dest; WRITE_LE_UINT16(lh_ptr, lh_last); lh_ptr += 2; WRITE_LE_UINT16(writer, celcounts[w]); writer += 2; WRITE_LE_UINT16(writer, 0); writer += 2; /* Now, build the cel offset table */ chptr = (writer - dest) + (2 * celcounts[w]); for (c = 0; c < celcounts[w]; c++) { WRITE_LE_UINT16(writer, chptr); writer += 2; cc_pos[celindex+c] = dest + chptr; chptr += 8 + READ_LE_UINT16(cellengths + 2 * (celindex + c)); } buildCelHeaders(&seeker, &writer, celindex, cc_lengths, celcounts[w]); celindex += celcounts[w]; w++; } lb = lb << 1; } if (celindex < cel_total) { warning("View decompression generated too few (%d / %d) headers", celindex, cel_total); return; } /* Figure out where the pixel data begins. */ for (c = 0; c < cel_total; c++) pix_ptr += getRLEsize(pix_ptr, cc_lengths[c]); rle_ptr = cellengths + (2 * cel_total); for (c = 0; c < cel_total; c++) decodeRLE(&rle_ptr, &pix_ptr, cc_pos[c] + 8, cc_lengths[c]); if (pal_offset) { *writer++ = 'P'; *writer++ = 'A'; *writer++ = 'L'; for (c = 0; c < 256; c++) *writer++ = c; seeker -= 4; /* The missing four. Don't ask why. */ memcpy(writer, seeker, 4*256 + 4); } free(cc_pos); free(cc_lengths); }
void DecompressorLZW::reorderPic(byte *src, byte *dest, int dsize) { uint16 view_size, view_start, cdata_size; int i; byte *seeker = src; byte *writer = dest; char viewdata[7]; byte *cdata, *cdata_start; *writer++ = PIC_OP_OPX; *writer++ = PIC_OPX_SET_PALETTE; for (i = 0; i < 256; i++) /* Palette translation map */ *writer++ = i; WRITE_LE_UINT32(writer, 0); /* Palette stamp */ writer += 4; view_size = READ_LE_UINT16(seeker); seeker += 2; view_start = READ_LE_UINT16(seeker); seeker += 2; cdata_size = READ_LE_UINT16(seeker); seeker += 2; memcpy(viewdata, seeker, sizeof(viewdata)); seeker += sizeof(viewdata); memcpy(writer, seeker, 4*256); /* Palette */ seeker += 4*256; writer += 4*256; if (view_start != PAL_SIZE + 2) { /* +2 for the opcode */ memcpy(writer, seeker, view_start-PAL_SIZE-2); seeker += view_start - PAL_SIZE - 2; writer += view_start - PAL_SIZE - 2; } if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) { memcpy(dest + view_size + view_start + EXTRA_MAGIC_SIZE, seeker, dsize - view_size - view_start - EXTRA_MAGIC_SIZE); seeker += dsize - view_size - view_start - EXTRA_MAGIC_SIZE; } cdata_start = cdata = (byte *)malloc(cdata_size); memcpy(cdata, seeker, cdata_size); seeker += cdata_size; writer = dest + view_start; *writer++ = PIC_OP_OPX; *writer++ = PIC_OPX_EMBEDDED_VIEW; *writer++ = 0; *writer++ = 0; *writer++ = 0; WRITE_LE_UINT16(writer, view_size + 8); writer += 2; memcpy(writer, viewdata, sizeof(viewdata)); writer += sizeof(viewdata); *writer++ = 0; decodeRLE(&seeker, &cdata, writer, view_size); free(cdata_start); }
uint8_t ADMVideoSupSub::decode(uint32_t size, uint8_t *data) { uint32_t odd,even,_subSize,_dataSize,next=0,date,command,dum; uint32_t _curOffset=0,doneA=0,doneB=0; odd=even=0; _subSize=(data[0]<<8)+data[1]; if(!_subSize) { printf("Vobsub: error reading\n"); return 0; } aprintf("Vobsub: data len =%d\n",_subSize); _curOffset=2; if(_subSize<4) { printf("[handleSub] Packet too short!\n"); return 1; } _dataSize=(data[2]<<8)+data[3]; aprintf("data block=%lu\n",_dataSize); if(_dataSize<=4) { printf("Vobsub: data block too small\n"); return 0; } if(_dataSize-4>=_subSize) { printf("DataSize too large\n"); return 0; } _curOffset=_dataSize; while(2) { if(_curOffset>_subSize-5) break; date=READ16(); next=READ16(); if(next==_curOffset-4) break; // end of command while(_curOffset<next) { command=data[_curOffset++]; aprintf("vobsub:Command : %d date:%d next:%d cur:%lu\n",command,date,next,_curOffset); int left=next-_curOffset; switch(command) { case 00: break; case 01: // start date break; case 02: // stop date break; case 03: // Pallette 4 nibble= 16 bits if(left<2) { printf("Command 3: Palette: Not enough bytes left\n"); return 1; } dum=READ16(); _colors[0]=dum>>12; _colors[1]=0xf & (dum>>8); _colors[2]=0xf & (dum>>4); _colors[3]=0xf & (dum); printf("[SUP] Palette %x %x %x %x\n",_colors[0],_colors[1],_colors[2],_colors[3]); break; case 0xff: break; case 04: // alpha channel //4 nibble= 16 bits if(left<2) { printf("Command 4: Alpha: Not enough bytes left\n"); return 1; } dum=READ16(); _alpha[0]=dum>>12; _alpha[1]=0xf & (dum>>8); _alpha[2]=0xf & (dum>>4); _alpha[3]=0xf & (dum); printf("[SUP] Alpha %x %x %x %x\n",_alpha[0],_alpha[1],_alpha[2],_alpha[3]); break; case 05: // Coordinates 12 bits per entry X1/X2/Y1/Y2 // 48 bits total / 6 bytes { uint16_t a,b,c; uint32_t nx1,nx2,ny1,ny2; if(left<6) { printf("Command 5: Coord: Not enough bytes left\n"); return 1; } if(doneA) return 1; doneA++; a=READ16(); b=READ16(); c=READ16(); nx1=a>>4; nx2=((a&0xf)<<8)+(b>>8); ny1=((b&0xf)<<4)+(c>>12); ny2=c&0xfff; aprintf("vobsuv: x1:%d x2:%d y1:%d y2:%d\n",nx1,nx2,ny1,ny2); if(bitmap && ((nx2+1-nx1)==bitmap->_width) && ((ny2+1-ny1)==bitmap->_height)) { // Reuse old bitmap bitmap->clear(); } else { if(bitmap) delete bitmap; bitmap=NULL; _subW=nx2+1-nx1; _subH=ny2+1-ny1; bitmap=new vobSubBitmap(_subW,_subH); } } break; case 06: // RLE offset // 2*16 bits : odd offset, even offset { if(doneB) return 1; doneB++; if(left<4) { printf("Command 6: RLE: Not enough bytes left\n"); return 1; } odd=READ16(); even=READ16(); } break; default: printf("Unknown command:%d\n",command); return 0; } //End switch command }// end while } /*****/ if(bitmap && odd && even) { bitmap->clear(); decodeRLE(odd,0,even,data,_dataSize); decodeRLE(even,1,0,data,_dataSize); } return 1; }