[Scummvm-cvs-logs] scummvm master -> 3becde4d1a7557e25292485380a0df4591544a52
bgK
bastien.bouclet at gmail.com
Thu Feb 9 16:19:52 CET 2012
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9d85382c15 VIDEO: Fix the BINK decoder to play file whose width is 24px
577635acf2 AUDIO: Add support for RAW PCM wave stream with an incomplete packet
de0425c7e2 GRAPHICS: Add support for JPEG files using a restart interval
3becde4d1a GRAPHICS: Switch to integer based JPEG IDCT
Commit: 9d85382c153bd4bcb58b7683f4d06658bf18c4d7
https://github.com/scummvm/scummvm/commit/9d85382c153bd4bcb58b7683f4d06658bf18c4d7
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-02-09T07:10:47-08:00
Commit Message:
VIDEO: Fix the BINK decoder to play file whose width is 24px
See https://ffmpeg.org/trac/ffmpeg/ticket/962
Changed paths:
video/bink_decoder.cpp
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index c5dc5f2..884ca69 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -717,15 +717,15 @@ void BinkDecoder::initBundles() {
for (int i = 0; i < 2; i++) {
int width = MAX<uint32>(cw[i], 8);
- _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2((width >> 4) + 511) + 1;
- _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i] )*64 + 511) + 1;
- _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
- _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i] )*48 + 511) + 1;
+ _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2(((width + 7) >> 4) + 511) + 1;
+ _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i]) * 64 + 511) + 1;
+ _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
+ _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i]) * 48 + 511) + 1;
}
}
Commit: 577635acf2d831240e6d83906f4f17f5b7600ac6
https://github.com/scummvm/scummvm/commit/577635acf2d831240e6d83906f4f17f5b7600ac6
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-02-09T07:10:50-08:00
Commit Message:
AUDIO: Add support for RAW PCM wave stream with an incomplete packet
The last incomplete packet is ignored
Changed paths:
audio/decoders/wave.cpp
diff --git a/audio/decoders/wave.cpp b/audio/decoders/wave.cpp
index 3cf4566..44188f8 100644
--- a/audio/decoders/wave.cpp
+++ b/audio/decoders/wave.cpp
@@ -175,6 +175,13 @@ RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, Dispose
else if (type == 2) // MS ADPCM
return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);
+ // Raw PCM, make sure the last packet is complete
+ uint sampleSize = (flags & Audio::FLAG_16BITS ? 2 : 1) * (flags & Audio::FLAG_STEREO ? 2 : 1);
+ if (size % sampleSize != 0) {
+ warning("makeWAVStream: Trying to play a WAVE file with an incomplete PCM packet");
+ size &= ~(sampleSize - 1);
+ }
+
// Raw PCM. Just read everything at once.
// TODO: More elegant would be to wrap the stream.
byte *data = (byte *)malloc(size);
Commit: de0425c7e2778230c9b6df3681ae6bd9c292ba64
https://github.com/scummvm/scummvm/commit/de0425c7e2778230c9b6df3681ae6bd9c292ba64
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-02-09T07:10:51-08:00
Commit Message:
GRAPHICS: Add support for JPEG files using a restart interval
Patch by Scott and clone2727
Changed paths:
graphics/jpeg.cpp
graphics/jpeg.h
diff --git a/graphics/jpeg.cpp b/graphics/jpeg.cpp
index 8809477..9a1a35e 100644
--- a/graphics/jpeg.cpp
+++ b/graphics/jpeg.cpp
@@ -113,6 +113,7 @@ void JPEG::reset() {
// Reset member variables
_stream = NULL;
_w = _h = 0;
+ _restartInterval = 0;
// Free the components
for (int c = 0; c < _numComp; c++)
@@ -208,12 +209,18 @@ bool JPEG::read(Common::SeekableReadStream *stream) {
case 0xE0: // JFIF/JFXX segment
ok = readJFIF();
break;
+ case 0xDD: // Define Restart Interval
+ ok = readDRI();
+ break;
case 0xFE: // Comment
_stream->seek(_stream->readUint16BE() - 2, SEEK_CUR);
break;
default: { // Unknown marker
uint16 size = _stream->readUint16BE();
- warning("JPEG: Unknown marker %02X, skipping %d bytes", marker, size - 2);
+
+ if ((marker & 0xE0) != 0xE0)
+ warning("JPEG: Unknown marker %02X, skipping %d bytes", marker, size - 2);
+
_stream->seek(size - 2, SEEK_CUR);
}
}
@@ -234,8 +241,10 @@ bool JPEG::readJFIF() {
}
byte majorVersion = _stream->readByte();
byte minorVersion = _stream->readByte();
- if (majorVersion != 1 || minorVersion != 1)
- warning("JPEG::readJFIF() Non-v1.1 JPEGs may not be handled correctly");
+
+ if (majorVersion != 1 || (minorVersion != 1 && minorVersion != 2))
+ warning("JPEG::readJFIF() Non-v1.1/1.2 JPEGs may not be handled correctly");
+
/* byte densityUnits = */ _stream->readByte();
/* uint16 xDensity = */ _stream->readUint16BE();
/* uint16 yDensity = */ _stream->readUint16BE();
@@ -445,10 +454,28 @@ bool JPEG::readSOS() {
}
bool ok = true;
- for (int y = 0; ok && (y < yMCU); y++)
- for (int x = 0; ok && (x < xMCU); x++)
+ uint16 interval = _restartInterval;
+
+ for (int y = 0; ok && (y < yMCU); y++) {
+ for (int x = 0; ok && (x < xMCU); x++) {
ok = readMCU(x, y);
+ // If we have a restart interval, we'll need to reset a couple
+ // variables
+ if (_restartInterval != 0) {
+ interval--;
+
+ if (interval == 0) {
+ interval = _restartInterval;
+ _bitsNumber = 0;
+
+ for (byte i = 0; i < _numScanComp; i++)
+ _scanComp[i]->DCpredictor = 0;
+ }
+ }
+ }
+ }
+
// Trim Component surfaces back to image height and width
// Note: Code using jpeg must use surface.pitch correctly...
for (uint16 c = 0; c < _numScanComp; c++) {
@@ -489,6 +516,21 @@ bool JPEG::readDQT() {
return true;
}
+// Marker 0xDD (Define Restart Interval)
+bool JPEG::readDRI() {
+ debug(5, "JPEG: readDRI");
+ uint16 size = _stream->readUint16BE() - 2;
+
+ if (size != 2) {
+ warning("JPEG: Invalid DRI size %d", size);
+ return false;
+ }
+
+ _restartInterval = _stream->readUint16BE();
+ debug(5, "Restart interval: %d", _restartInterval);
+ return true;
+}
+
bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
bool ok = true;
for (int c = 0; ok && (c < _numComp); c++) {
@@ -647,7 +689,8 @@ void JPEG::readAC(int16 *out) {
int16 JPEG::readSignedBits(uint8 numBits) {
uint16 ret = 0;
- if (numBits > 16) error("requested %d bits", numBits); //XXX
+ if (numBits > 16)
+ error("requested %d bits", numBits); //XXX
// MSB=0 for negatives, 1 for positives
for (int i = 0; i < numBits; i++)
@@ -708,6 +751,9 @@ uint8 JPEG::readBit() {
// DNL marker: Define Number of Lines
// TODO: terminate scan
warning("DNL marker detected: terminate scan");
+ } else if (byte2 >= 0xD0 && byte2 <= 0xD7) {
+ debug(7, "RST%d marker detected", byte2 & 7);
+ _bitsData = _stream->readByte();
} else {
warning("Error: marker 0x%02X read in entropy data", byte2);
}
diff --git a/graphics/jpeg.h b/graphics/jpeg.h
index 27b91e8..9268cb7 100644
--- a/graphics/jpeg.h
+++ b/graphics/jpeg.h
@@ -54,6 +54,7 @@ private:
Common::SeekableReadStream *_stream;
uint16 _w, _h;
+ uint16 _restartInterval;
// Image components
uint8 _numComp;
@@ -101,6 +102,7 @@ private:
bool readDHT();
bool readSOS();
bool readDQT();
+ bool readDRI();
// Helper functions
bool readMCU(uint16 xMCU, uint16 yMCU);
Commit: 3becde4d1a7557e25292485380a0df4591544a52
https://github.com/scummvm/scummvm/commit/3becde4d1a7557e25292485380a0df4591544a52
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-02-09T07:10:51-08:00
Commit Message:
GRAPHICS: Switch to integer based JPEG IDCT
Based on public domain code, and explanations from :
http://halicery.com/jpeg/idct.html
Thanks.
Changed paths:
graphics/jpeg.cpp
graphics/jpeg.h
diff --git a/graphics/jpeg.cpp b/graphics/jpeg.cpp
index 9a1a35e..53e693a 100644
--- a/graphics/jpeg.cpp
+++ b/graphics/jpeg.cpp
@@ -43,20 +43,6 @@ static const uint8 _zigZagOrder[64] = {
53, 60, 61, 54, 47, 55, 62, 63
};
-// IDCT table built with :
-// _idct8x8[x][y] = cos(((2 * x + 1) * y) * (M_PI / 16.0)) * 0.5;
-// _idct8x8[x][y] /= sqrt(2.0) if y == 0
-static const double _idct8x8[8][8] = {
- { 0.353553390593274, 0.490392640201615, 0.461939766255643, 0.415734806151273, 0.353553390593274, 0.277785116509801, 0.191341716182545, 0.097545161008064 },
- { 0.353553390593274, 0.415734806151273, 0.191341716182545, -0.097545161008064, -0.353553390593274, -0.490392640201615, -0.461939766255643, -0.277785116509801 },
- { 0.353553390593274, 0.277785116509801, -0.191341716182545, -0.490392640201615, -0.353553390593274, 0.097545161008064, 0.461939766255643, 0.415734806151273 },
- { 0.353553390593274, 0.097545161008064, -0.461939766255643, -0.277785116509801, 0.353553390593274, 0.415734806151273, -0.191341716182545, -0.490392640201615 },
- { 0.353553390593274, -0.097545161008064, -0.461939766255643, 0.277785116509801, 0.353553390593274, -0.415734806151273, -0.191341716182545, 0.490392640201615 },
- { 0.353553390593274, -0.277785116509801, -0.191341716182545, 0.490392640201615, -0.353553390593273, -0.097545161008064, 0.461939766255643, -0.415734806151273 },
- { 0.353553390593274, -0.415734806151273, 0.191341716182545, 0.097545161008064, -0.353553390593274, 0.490392640201615, -0.461939766255643, 0.277785116509801 },
- { 0.353553390593274, -0.490392640201615, 0.461939766255643, -0.415734806151273, 0.353553390593273, -0.277785116509801, 0.191341716182545, -0.097545161008064 }
-};
-
JPEG::JPEG() :
_stream(NULL), _w(0), _h(0), _numComp(0), _components(NULL), _numScanComp(0),
_scanComp(NULL), _currentComp(NULL) {
@@ -546,40 +532,63 @@ bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
return ok;
}
-void JPEG::idct8x8(float result[64], const int16 dct[64]) {
- float tmp[64];
+// triple-butterfly-add (and possible rounding)
+#define xadd3(xa, xb, xc, xd, h) \
+ p = xa + xb; \
+ n = xa - xb; \
+ xa = p + xc + h; \
+ xb = n + xd + h; \
+ xc = p - xc + h; \
+ xd = n - xd + h;
+
+// butterfly-mul
+#define xmul(xa, xb, k1, k2, sh) \
+ n = k1 * (xa + xb); \
+ p = xa; \
+ xa = (n + (k2 - k1) * xb) >> sh; \
+ xb = (n - (k2 + k1) * p) >> sh;
+
+// IDCT based on public domain code from http://halicery.com/jpeg/idct.html
+void JPEG::idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half) {
+ int p, n;
+
+ src[0] <<= 9;
+ src[1] <<= 7;
+ src[3] *= 181;
+ src[4] <<= 9;
+ src[5] *= 181;
+ src[7] <<= 7;
+
+ // Even part
+ xmul(src[6], src[2], 277, 669, 0)
+ xadd3(src[0], src[4], src[6], src[2], half)
+
+ // Odd part
+ xadd3(src[1], src[7], src[3], src[5], 0)
+ xmul(src[5], src[3], 251, 50, 6)
+ xmul(src[1], src[7], 213, 142, 6)
+
+ dest[0 * 8] = (src[0] + src[1]) >> ps;
+ dest[1 * 8] = (src[4] + src[5]) >> ps;
+ dest[2 * 8] = (src[2] + src[3]) >> ps;
+ dest[3 * 8] = (src[6] + src[7]) >> ps;
+ dest[4 * 8] = (src[6] - src[7]) >> ps;
+ dest[5 * 8] = (src[2] - src[3]) >> ps;
+ dest[6 * 8] = (src[4] - src[5]) >> ps;
+ dest[7 * 8] = (src[0] - src[1]) >> ps;
+}
- // Apply 1D IDCT to rows
- for (int y = 0; y < 8; y++) {
- for (int x = 0; x < 8; x++) {
- tmp[y + x * 8] = dct[0] * _idct8x8[x][0]
- + dct[1] * _idct8x8[x][1]
- + dct[2] * _idct8x8[x][2]
- + dct[3] * _idct8x8[x][3]
- + dct[4] * _idct8x8[x][4]
- + dct[5] * _idct8x8[x][5]
- + dct[6] * _idct8x8[x][6]
- + dct[7] * _idct8x8[x][7];
- }
+void JPEG::idct2D8x8(int32 block[64]) {
+ int32 tmp[64];
- dct += 8;
- }
+ // Apply 1D IDCT to rows
+ for (int i = 0; i < 8; i++)
+ idct1D8x8(&block[i * 8], &tmp[i], 9, 1 << 8);
// Apply 1D IDCT to columns
- for (int x = 0; x < 8; x++) {
- const float *u = tmp + x * 8;
- for (int y = 0; y < 8; y++) {
- result[y * 8 + x] = u[0] * _idct8x8[y][0]
- + u[1] * _idct8x8[y][1]
- + u[2] * _idct8x8[y][2]
- + u[3] * _idct8x8[y][3]
- + u[4] * _idct8x8[y][4]
- + u[5] * _idct8x8[y][5]
- + u[6] * _idct8x8[y][6]
- + u[7] * _idct8x8[y][7];
- }
- }
-}
+ for (int i = 0; i < 8; i++)
+ idct1D8x8(&tmp[i * 8], &block[i], 12, 1 << 11);
+ }
bool JPEG::readDataUnit(uint16 x, uint16 y) {
// Prepare an empty data array
@@ -595,30 +604,29 @@ bool JPEG::readDataUnit(uint16 x, uint16 y) {
readAC(readData);
// Calculate the DCT coefficients from the input sequence
- int16 DCT[64];
+ int32 block[64];
for (uint8 i = 0; i < 64; i++) {
// Dequantize
- int16 val = readData[i];
+ int32 val = readData[i];
int16 quant = _quant[_currentComp->quantTableSelector][i];
val *= quant;
// Store the normalized coefficients, undoing the Zig-Zag
- DCT[_zigZagOrder[i]] = val;
+ block[_zigZagOrder[i]] = val;
}
// Apply the IDCT
- float result[64];
- idct8x8(result, DCT);
+ idct2D8x8(block);
// Level shift to make the values unsigned
for (int i = 0; i < 64; i++) {
- result[i] = result[i] + 128;
+ block[i] = block[i] + 128;
- if (result[i] < 0)
- result[i] = 0;
+ if (block[i] < 0)
+ block[i] = 0;
- if (result[i] > 255)
- result[i] = 255;
+ if (block[i] > 255)
+ block[i] = 255;
}
// Paint the component surface
@@ -636,7 +644,7 @@ bool JPEG::readDataUnit(uint16 x, uint16 y) {
for (uint8 i = 0; i < 8; i++) {
for (uint16 sH = 0; sH < scalingH; sH++) {
- *ptr = (byte)(result[j * 8 + i]);
+ *ptr = (byte)(block[j * 8 + i]);
ptr++;
}
}
diff --git a/graphics/jpeg.h b/graphics/jpeg.h
index 9268cb7..b877914 100644
--- a/graphics/jpeg.h
+++ b/graphics/jpeg.h
@@ -118,7 +118,8 @@ private:
uint8 _bitsNumber;
// Inverse Discrete Cosine Transformation
- void idct8x8(float dst[64], const int16 src[64]);
+ static void idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half);
+ static void idct2D8x8(int32 block[64]);
};
} // End of Graphics namespace
More information about the Scummvm-git-logs
mailing list