[Scummvm-cvs-logs] SF.net SVN: scummvm: [24837] tools/trunk/encode_dxa.cpp
kirben at users.sourceforge.net
kirben at users.sourceforge.net
Mon Dec 11 07:53:15 CET 2006
Revision: 24837
http://scummvm.svn.sourceforge.net/scummvm/?rev=24837&view=rev
Author: kirben
Date: 2006-12-10 22:53:14 -0800 (Sun, 10 Dec 2006)
Log Message:
-----------
Add patch #1611503 - DXA: Improved encoder (filesize and speed)
Modified Paths:
--------------
tools/trunk/encode_dxa.cpp
Modified: tools/trunk/encode_dxa.cpp
===================================================================
--- tools/trunk/encode_dxa.cpp 2006-12-11 06:20:17 UTC (rev 24836)
+++ tools/trunk/encode_dxa.cpp 2006-12-11 06:53:14 UTC (rev 24837)
@@ -36,32 +36,44 @@
#define BUFFER_LEN 1024
// other block dimensions than 4x4 are not really supported yet
-#define BLOCKW 4
-#define BLOCKH 4
+#define BLOCKW 4
+#define BLOCKH 4
static CompressMode gCompMode = kMP3Mode;
+enum ScaleMode { S_NONE, S_INTERLACED, S_DOUBLE };
+
+struct DiffStruct {
+ uint16 map;
+ int count;
+ byte pixels[BLOCKW*BLOCKH];
+};
+
class DxaEncoder {
private:
FILE *_dxa;
- int _width, _height, _framerate, _framecount;
+ int _width, _height, _framerate, _framecount, _workheight;
uint8 *_prevframe, *_prevpalette;
+ ScaleMode _scaleMode;
- bool m12blocksAreEqual(byte *frame, int x, int y, int x2, int y2);
- bool m12blockIsSolidColor(byte *frame, int x, int y, byte &color);
- void m12blockDelta(byte *frame, int x, int y, unsigned short &diffMap, int &diffCount, byte diffPix[]);
- bool m12motionVector(byte *frame, int x, int y, int &mx, int &my);
- uLong m12encode(byte *frame, byte *outbuf);
+ byte *_codeBuf, *_dataBuf, *_motBuf, *_maskBuf;
+ void grabBlock(byte *frame, int x, int y, int blockw, int blockh, byte *block);
+ bool m13blocksAreEqual(byte *frame, int x, int y, int x2, int y2, int w, int h);
+ bool m13blockIsSolidColor(byte *frame, int x, int y, int w, int h, byte &color);
+ void m13blockDelta(byte *frame, int x, int y, int x2, int y2, DiffStruct &diff);
+ bool m13motionVector(byte *frame, int x, int y, int w, int h, int &mx, int &my);
+ int m13countColors(byte *block, byte *pixels, unsigned long &code, int &codeSize);
+ uLong m13encode(byte *frame, byte *outbuf);
public:
- DxaEncoder(char *filename, int width, int height, int fps);
+ DxaEncoder(char *filename, int width, int height, int framerate, ScaleMode scaleMode);
~DxaEncoder();
void writeHeader();
void writeNULL();
void writeFrame(uint8 *frame, uint8 *palette);
};
-DxaEncoder::DxaEncoder(char *filename, int width, int height, int framerate) {
+DxaEncoder::DxaEncoder(char *filename, int width, int height, int framerate, ScaleMode scaleMode) {
_dxa = fopen(filename, "wb");
_width = width;
_height = height;
@@ -69,7 +81,14 @@
_framecount = 0;
_prevframe = new uint8[_width * _height];
_prevpalette = new uint8[768];
+ _scaleMode = scaleMode;
+ _workheight = _scaleMode == S_NONE ? _height : _height / 2;
+ _codeBuf = new byte[_width * _height / 16];
+ _dataBuf = new byte[_width * _height];
+ _motBuf = new byte[_width * _height];
+ _maskBuf = new byte[_width * _height];
+
writeHeader();
}
@@ -80,6 +99,11 @@
fclose(_dxa);
+ delete[] _codeBuf;
+ delete[] _dataBuf;
+ delete[] _motBuf;
+ delete[] _maskBuf;
+
delete[] _prevframe;
delete[] _prevpalette;
}
@@ -88,6 +112,12 @@
//DEXA
uint8 version = 0;
+ /* remember the scaling mode */
+ if (_scaleMode == S_INTERLACED)
+ version |= 0x80;
+ else if (_scaleMode == S_DOUBLE)
+ version |= 0x40;
+
writeUint32LE(_dxa, typeDEXA);
writeByte(_dxa, version);
@@ -102,140 +132,110 @@
writeUint32LE(_dxa, typeNULL);
}
-void DxaEncoder::writeFrame(uint8 *frame, uint8 *palette) {
+void DxaEncoder::writeFrame(byte *frame, byte *palette) {
+
if (_framecount == 0 || memcmp(_prevpalette, palette, 768)) {
writeUint32LE(_dxa, typeCMAP);
fwrite(palette, 768, 1, _dxa);
-
memcpy(_prevpalette, palette, 768);
} else {
writeNULL();
}
- if (_framecount == 0 || memcmp(_prevframe, frame, _width * _height)) {
+ if (_framecount == 0 || memcmp(_prevframe, frame, _width * _workheight)) {
//FRAM
- uint8 compType;
+ byte compType;
writeUint32LE(_dxa, typeFRAM);
if (_framecount == 0)
compType = 2;
else
- //compType = 3;
- compType = 12;
+ compType = 13;
switch (compType) {
+
case 2:
{
- uLong outsize = _width * _height;
- uint8 *outbuf = new uint8[outsize];
-
- compress2(outbuf, &outsize, frame, _width * _height, 9);
-
+ uLong outsize = _width * _workheight;
+ byte *outbuf = new byte[outsize];
+ compress2(outbuf, &outsize, frame, _width * _workheight, 9);
writeByte(_dxa, compType);
-
writeUint32BE(_dxa, outsize);
-
fwrite(outbuf, outsize, 1, _dxa);
-
delete[] outbuf;
-
break;
}
- case 3:
+
+ case 13:
{
- uLong outsize1 = _width * _height;
- uLong outsize2 = outsize1;
- uLong outsize;
- uint8 *outbuf;
- uint8 *outbuf1 = new uint8[outsize1];
- uint8 *outbuf2 = new uint8[outsize2];
- uint8 *xorbuf = new uint8[_width * _height];
+ int r;
+ uLong frameoutsize;
+ byte *frameoutbuf;
- for (int i = 0; i < _width * _height; i++)
- xorbuf[i] = _prevframe[i] ^ frame[i];
+ byte *xorbuf = new byte[_width * _workheight];
+ uLong xorsize_z = _width * _workheight;
+ byte *xorbuf_z = new byte[xorsize_z];
- compress2(outbuf1, &outsize1, xorbuf, _width * _height, 9);
- compress2(outbuf2, &outsize2, frame, _width * _height, 9);
+ uLong rawsize_z = _width * _workheight;
+ byte *rawbuf_z = new byte[rawsize_z];
- if (outsize1 < outsize2) {
- compType = 3;
- outsize = outsize1;
- outbuf = outbuf1;
- } else {
- compType = 2;
- outsize = outsize2;
- outbuf = outbuf2;
- }
+ uLong m13size = _width * _workheight * 2;
+ byte *m13buf = new byte[m13size];
+ uLong m13size_z = _width * _workheight;
+ byte *m13buf_z = new byte[m13size_z];
- writeByte(_dxa, compType);
+ /* encode the delta frame with mode 12 */
+ m13size = m13encode(frame, m13buf);
- writeUint32BE(_dxa, outsize);
+ /* create the xor buffer */
+ for (int i = 0; i < _width * _workheight; i++)
+ xorbuf[i] = _prevframe[i] ^ frame[i];
- fwrite(outbuf, outsize, 1, _dxa);
+ /* compress the m13 buffer */
+ compress2(m13buf_z, &m13size_z, m13buf, m13size, 9);
- delete[] outbuf1;
- delete[] outbuf2;
- delete[] xorbuf;
+ /* compress the xor buffer */
+ xorsize_z = m13size_z;
+ r = compress2(xorbuf_z, &xorsize_z, xorbuf, _width * _workheight, 9);
+ if (r != Z_OK) xorsize_z = 0xFFFFFFF;
- break;
- }
- case 12:
+ if (m13size_z < xorsize_z) {
+ compType = 13;
+ frameoutsize = m13size_z;
+ frameoutbuf = m13buf_z;
+ } else {
+ compType = 3;
+ frameoutsize = xorsize_z;
+ frameoutbuf = xorbuf_z;
+ }
- {
+ /* compress the raw frame */
+ rawsize_z = frameoutsize;
+ r = compress2(rawbuf_z, &rawsize_z, frame, _width * _workheight, 9);
+ if (r != Z_OK) rawsize_z = 0xFFFFFFF;
- uLong outsize1 = _width * _height;
- uLong outsize2 = outsize1;
- uLong outsize3 = outsize1*2;
- uLong outsize4 = outsize1;
- uLong outsize;
- uint8 *outbuf;
- uint8 *outbuf1 = new uint8[outsize1];
- uint8 *outbuf2 = new uint8[outsize2];
- uint8 *outbuf3 = new uint8[outsize3];
- uint8 *outbuf4 = new uint8[outsize4];
- uint8 *xorbuf = new uint8[_width * _height];
-
- for (int i = 0; i < _width * _height; i++)
- xorbuf[i] = _prevframe[i] ^ frame[i];
-
- compress2(outbuf1, &outsize1, xorbuf, _width * _height, 9);
- compress2(outbuf2, &outsize2, frame, _width * _height, 9);
- if (outsize1 < outsize2) {
- compType = 3;
- outsize = outsize1;
- outbuf = outbuf1;
- } else {
+ if (rawsize_z < frameoutsize) {
compType = 2;
- outsize = outsize2;
- outbuf = outbuf2;
+ frameoutsize = rawsize_z;
+ frameoutbuf = rawbuf_z;
}
- outsize3 = m12encode(frame, outbuf3);
-
- compress2(outbuf4, &outsize4, outbuf3, outsize3, 9);
-
- if (outsize4 < outsize) {
- compType = 12;
- outsize = outsize4;
- outbuf = outbuf4;
- }
-
writeByte(_dxa, compType);
- writeUint32BE(_dxa, outsize);
- fwrite(outbuf, outsize, 1, _dxa);
+ writeUint32BE(_dxa, frameoutsize);
+ fwrite(frameoutbuf, frameoutsize, 1, _dxa);
- delete[] outbuf1;
- delete[] outbuf2;
- delete[] outbuf3;
- delete[] outbuf4;
+ delete[] xorbuf_z;
+ delete[] rawbuf_z;
+ delete[] m13buf_z;
+ delete[] m13buf;
delete[] xorbuf;
break;
}
}
- memcpy(_prevframe, frame, _width * _height);
+ memcpy(_prevframe, frame, _width * _workheight);
} else {
writeNULL();
@@ -244,11 +244,11 @@
_framecount++;
}
-bool DxaEncoder::m12blocksAreEqual(byte *frame, int x, int y, int x2, int y2) {
+bool DxaEncoder::m13blocksAreEqual(byte *frame, int x, int y, int x2, int y2, int w, int h) {
byte *b1 = _prevframe + x + y * _width;
byte *b2 = frame + x2 + y2 * _width;
- for (int yc = 0; yc < BLOCKH; yc++) {
- if (memcmp(b1, b2, BLOCKW))
+ for (int yc = 0; yc < h; yc++) {
+ if (memcmp(b1, b2, w))
return false;
b1 += _width;
b2 += _width;
@@ -256,11 +256,11 @@
return true;
}
-bool DxaEncoder::m12blockIsSolidColor(byte *frame, int x, int y, byte &color) {
+bool DxaEncoder::m13blockIsSolidColor(byte *frame, int x, int y, int w, int h, byte &color) {
byte *b2 = frame + x + y * _width;
color = *b2;
- for (int yc = 0; yc < BLOCKH; yc++) {
- for (int xc = 0; xc < BLOCKW; xc++) {
+ for (int yc = 0; yc < h; yc++) {
+ for (int xc = 0; xc < w; xc++) {
if (b2[xc] != color)
return false;
}
@@ -269,18 +269,18 @@
return true;
}
-void DxaEncoder::m12blockDelta(byte *frame, int x, int y, unsigned short &diffMap, int &diffCount, byte diffPix[]) {
+void DxaEncoder::m13blockDelta(byte *frame, int x, int y, int x2, int y2, DiffStruct &diff) {
byte *b1 = _prevframe + x + y * _width;
- byte *b2 = frame + x + y * _width;
- diffCount = 0;
- diffMap = 0;
+ byte *b2 = frame + x2 + y2 * _width;
+ diff.count = 0;
+ diff.map = 0;
for (int yc = 0; yc < BLOCKH; yc++) {
for (int xc = 0; xc < BLOCKW; xc++) {
if (b1[xc] != b2[xc]) {
- diffMap = (diffMap << 1) | 1;
- diffPix[diffCount++] = b2[xc];
+ diff.map = (diff.map << 1) | 1;
+ diff.pixels[diff.count++] = b2[xc];
} else {
- diffMap = (diffMap << 1) | 0;
+ diff.map = (diff.map << 1) | 0;
}
}
b1 += _width;
@@ -288,14 +288,14 @@
}
}
-bool DxaEncoder::m12motionVector(byte *frame, int x, int y, int &mx, int &my) {
+bool DxaEncoder::m13motionVector(byte *frame, int x, int y, int w, int h, int &mx, int &my) {
int xmin = (0 > x-7) ? 0 : x-7;
int ymin = (0 > y-7) ? 0 : y-7;
int xmax = (_width < x+8) ? _width : x+8;
- int ymax = (_height < y+8) ? _height : y+8;
+ int ymax = (_workheight < y+8) ? _height : y+8;
for (int yc = ymin; yc < ymax; yc++) {
for (int xc = xmin; xc < xmax; xc++) {
- if (m12blocksAreEqual(frame, xc, yc, x, y)) {
+ if (m13blocksAreEqual(frame, xc, yc, x, y, w, h)) {
mx = xc - x;
my = yc - y;
return true;
@@ -305,85 +305,236 @@
return false;
}
-uLong DxaEncoder::m12encode(byte *frame, byte *outbuf) {
+int DxaEncoder::m13countColors(byte *block, byte *pixels, unsigned long &code, int &codeSize) {
+
+ code = 0;
+ codeSize = 0;
+
+ /* count the number of colors used in this block */
+ int count = 0;
+ int colTab[256];
+ for (int i = 0; i < 256; i++)
+ colTab[i] = -1;
+
+ for (int i = 0; i < BLOCKW * BLOCKH; i++) {
+ if (colTab[block[i]] == -1) {
+ colTab[block[i]] = count;
+ pixels[count] = block[i];
+ count++;
+ }
+ }
+
+ if (count <= 4) {
+ /* set the bitmask */
+ if (count == 2) {
+ for (int i = 15; i >= 0; i--) {
+ code = (code << 1) | colTab[block[i]];
+ }
+ codeSize = 2;
+ } else if (count == 4 || count == 3) {
+ for (int i = 15; i >= 0; i--) {
+ code = (code << 2) | colTab[block[i]];
+ }
+ codeSize = 4;
+ }
+ }
+
+ return count;
+}
+
+/* grab the block */
+void DxaEncoder::grabBlock(byte *frame, int x, int y, int blockw, int blockh, byte *block) {
+ byte *b2 = (byte*)frame + x + y * _width;
+ for (int yc = 0; yc < blockh; yc++) {
+ memcpy(&block[yc*blockw], b2, blockw);
+ b2 += _width;
+ }
+}
+
+uLong DxaEncoder::m13encode(byte *frame, byte *outbuf) {
+
+ byte *codeB = _codeBuf;
+ byte *dataB = _dataBuf;
+ byte *motB = _motBuf;
+ byte *maskB = _maskBuf;
+
byte *outb = outbuf;
byte color;
int mx, my;
- unsigned short diffMap;
- int diffCount;
- byte diffPix[BLOCKW*BLOCKH];
+ DiffStruct diff;
- for (int by = 0; by < _height; by += BLOCKH) {
+ memset(_codeBuf, 0, _width * _height / 16);
+ memset(_dataBuf, 0, _width * _height);
+ memset(_motBuf, 0, _width * _height);
+ memset(_maskBuf, 0, _width * _height);
+
+ for (int by = 0; by < _workheight; by += BLOCKH) {
for (int bx = 0; bx < _width; bx += BLOCKW) {
- if (m12blocksAreEqual(frame, bx, by, bx, by)) {
- *outb++ = 0;
+ if (m13blocksAreEqual(frame, bx, by, bx, by, BLOCKW, BLOCKH)) {
+ *codeB++ = 0;
continue;
}
- if (m12blockIsSolidColor(frame, bx, by, color)) {
- *outb++ = 2;
- *outb++ = color;
+ if (m13blockIsSolidColor(frame, bx, by, BLOCKW, BLOCKH, color)) {
+ *codeB++ = 2;
+ *dataB++ = color;
continue;
}
- if (m12motionVector(frame, bx, by, mx, my)) {
- byte mbyte = 0;
- if (mx < 0) mbyte |= 0x80;
- mbyte |= (abs(mx) & 7) << 4;
- if (my < 0) mbyte |= 0x08;
- mbyte |= abs(my) & 7;
- *outb++ = 4;
- *outb++ = mbyte;
+ if (m13motionVector(frame, bx, by, BLOCKW, BLOCKH, mx, my)) {
+ /* motion vector */
+ byte motionByte = 0;
+ if (mx < 0) motionByte |= 0x80;
+ motionByte |= (abs(mx) & 7) << 4;
+ if (my < 0) motionByte |= 0x08;
+ motionByte |= abs(my) & 7;
+ *codeB++ = 4;
+ *motB++ = motionByte;
continue;
}
- m12blockDelta(frame, bx, by, diffMap, diffCount, diffPix);
+ byte subMask = 0;
+ byte subMot[4], subData[16];
+ int subMotSize = 0, subDataSize = 0;
- if (diffCount >= 14) {
- // in this case we store all 16 pixels
- *outb++ = 3;
- byte *b2 = (byte*)frame + bx + by * _width;
- for (int yc = 0; yc < BLOCKH; yc++) {
- memcpy(outb, b2, BLOCKW);
- b2 += _width;
- outb += BLOCKW;
+ static const int subX[4] = {0, 2, 0, 2};
+ static const int subY[4] = {0, 0, 2, 2};
+
+ /* 0: skip
+ 1: solid color (+ data byte)
+ 2: motion vector (+ mot byte)
+ 3: raw block (+ 4 data bytes)
+ */
+
+ for (int subBlock = 0; subBlock < 4; subBlock++) {
+
+ int sx = bx + subX[subBlock], sy = by + subY[subBlock];
+ byte scolor;
+ int smx, smy;
+
+ if (m13blocksAreEqual(frame, sx, sy, sx, sy, BLOCKW/2, BLOCKH/2)) {
+ subMask = (subMask << 2) | 0;
+ continue;
}
- continue;
- } else {
- static const struct { uint16 mask; uint8 sh1, sh2; } maskTbl[6] = {
- {0xFF00, 0, 0},
- {0x0FF0, 8, 0},
- {0x00FF, 8, 8},
- {0x0F0F, 8, 4},
- {0xF0F0, 4, 0},
- {0xF00F, 4, 4}
- };
- bool smallMask = false;
+ if (m13blockIsSolidColor(frame, sx, sy, BLOCKW/2, BLOCKH/2, scolor)) {
+ subData[subDataSize++] = scolor;
+ subMask = (subMask << 2) | 1;
+ continue;
+ }
- // here we check if the difference bitmap can be stored in only one byte
- for (int m = 0; m < 6; m++) {
- if ((diffMap & maskTbl[m].mask) == 0) {
- smallMask = true;
- *outb++ = 10 + m;
- *outb++ = ((diffMap >> maskTbl[m].sh1) & 0xF0) | ((diffMap >> maskTbl[m].sh2) & 0x0F);
- break;
- }
+ if (m13motionVector(frame, sx, sy, BLOCKW/2, BLOCKH/2, smx, smy)) {
+ byte motionByte = 0;
+ if (smx < 0) motionByte |= 0x80;
+ motionByte |= (abs(smx) & 7) << 4;
+ if (smy < 0) motionByte |= 0x08;
+ motionByte |= abs(smy) & 7;
+ subMot[subMotSize++] = motionByte;
+ subMask = (subMask << 2) | 2;
+ continue;
}
- if (!smallMask) {
- *outb++ = 1;
- *(unsigned short*)outb = diffMap;
- outb += 2;
+ byte *b2 = (byte*)frame + sx + sy * _width;
+ for (int yc = 0; yc < BLOCKH/2; yc++) {
+ memcpy(&subData[subDataSize], b2, BLOCKW/2);
+ subDataSize += BLOCKW/2;
+ b2 += _width;
}
- memcpy(outb, diffPix, diffCount);
- outb += diffCount;
- continue;
+ subMask = (subMask << 2) | 3;
}
+
+ int blockSize = 0;
+
+ m13blockDelta(frame, bx, by, bx, by, diff);
+
+ byte block[16];
+ grabBlock(frame, bx, by, BLOCKW, BLOCKW, block);
+
+ unsigned long code;
+ int codeSize;
+ byte pixels[16];
+ int count = m13countColors(block, pixels, code, codeSize);
+
+ int countColorsSize = 1000;
+ if (count == 2)
+ countColorsSize = 4; // 2 bytes mask, 2 pixels
+ else if (count <= 4)
+ countColorsSize = 4 + count; // 4 bytes mask, count pixels
+
+ if (countColorsSize < diff.count + 2) {
+ blockSize = countColorsSize;
+ } else {
+ if (diff.count <= 12) {
+ blockSize = 2 + diff.count;
+ } else {
+ blockSize = 16;
+ }
+ }
+
+ if (1 + subMotSize + subDataSize < blockSize) {
+ /* store subblocks */
+ *codeB++ = 8;
+ *maskB++ = subMask;
+ memcpy(dataB, subData, subDataSize);
+ dataB += subDataSize;
+ memcpy(motB, subMot, subMotSize);
+ motB += subMotSize;
+ } else {
+ /* store full block */
+ if (countColorsSize < diff.count + 2) {
+ /* write the pixel values */
+ *codeB++ = 30 + count;
+ memcpy(dataB, pixels, count);
+ dataB += count;
+ memcpy(maskB, &code, codeSize);
+ maskB += codeSize;
+ } else {
+ if (diff.count <= 12) {
+ /* difference map */
+ *codeB++ = 1;
+ *(uint16*)maskB = diff.map;
+ maskB += 2;
+ memcpy(dataB, diff.pixels, diff.count);
+ dataB += diff.count;
+ } else {
+ /* write the whole block */
+ *codeB++ = 3;
+ memcpy(dataB, block, 16);
+ dataB += 16;
+ }
+ }
+ }
}
}
+ outb = outbuf;
+
+ int size;
+
+ size = dataB - _dataBuf;
+ memcpy(outb, &size, 4);
+ outb += 4;
+ size = motB - _motBuf;
+ memcpy(outb, &size, 4);
+ outb += 4;
+ size = maskB - _maskBuf;
+ memcpy(outb, &size, 4);
+ outb += 4;
+
+ /* this size is always constant throughout a DXA */
+ memcpy(outb, _codeBuf, codeB - _codeBuf);
+ outb += codeB - _codeBuf;
+
+ memcpy(outb, _dataBuf, dataB - _dataBuf);
+ outb += dataB - _dataBuf;
+
+ memcpy(outb, _motBuf, motB - _motBuf);
+ outb += motB - _motBuf;
+
+ memcpy(outb, _maskBuf, maskB - _maskBuf);
+ outb += maskB - _maskBuf;
+
return outb - outbuf;
}
@@ -469,13 +620,17 @@
return 0;
}
-void readVideoInfo(char *filename, int &width, int &height, int &framerate, int &frames) {
+void readVideoInfo(char *filename, int &width, int &height, int &framerate, int &frames,
+ ScaleMode &scaleMode) {
+
FILE *smk = fopen(filename, "rb");
if (!smk) {
printf("readVideoInfo: Can't open file: %s\n", filename);
exit(-1);
}
+ scaleMode = S_NONE;
+
char buf[4];
fread(buf, 1, 4, smk);
if (!memcmp(buf, "BIK", 3)) {
@@ -503,7 +658,12 @@
// If the Y-interlaced or Y-doubled flag is set, the RAD Video Tools
// will have scaled the frames to twice their original height.
- if ((flags & 0x02) || (flags & 0x04))
+ if (flags & 0x02)
+ scaleMode = S_INTERLACED;
+ else if (flags & 0x04)
+ scaleMode = S_DOUBLE;
+
+ if (scaleMode != S_NONE)
height *= 2;
} else {
error("readVideoInfo: Unknown type");
@@ -577,7 +737,8 @@
char strbuf[512];
int width, height, framerate, frames;
-
+ ScaleMode scaleMode;
+
/* compression mode */
gCompMode = kMP3Mode;
int i = 1;
@@ -634,14 +795,14 @@
}
// read some data from the Bink or Smacker file.
- readVideoInfo(filename, width, height, framerate, frames);
+ readVideoInfo(filename, width, height, framerate, frames, scaleMode);
printf("Width = %d, Height = %d, Framerate = %d, Frames = %d\n",
width, height, framerate, frames);
// create the encoder object
sprintf(strbuf, "%s.dxa", prefix);
- DxaEncoder dxe(strbuf, width, height, framerate);
+ DxaEncoder dxe(strbuf, width, height, framerate, scaleMode);
// No sound block
dxe.writeNULL();
@@ -671,7 +832,17 @@
}
if (!r) {
- dxe.writeFrame(image, palette);
+ if (scaleMode != S_NONE) {
+ byte *unscaledImage = new byte[width * height / 2];
+
+ for (int y = 0; y < height; y += 2)
+ memcpy(&unscaledImage[(width*y)/2], &image[width*y], width);
+
+ dxe.writeFrame(unscaledImage, palette);
+ delete[] unscaledImage;
+ } else {
+ dxe.writeFrame(image, palette);
+ }
}
if (image) delete[] image;
@@ -679,7 +850,7 @@
if (r)
break;
-
+
framenum++;
if (framenum % 20 == 0) {
@@ -687,10 +858,8 @@
fflush(stdout);
}
}
-
+
printf("\rEncoding video...100%% (%d of %d)\n", frames, frames);
-
+
return 0;
}
-
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list