我正在尝试为DOS游戏中使用的旧视频格式(Psygnosis SMV视频格式)编写解码器,但是我很难理解图像解码过程,尤其是本节:

Macroblocks drawing

Macroblocks are stored in the following format:

 u8 pixels[16 * num_mblocks]
 u4 nibbles[num_mblocks]

Size of pixels[] is equal to ST chunk's nibbles.
For each macroblock draw it by indexing its pixels by nibbles.
First nibble stored in top 4 bits of byte.


这是我要解码的帧的属性:


图像宽度= 320
图像高度= 192
宏块宽度= 16
宏块高度= 16
半字节= 3840
以字节为单位的帧大小= 34560

因此,根据这些,我计算出以下值: >
num_mblocks = nibbles / 16 = 3840 / 16 = 240 macroblocks

further checking:
(image width / macroblock width) * (image height / macroblock height)
= (320 / 16) * (192 / 16)
= 20 * 12
= 240 macroblocks


第一个问题:

u8 pixels[16 * num_mblocks]的大小确实为3840字节,但是u4 nibbles[num_mblocks]的大小应该是多少?第二个问题:

,因为类型是u4,所以需要240个字节或一半的数量? (34560/240 = 144),但是对我来说,这与预期的相去甚远,我想我在某个地方错了。作者写道:

对于每个宏块,通过用半字节对其像素进行索引来绘制它。 >
您能解释一下如何解码一帧吗?

#1 楼

注意:这是一个可能正确或不正确的假设;我尚未针对任何真实文件进行测试。

文件格式的创建者似乎一直在尝试节省空间。他们想编码256种颜色(“编码8位调色视频”),因此每个像素需要一个字节。但是,屏幕的某个较小区域可能会重复包含相同颜色的像素。因此,我想说每个宏块只能包含16种不同的颜色,可以用4位/一个半字节来表示。调色板表,每个需要1字节。接下来是每个像素1个半字节,它是u8 pixels[16 * num_mblocks]的索引。可能看起来像这样:(很抱歉,一些颜色名称;我用不了5个字符的名称...)

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
+  1  +  2  +  3  +  4  +  5  +  6  +  7  +  8  +  9  +  A  +  B  +  C  +  D  +  E  +  F  +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
| red |green|blue |yellw|magnt|cyan |grey |black|orang|gold |aqua |azure|ivory|plum |wheat|
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----


接下来,您需要每个像素一个半字节,这是该表的索引。因此,字节CA 53 2D将代表6个像素,分别是天蓝色,金色,洋红色,蓝色,绿色和象牙色。

因此,对于256个像素的宏块,像素表需要16个字节,而256个像素/ 2 = 128字节的像素。总计为您计算的144。 pixels可能是错误的,应该是u4 nibbles[num_mblocks]

评论


谢谢,我一直在用您的答案进行挖掘,但是,我的图片不正确……我开始怀疑我对LZ77式解压缩的实现,并决定以最简单的格式进行攻击:解压缩打包的音乐块;虽然算法产生了确切的字节数,但是内容是错误的……我实际上正在为这部分苦苦挣扎!

–aybe
16年11月16日在21:10