JV

From MultimediaWiki

(Difference between revisions)
Jump to: navigation, search
Revision as of 21:31, 29 March 2008
Suxen drol (Talk | contribs)
(cat)
← Previous diff
Revision as of 14:30, 6 March 2011
VAG (Talk | contribs)
(rewrite)
Next diff →
Line 3: Line 3:
* Samples: TBD * Samples: TBD
-JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game [http://www.mobygames.com/game/dos/z Z]. No other games are known to use this format.+JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game [http://www.mobygames.com/game/dos/z Z]. No other games are known to use this format. Carries palettized video using [[BTC]] encoding and [[PCM]] audio.
-==File Structure==+== File Format ==
-Files consist of a fixed-length header, followed by an index table, and the+
- 0x0000 70 bytes ASCIIZ "JV00 Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."+Files consist of a fixed-length header, followed by an index table, and then frame chunks. All numbers are little-endian.
- 0x0050 le_u16 frame width (pixels)+
- 0x0052 le_u16 frame height (pixels)+
- 0x0054 le_u16 total frame count+
- 0x0056 le_u16 always 0x50+
- 0x0058 le_u16 always 0x01+
- 0x005a le_u16 always 0x02+
- 0x005c le_u16 audio samples per second (22050 observed)+
- 0x0060 7 bytes always zero+
- 0x0067 u8 always non-zero+
-The frame index table begins at offset 0x68, and contains an index record for each frame. The size of the table can be calculated using the total frame count field.+File header (0x68 bytes):
- le_u32 - total frame length (octets)+ u8 sig[2] -- File signature, "JV"
- le_u32 - audio chunk length (octets)+ u8 palmode1 -- Initial palette mode. 'W' - all White, '0' (or any
- le_u32 - video chunk length (octets)+ other value) - Black. (Un)used for fade-in effect
- le_u16 - unknown+ u8 palmode2 -- Final palette mode. Same as above, but fade-out
- le_u16 - unknown+ u8 copyright[0x4C]; -- "Compression by John M Phillips"... bla-bla
 + s16 width; -- Frame width
 + s16 height; -- Frame height
 + s16 frames; -- Number of frames
 + s16 rate; -- Frame rate. Delay between successive frames in ms
 + s32 maxchunk; -- Maximal size of a single frame chunk
 + s32 freq; -- Audio frequency
 + u8 flags0:1; -- ?
 + u8 volume:7; -- Default sound volume (0 - max)
 + u8 unused[6];
 + u8 flags1:3; -- Number of fade-in frames?
 + u8 flags2:3; -- ?
 + u8 flags3:1; -- ?
 + u8 flags4:1; -- ?
-Frame data is stored immediately follows the header, where each frame corresonds to an entry in the index table. Each frame comprises an audio chunk followed immediately by a video chunk. The length of the audio and video data corresponds to the value indicated in the index record. Video chunks may sometimes be zero length. Frames sometimes contain additional unknown data (suspected to be padding), therefore the "total frame length" field must considered when parsing each frame.+File header is followed by frame index table, one entry per frame.
-==Audio Chunk==+Table entry format (0x10 bytes):
-Each audio chunk contains mono unsigned 8-bit PCM audio samples.+ s32 chunk_size; -- Size of the chunk data
 + s32 audio_size; -- Size of the audio portion of the frame
 + s32 video_size; -- Size of the video portion of the frame
 + s8 has_palette; -- New palette is present
 + s8 audio_type; -- Audio format. Always 0 - mono, 8-bit [[PCM]]
 + s8 video_type; -- Video compression method (see below)
 + s8 unused;
-==Video Chunk==+Finally, frame chunks follows.
-The compression algorithm is unknown.+Frama chunk format:
 + 
 + s8 audio[audio_size]; -- Audio data
 + RGB palette[256]; -- New palette (present only if has_palette flag is set)
 + s8 video[video_size]; -- Video data
 + s8 padding[]; -- sizeof(audio + palette + video + padding) == chunk_size
 + 
 +== Video compression ==
 + 
 +Depending on video_type value, frame can be encoded using the following way:
 + 
 +=== Type 0: Raw frame ===
 +Paint frame using the video data and continue with Type 1 decoding.
 +Apparently, someone forgot to put the "break" keyword here because additional decoding of the raw data seems redundant. Or perhaps it was originally planned to (losely) compress this block data somehow.
 + 
 +=== Type 1: BTC frame ===
 +Initialize a bit-reader using video data. Fill it with 8-bit values, fetch bits starting from the highest. Multi-byte values are read as byte0 = GetByte(), byte1 = GetByte(), etc.
 + 
 +Frame is encoded as a series of 8x8 blocks. To decode single block:
 + Read 2-bit block type:
 + 0: End. End of (sub)block decoding.
 + 1: Fill. Read 8 bits and use them to fill the (sub)block.
 + 2: BTC. Read color0 and color1, 8 bits each. Read mask. For each pixel of
 + (sub)block, if mask bit is set - paint it using color1. Use color0 if bit
 + is clear. Complete mask read first (4/16/64 bits) and processed from
 + its highest bit to lowest.
 + 3: Subblock. Split the block on 4 equal subblocks and process each one
 + separately using the same scheme recursively. If the subblock size is
 + already 2x2, paint it using the next 2 * 2 * 8 bits.
 + 
 +=== Type 2: Solid frame ===
 +Read 8-bit pixel value from video data and use it to fill the whole frame.
[[Category:Game Formats]] [[Category:Game Formats]]
[[Category:Undiscovered_Video_Codecs]] [[Category:Undiscovered_Video_Codecs]]

Revision as of 14:30, 6 March 2011

JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game Z. No other games are known to use this format. Carries palettized video using BTC encoding and PCM audio.

Contents

File Format

Files consist of a fixed-length header, followed by an index table, and then frame chunks. All numbers are little-endian.

File header (0x68 bytes):

 u8  sig[2]             -- File signature, "JV"
 u8  palmode1           -- Initial palette mode. 'W' - all White, '0' (or any
                           other value) - Black. (Un)used for fade-in effect
 u8  palmode2           -- Final palette mode. Same as above, but fade-out
 u8  copyright[0x4C];   -- "Compression by John M Phillips"... bla-bla
 s16 width;             -- Frame width
 s16 height;            -- Frame height
 s16 frames;            -- Number of frames
 s16 rate;              -- Frame rate. Delay between successive frames in ms
 s32 maxchunk;          -- Maximal size of a single frame chunk
 s32 freq;              -- Audio frequency
 u8  flags0:1;          -- ?
 u8  volume:7;          -- Default sound volume (0 - max)
 u8  unused[6];
 u8  flags1:3;          -- Number of fade-in frames?
 u8  flags2:3;          -- ?
 u8  flags3:1;          -- ?
 u8  flags4:1;          -- ?

File header is followed by frame index table, one entry per frame.

Table entry format (0x10 bytes):

 s32 chunk_size;        -- Size of the chunk data
 s32 audio_size;        -- Size of the audio portion of the frame
 s32 video_size;        -- Size of the video portion of the frame
 s8  has_palette;       -- New palette is present
 s8  audio_type;        -- Audio format. Always 0 - mono, 8-bit PCM
 s8  video_type;        -- Video compression method (see below)
 s8  unused;

Finally, frame chunks follows.

Frama chunk format:

 s8  audio[audio_size]; -- Audio data
 RGB palette[256];      -- New palette (present only if has_palette flag is set)
 s8  video[video_size]; -- Video data
 s8  padding[];         -- sizeof(audio + palette + video + padding) == chunk_size 

Video compression

Depending on video_type value, frame can be encoded using the following way:

Type 0: Raw frame

Paint frame using the video data and continue with Type 1 decoding. Apparently, someone forgot to put the "break" keyword here because additional decoding of the raw data seems redundant. Or perhaps it was originally planned to (losely) compress this block data somehow.

Type 1: BTC frame

Initialize a bit-reader using video data. Fill it with 8-bit values, fetch bits starting from the highest. Multi-byte values are read as byte0 = GetByte(), byte1 = GetByte(), etc.

Frame is encoded as a series of 8x8 blocks. To decode single block:

 Read 2-bit block type:
 0: End. End of (sub)block decoding.
 1: Fill. Read 8 bits and use them to fill the (sub)block.
 2: BTC. Read color0 and color1, 8 bits each. Read mask. For each pixel of
    (sub)block, if mask bit is set - paint it using color1. Use color0 if bit
    is clear. Complete mask read first (4/16/64 bits) and processed from
    its highest bit to lowest.
 3: Subblock. Split the block on 4 equal subblocks and process each one
    separately using the same scheme recursively. If the subblock size is
    already 2x2, paint it using the next 2 * 2 * 8 bits.

Type 2: Solid frame

Read 8-bit pixel value from video data and use it to fill the whole frame.

Personal tools