summaryrefslogtreecommitdiff
path: root/jdmcu.c
blob: 0d99170887456520974d1338462b7dac886a067c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * jdmcu.c
 *
 * Copyright (C) 1991, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains MCU disassembly routines and quantization descaling.
 * These routines are invoked via the disassemble_MCU and
 * disassemble_init/term methods.
 */

#include "jinclude.h"


/*
 * Quantization descaling and zigzag reordering
 */


/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */

static const short ZAG[DCTSIZE2] = {
  0,  1,  8, 16,  9,  2,  3, 10,
 17, 24, 32, 25, 18, 11,  4,  5,
 12, 19, 26, 33, 40, 48, 41, 34,
 27, 20, 13,  6,  7, 14, 21, 28,
 35, 42, 49, 56, 57, 50, 43, 36,
 29, 22, 15, 23, 30, 37, 44, 51,
 58, 59, 52, 45, 38, 31, 39, 46,
 53, 60, 61, 54, 47, 55, 62, 63
};


LOCAL void
qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
{
  short i;

  for (i = 0; i < DCTSIZE2; i++) {
    (*outputptr)[ZAG[i]] = (*input++) * (*quanttbl++);
  }
}



/*
 * Fetch one MCU row from entropy_decode, build coefficient array.
 * This version is used for noninterleaved (single-component) scans.
 */

METHODDEF void
disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
				JBLOCKIMAGE image_data)
{
  JBLOCK MCU_data[1];
  long mcuindex;
  jpeg_component_info * compptr;
  QUANT_TBL_PTR quant_ptr;

  /* this is pretty easy since there is one component and one block per MCU */
  compptr = cinfo->cur_comp_info[0];
  quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
    /* Fetch the coefficient data */
    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
    /* Descale, reorder, and distribute it into the image array */
    qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
  }
}


/*
 * Fetch one MCU row from entropy_decode, build coefficient array.
 * This version is used for interleaved (multi-component) scans.
 */

METHODDEF void
disassemble_interleaved_MCU (decompress_info_ptr cinfo,
			     JBLOCKIMAGE image_data)
{
  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
  long mcuindex;
  short blkn, ci, xpos, ypos;
  jpeg_component_info * compptr;
  QUANT_TBL_PTR quant_ptr;
  JBLOCKROW image_ptr;

  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
    /* Fetch the coefficient data */
    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
    /* Descale, reorder, and distribute it into the image array */
    blkn = 0;
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
      compptr = cinfo->cur_comp_info[ci];
      quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
      for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
	image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
	for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
	  qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
	  image_ptr++;
	  blkn++;
	}
      }
    }
  }
}


/*
 * Initialize for processing a scan.
 */

METHODDEF void
disassemble_init (decompress_info_ptr cinfo)
{
  /* no work for now */
}


/*
 * Clean up after a scan.
 */

METHODDEF void
disassemble_term (decompress_info_ptr cinfo)
{
  /* no work for now */
}



/*
 * The method selection routine for MCU disassembly.
 */

GLOBAL void
jseldmcu (decompress_info_ptr cinfo)
{
  if (cinfo->comps_in_scan == 1)
    cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
  else
    cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
  cinfo->methods->disassemble_init = disassemble_init;
  cinfo->methods->disassemble_term = disassemble_term;
}