#define SUBBLOCK_SIZE 64
typedef void (*tile_line_emitter_t)(const int16_t *y, const int16_t *u, uint32_t address);
-typedef void (*std_macroblock_decoder_t)(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
+typedef void (*subblock_transform_t)(int16_t* dst, const int16_t* src);
/* rdram operations */
// FIXME: these functions deserve their own module
static void rdram_write_many_u32(const uint32_t *src, uint32_t address, unsigned int count);
/* standard jpeg ucode decoder */
-static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line);
+static void jpeg_decode_std(const char * const version,
+ const subblock_transform_t transform_luma,
+ const subblock_transform_t transform_chroma,
+ const tile_line_emitter_t emit_line);
/* helper functions */
static uint8_t clamp_u8(int16_t x);
static void EmitRGBATileLine(const int16_t *y, const int16_t *u, uint32_t address);
/* macroblocks operations */
-static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
-static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
-static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
+static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
+static void decode_macroblock_std(
+ const subblock_transform_t transform_luma,
+ const subblock_transform_t transform_chroma,
+ int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
static void EmitTilesMode0(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
static void EmitTilesMode2(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
**************************************************************************/
void jpeg_decode_PS0()
{
- jpeg_decode_std("PS0", DecodeMacroblock3, EmitYUVTileLine);
+ jpeg_decode_std("PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine);
}
/***************************************************************************
**************************************************************************/
void jpeg_decode_PS()
{
- jpeg_decode_std("PS", DecodeMacroblock2, EmitRGBATileLine);
+ jpeg_decode_std("PS", NULL, NULL, EmitRGBATileLine);
}
/***************************************************************************
int16_t macroblock[6*SUBBLOCK_SIZE];
rdram_read_many_u16((uint16_t*)macroblock, address, 6*SUBBLOCK_SIZE);
- DecodeMacroblock1(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL);
+ decode_macroblock_ob(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL);
EmitTilesMode2(EmitYUVTileLine, macroblock, address);
address += (2*6*SUBBLOCK_SIZE);
/* local functions */
-static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line)
+static void jpeg_decode_std(const char * const version,
+ const subblock_transform_t transform_luma,
+ const subblock_transform_t transform_chroma,
+ const tile_line_emitter_t emit_line)
{
int16_t qtables[3][SUBBLOCK_SIZE];
unsigned int mb;
uint32_t qtableV_ptr;
unsigned int subblock_count;
unsigned int macroblock_size;
- int16_t *macroblock;
+ int16_t macroblock[6*SUBBLOCK_SIZE]; /* macroblock contains at most 6 subblobcks */
const OSTask_t * const task = get_task();
if (task->flags & 0x1)
}
subblock_count = mode + 4;
- macroblock_size = 2*subblock_count*SUBBLOCK_SIZE;
+ macroblock_size = subblock_count*SUBBLOCK_SIZE;
rdram_read_many_u16((uint16_t*)qtables[0], qtableY_ptr, SUBBLOCK_SIZE);
rdram_read_many_u16((uint16_t*)qtables[1], qtableU_ptr, SUBBLOCK_SIZE);
rdram_read_many_u16((uint16_t*)qtables[2], qtableV_ptr, SUBBLOCK_SIZE);
- macroblock = malloc(sizeof(*macroblock) * macroblock_size);
- if (!macroblock)
- {
- DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: could not allocate macroblock", version);
- return;
- }
-
for (mb = 0; mb < macroblock_count; ++mb)
{
- rdram_read_many_u16((uint16_t*)macroblock, address, macroblock_size >> 1);
- decode_mb(macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables);
+ rdram_read_many_u16((uint16_t*)macroblock, address, macroblock_size);
+ decode_macroblock_std(transform_luma, transform_chroma,
+ macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables);
if (mode == 0)
{
EmitTilesMode2(emit_line, macroblock, address);
}
- address += macroblock_size;
+ address += 2*macroblock_size;
}
- free(macroblock);
}
static uint8_t clamp_u8(int16_t x)
}
}
-static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable)
+static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable)
{
int sb;
}
}
-static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE])
-{
- unsigned int sb;
- unsigned int q = 0;
-
- for (sb = 0; sb < subblock_count; ++sb)
- {
- int16_t tmp_sb[SUBBLOCK_SIZE];
- const int isChromaSubBlock = (subblock_count - sb <= 2);
-
- if (isChromaSubBlock) { ++q; }
-
- MultSubBlocks(macroblock, macroblock, qtables[q], 4);
- ZigZagSubBlock(tmp_sb, macroblock);
- InverseDCTSubBlock(macroblock, tmp_sb);
-
- macroblock += SUBBLOCK_SIZE;
- }
-
-}
-
-static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE])
+static void decode_macroblock_std(
+ const subblock_transform_t transform_luma,
+ const subblock_transform_t transform_chroma,
+ int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE])
{
unsigned int sb;
unsigned int q = 0;
if (isChromaSubBlock)
{
- RescaleUVSubBlock(macroblock, macroblock);
+ if (transform_chroma != NULL)
+ transform_chroma(macroblock, macroblock);
}
else
{
- RescaleYSubBlock(macroblock, macroblock);
+ if (transform_luma != NULL)
+ transform_luma(macroblock, macroblock);
}
macroblock += SUBBLOCK_SIZE;