Browse Source

Change tabs to spaces, adjust formatting.

Former-commit-id: dc28bb2d7ef6df5f3632a7bfb89462f09cc94da9
Former-commit-id: 78751356195d16bae5ccef1373f6bc11b775a13d
Former-commit-id: d26a9612598636d0b26f80cddc96b7033b6b16c7
pull/1/head
Michael Weber 10 years ago
parent
commit
793aa2c212
  1. 20
      src/ImageProcessorCore/Formats/Jpg/Block.cs
  2. 68
      src/ImageProcessorCore/Formats/Jpg/Colors.cs
  3. 3302
      src/ImageProcessorCore/Formats/Jpg/Decoder.cs
  4. 1239
      src/ImageProcessorCore/Formats/Jpg/Encoder.cs
  5. 234
      src/ImageProcessorCore/Formats/Jpg/FDCT.cs
  6. 310
      src/ImageProcessorCore/Formats/Jpg/IDCT.cs
  7. 18
      src/ImageProcessorCore/Formats/Jpg/JpegDecoder.cs

20
src/ImageProcessorCore/Formats/Jpg/Block.cs

@ -3,16 +3,16 @@ namespace ImageProcessorCore.Formats.Jpg
using System; using System;
using System.IO; using System.IO;
internal class Block internal class Block
{ {
public const int blockSize = 64; public const int blockSize = 64;
private int[] _data; private int[] _data;
public Block() public Block()
{ {
_data = new int[blockSize]; _data = new int[blockSize];
} }
public int this[int idx] { get { return _data[idx]; } set { _data[idx] = value; } } public int this[int idx] { get { return _data[idx]; } set { _data[idx] = value; } }
} }
} }

68
src/ImageProcessorCore/Formats/Jpg/Colors.cs

@ -3,43 +3,43 @@ namespace ImageProcessorCore.Formats.Jpg
using System; using System;
using System.IO; using System.IO;
internal static class Colors internal static class Colors
{ {
public static void RGBToYCbCr(byte r, byte g, byte b, out byte yy, out byte cb, out byte cr) public static void RGBToYCbCr(byte r, byte g, byte b, out byte yy, out byte cb, out byte cr)
{ {
// The JFIF specification says: // The JFIF specification says:
// Y' = 0.2990*R + 0.5870*G + 0.1140*B // Y' = 0.2990*R + 0.5870*G + 0.1140*B
// Cb = -0.1687*R - 0.3313*G + 0.5000*B + 128 // Cb = -0.1687*R - 0.3313*G + 0.5000*B + 128
// Cr = 0.5000*R - 0.4187*G - 0.0813*B + 128 // Cr = 0.5000*R - 0.4187*G - 0.0813*B + 128
// http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'. // http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'.
int iyy = (19595*r + 38470*g + 7471*b + (1<<15)) >> 16; int iyy = (19595*r + 38470*g + 7471*b + (1<<15)) >> 16;
int icb = (-11056*r - 21712*g + 32768*b + (257<<15)) >> 16; int icb = (-11056*r - 21712*g + 32768*b + (257<<15)) >> 16;
int icr = (32768*r - 27440*g - 5328*b + (257<<15)) >> 16; int icr = (32768*r - 27440*g - 5328*b + (257<<15)) >> 16;
if(iyy < 0) yy = 0; else if(iyy > 255) yy = 255; else yy = (byte)iyy; if(iyy < 0) yy = 0; else if(iyy > 255) yy = 255; else yy = (byte)iyy;
if(icb < 0) cb = 0; else if(icb > 255) cb = 255; else cb = (byte)icb; if(icb < 0) cb = 0; else if(icb > 255) cb = 255; else cb = (byte)icb;
if(icr < 0) cr = 0; else if(icr > 255) cr = 255; else cr = (byte)icr; if(icr < 0) cr = 0; else if(icr > 255) cr = 255; else cr = (byte)icr;
} }
public static void YCbCrToRGB(byte yy, byte cb, byte cr, out byte r, out byte g, out byte b) public static void YCbCrToRGB(byte yy, byte cb, byte cr, out byte r, out byte g, out byte b)
{ {
// The JFIF specification says: // The JFIF specification says:
// R = Y' + 1.40200*(Cr-128) // R = Y' + 1.40200*(Cr-128)
// G = Y' - 0.34414*(Cb-128) - 0.71414*(Cr-128) // G = Y' - 0.34414*(Cb-128) - 0.71414*(Cr-128)
// B = Y' + 1.77200*(Cb-128) // B = Y' + 1.77200*(Cb-128)
// http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'. // http://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'.
int yy1 = yy * 0x10100; // Convert 0x12 to 0x121200. int yy1 = yy * 0x10100; // Convert 0x12 to 0x121200.
int cb1 = cb - 128; int cb1 = cb - 128;
int cr1 = cr - 128; int cr1 = cr - 128;
int ir = (yy1 + 91881*cr1) >> 16; int ir = (yy1 + 91881*cr1) >> 16;
int ig = (yy1 - 22554*cb1 - 46802*cr1) >> 16; int ig = (yy1 - 22554*cb1 - 46802*cr1) >> 16;
int ib = (yy1 + 116130*cb1) >> 16; int ib = (yy1 + 116130*cb1) >> 16;
if(ir < 0) r = 0; else if(ir > 255) r = 255; else r = (byte)ir; if(ir < 0) r = 0; else if(ir > 255) r = 255; else r = (byte)ir;
if(ig < 0) g = 0; else if(ig > 255) g = 255; else g = (byte)ig; if(ig < 0) g = 0; else if(ig > 255) g = 255; else g = (byte)ig;
if(ib < 0) b = 0; else if(ib > 255) b = 255; else b = (byte)ib; if(ib < 0) b = 0; else if(ib > 255) b = 255; else b = (byte)ib;
} }
} }
} }

3302
src/ImageProcessorCore/Formats/Jpg/Decoder.cs

File diff suppressed because it is too large

1239
src/ImageProcessorCore/Formats/Jpg/Encoder.cs

File diff suppressed because it is too large

234
src/ImageProcessorCore/Formats/Jpg/FDCT.cs

@ -3,135 +3,135 @@ namespace ImageProcessorCore.Formats.Jpg
using System; using System;
using System.IO; using System.IO;
internal partial class Encoder internal partial class Encoder
{ {
// Trigonometric constants in 13-bit fixed point format. // Trigonometric constants in 13-bit fixed point format.
private const int fix_0_298631336 = 2446; private const int fix_0_298631336 = 2446;
private const int fix_0_390180644 = 3196; private const int fix_0_390180644 = 3196;
private const int fix_0_541196100 = 4433; private const int fix_0_541196100 = 4433;
private const int fix_0_765366865 = 6270; private const int fix_0_765366865 = 6270;
private const int fix_0_899976223 = 7373; private const int fix_0_899976223 = 7373;
private const int fix_1_175875602 = 9633; private const int fix_1_175875602 = 9633;
private const int fix_1_501321110 = 12299; private const int fix_1_501321110 = 12299;
private const int fix_1_847759065 = 15137; private const int fix_1_847759065 = 15137;
private const int fix_1_961570560 = 16069; private const int fix_1_961570560 = 16069;
private const int fix_2_053119869 = 16819; private const int fix_2_053119869 = 16819;
private const int fix_2_562915447 = 20995; private const int fix_2_562915447 = 20995;
private const int fix_3_072711026 = 25172; private const int fix_3_072711026 = 25172;
private const int constBits = 13; private const int constBits = 13;
private const int pass1Bits = 2; private const int pass1Bits = 2;
private const int centerJSample = 128; private const int centerJSample = 128;
// fdct performs a forward DCT on an 8x8 block of coefficients, including a // fdct performs a forward DCT on an 8x8 block of coefficients, including a
// level shift. // level shift.
private static void FDCT(Block b) private static void FDCT(Block b)
{ {
// Pass 1: process rows. // Pass 1: process rows.
for(int y = 0; y < 8; y++) for(int y = 0; y < 8; y++)
{ {
int x0 = b[y*8+0]; int x0 = b[y*8+0];
int x1 = b[y*8+1]; int x1 = b[y*8+1];
int x2 = b[y*8+2]; int x2 = b[y*8+2];
int x3 = b[y*8+3]; int x3 = b[y*8+3];
int x4 = b[y*8+4]; int x4 = b[y*8+4];
int x5 = b[y*8+5]; int x5 = b[y*8+5];
int x6 = b[y*8+6]; int x6 = b[y*8+6];
int x7 = b[y*8+7]; int x7 = b[y*8+7];
int tmp0 = x0 + x7; int tmp0 = x0 + x7;
int tmp1 = x1 + x6; int tmp1 = x1 + x6;
int tmp2 = x2 + x5; int tmp2 = x2 + x5;
int tmp3 = x3 + x4; int tmp3 = x3 + x4;
int tmp10 = tmp0 + tmp3; int tmp10 = tmp0 + tmp3;
int tmp12 = tmp0 - tmp3; int tmp12 = tmp0 - tmp3;
int tmp11 = tmp1 + tmp2; int tmp11 = tmp1 + tmp2;
int tmp13 = tmp1 - tmp2; int tmp13 = tmp1 - tmp2;
tmp0 = x0 - x7; tmp0 = x0 - x7;
tmp1 = x1 - x6; tmp1 = x1 - x6;
tmp2 = x2 - x5; tmp2 = x2 - x5;
tmp3 = x3 - x4; tmp3 = x3 - x4;
b[y*8+0] = (tmp10 + tmp11 - 8*centerJSample) << pass1Bits; b[y*8+0] = (tmp10 + tmp11 - 8*centerJSample) << pass1Bits;
b[y*8+4] = (tmp10 - tmp11) << pass1Bits; b[y*8+4] = (tmp10 - tmp11) << pass1Bits;
int z1 = (tmp12 + tmp13) * fix_0_541196100; int z1 = (tmp12 + tmp13) * fix_0_541196100;
z1 += 1 << (constBits - pass1Bits - 1); z1 += 1 << (constBits - pass1Bits - 1);
b[y*8+2] = (z1 + tmp12*fix_0_765366865) >> (constBits - pass1Bits); b[y*8+2] = (z1 + tmp12*fix_0_765366865) >> (constBits - pass1Bits);
b[y*8+6] = (z1 - tmp13*fix_1_847759065) >> (constBits - pass1Bits); b[y*8+6] = (z1 - tmp13*fix_1_847759065) >> (constBits - pass1Bits);
tmp10 = tmp0 + tmp3; tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2; tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3; tmp13 = tmp1 + tmp3;
z1 = (tmp12 + tmp13) * fix_1_175875602; z1 = (tmp12 + tmp13) * fix_1_175875602;
z1 += 1 << (constBits - pass1Bits - 1); z1 += 1 << (constBits - pass1Bits - 1);
tmp0 = tmp0 * fix_1_501321110; tmp0 = tmp0 * fix_1_501321110;
tmp1 = tmp1 * fix_3_072711026; tmp1 = tmp1 * fix_3_072711026;
tmp2 = tmp2 * fix_2_053119869; tmp2 = tmp2 * fix_2_053119869;
tmp3 = tmp3 * fix_0_298631336; tmp3 = tmp3 * fix_0_298631336;
tmp10 = tmp10 * -fix_0_899976223; tmp10 = tmp10 * -fix_0_899976223;
tmp11 = tmp11 * -fix_2_562915447; tmp11 = tmp11 * -fix_2_562915447;
tmp12 = tmp12 * -fix_0_390180644; tmp12 = tmp12 * -fix_0_390180644;
tmp13 = tmp13 * -fix_1_961570560; tmp13 = tmp13 * -fix_1_961570560;
tmp12 += z1; tmp12 += z1;
tmp13 += z1; tmp13 += z1;
b[y*8+1] = (tmp0 + tmp10 + tmp12) >> (constBits - pass1Bits); b[y*8+1] = (tmp0 + tmp10 + tmp12) >> (constBits - pass1Bits);
b[y*8+3] = (tmp1 + tmp11 + tmp13) >> (constBits - pass1Bits); b[y*8+3] = (tmp1 + tmp11 + tmp13) >> (constBits - pass1Bits);
b[y*8+5] = (tmp2 + tmp11 + tmp12) >> (constBits - pass1Bits); b[y*8+5] = (tmp2 + tmp11 + tmp12) >> (constBits - pass1Bits);
b[y*8+7] = (tmp3 + tmp10 + tmp13) >> (constBits - pass1Bits); b[y*8+7] = (tmp3 + tmp10 + tmp13) >> (constBits - pass1Bits);
} }
// Pass 2: process columns. // Pass 2: process columns.
// We remove pass1Bits scaling, but leave results scaled up by an overall factor of 8. // We remove pass1Bits scaling, but leave results scaled up by an overall factor of 8.
for(int x = 0; x < 8; x++) for(int x = 0; x < 8; x++)
{ {
int tmp0 = b[0*8+x] + b[7*8+x]; int tmp0 = b[0*8+x] + b[7*8+x];
int tmp1 = b[1*8+x] + b[6*8+x]; int tmp1 = b[1*8+x] + b[6*8+x];
int tmp2 = b[2*8+x] + b[5*8+x]; int tmp2 = b[2*8+x] + b[5*8+x];
int tmp3 = b[3*8+x] + b[4*8+x]; int tmp3 = b[3*8+x] + b[4*8+x];
int tmp10 = tmp0 + tmp3 + (1<<(pass1Bits-1)); int tmp10 = tmp0 + tmp3 + (1<<(pass1Bits-1));
int tmp12 = tmp0 - tmp3; int tmp12 = tmp0 - tmp3;
int tmp11 = tmp1 + tmp2; int tmp11 = tmp1 + tmp2;
int tmp13 = tmp1 - tmp2; int tmp13 = tmp1 - tmp2;
tmp0 = b[0*8+x] - b[7*8+x]; tmp0 = b[0*8+x] - b[7*8+x];
tmp1 = b[1*8+x] - b[6*8+x]; tmp1 = b[1*8+x] - b[6*8+x];
tmp2 = b[2*8+x] - b[5*8+x]; tmp2 = b[2*8+x] - b[5*8+x];
tmp3 = b[3*8+x] - b[4*8+x]; tmp3 = b[3*8+x] - b[4*8+x];
b[0*8+x] = (tmp10 + tmp11) >> pass1Bits; b[0*8+x] = (tmp10 + tmp11) >> pass1Bits;
b[4*8+x] = (tmp10 - tmp11) >> pass1Bits; b[4*8+x] = (tmp10 - tmp11) >> pass1Bits;
int z1 = (tmp12 + tmp13) * fix_0_541196100; int z1 = (tmp12 + tmp13) * fix_0_541196100;
z1 += 1 << (constBits + pass1Bits - 1); z1 += 1 << (constBits + pass1Bits - 1);
b[2*8+x] = (z1 + tmp12*fix_0_765366865) >> (constBits + pass1Bits); b[2*8+x] = (z1 + tmp12*fix_0_765366865) >> (constBits + pass1Bits);
b[6*8+x] = (z1 - tmp13*fix_1_847759065) >> (constBits + pass1Bits); b[6*8+x] = (z1 - tmp13*fix_1_847759065) >> (constBits + pass1Bits);
tmp10 = tmp0 + tmp3; tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2; tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3; tmp13 = tmp1 + tmp3;
z1 = (tmp12 + tmp13) * fix_1_175875602; z1 = (tmp12 + tmp13) * fix_1_175875602;
z1 += 1 << (constBits + pass1Bits - 1); z1 += 1 << (constBits + pass1Bits - 1);
tmp0 = tmp0 * fix_1_501321110; tmp0 = tmp0 * fix_1_501321110;
tmp1 = tmp1 * fix_3_072711026; tmp1 = tmp1 * fix_3_072711026;
tmp2 = tmp2 * fix_2_053119869; tmp2 = tmp2 * fix_2_053119869;
tmp3 = tmp3 * fix_0_298631336; tmp3 = tmp3 * fix_0_298631336;
tmp10 = tmp10 * -fix_0_899976223; tmp10 = tmp10 * -fix_0_899976223;
tmp11 = tmp11 * -fix_2_562915447; tmp11 = tmp11 * -fix_2_562915447;
tmp12 = tmp12 * -fix_0_390180644; tmp12 = tmp12 * -fix_0_390180644;
tmp13 = tmp13 * -fix_1_961570560; tmp13 = tmp13 * -fix_1_961570560;
tmp12 += z1; tmp12 += z1;
tmp13 += z1; tmp13 += z1;
b[1*8+x] = (tmp0 + tmp10 + tmp12) >> (constBits + pass1Bits); b[1*8+x] = (tmp0 + tmp10 + tmp12) >> (constBits + pass1Bits);
b[3*8+x] = (tmp1 + tmp11 + tmp13) >> (constBits + pass1Bits); b[3*8+x] = (tmp1 + tmp11 + tmp13) >> (constBits + pass1Bits);
b[5*8+x] = (tmp2 + tmp11 + tmp12) >> (constBits + pass1Bits); b[5*8+x] = (tmp2 + tmp11 + tmp12) >> (constBits + pass1Bits);
b[7*8+x] = (tmp3 + tmp10 + tmp13) >> (constBits + pass1Bits); b[7*8+x] = (tmp3 + tmp10 + tmp13) >> (constBits + pass1Bits);
} }
} }
} }
} }

310
src/ImageProcessorCore/Formats/Jpg/IDCT.cs

@ -3,159 +3,159 @@ namespace ImageProcessorCore.Formats.Jpg
using System; using System;
using System.IO; using System.IO;
internal partial class Decoder internal partial class Decoder
{ {
private const int w1 = 2841; // 2048*sqrt(2)*cos(1*pi/16) private const int w1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
private const int w2 = 2676; // 2048*sqrt(2)*cos(2*pi/16) private const int w2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
private const int w3 = 2408; // 2048*sqrt(2)*cos(3*pi/16) private const int w3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
private const int w5 = 1609; // 2048*sqrt(2)*cos(5*pi/16) private const int w5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
private const int w6 = 1108; // 2048*sqrt(2)*cos(6*pi/16) private const int w6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
private const int w7 = 565; // 2048*sqrt(2)*cos(7*pi/16) private const int w7 = 565; // 2048*sqrt(2)*cos(7*pi/16)
private const int w1pw7 = w1 + w7; private const int w1pw7 = w1 + w7;
private const int w1mw7 = w1 - w7; private const int w1mw7 = w1 - w7;
private const int w2pw6 = w2 + w6; private const int w2pw6 = w2 + w6;
private const int w2mw6 = w2 - w6; private const int w2mw6 = w2 - w6;
private const int w3pw5 = w3 + w5; private const int w3pw5 = w3 + w5;
private const int w3mw5 = w3 - w5; private const int w3mw5 = w3 - w5;
private const int r2 = 181; // 256/sqrt(2) private const int r2 = 181; // 256/sqrt(2)
// idct performs a 2-D Inverse Discrete Cosine Transformation. // idct performs a 2-D Inverse Discrete Cosine Transformation.
// //
// The input coefficients should already have been multiplied by the // The input coefficients should already have been multiplied by the
// appropriate quantization table. We use fixed-point computation, with the // appropriate quantization table. We use fixed-point computation, with the
// number of bits for the fractional component varying over the intermediate // number of bits for the fractional component varying over the intermediate
// stages. // stages.
// //
// For more on the actual algorithm, see Z. Wang, "Fast algorithms for the // For more on the actual algorithm, see Z. Wang, "Fast algorithms for the
// discrete W transform and for the discrete Fourier transform", IEEE Trans. on // discrete W transform and for the discrete Fourier transform", IEEE Trans. on
// ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984. // ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984.
private static void IDCT(Block src) private static void IDCT(Block src)
{ {
// Horizontal 1-D IDCT. // Horizontal 1-D IDCT.
for(int y = 0; y < 8; y++) for(int y = 0; y < 8; y++)
{ {
int y8 = y * 8; int y8 = y * 8;
// If all the AC components are zero, then the IDCT is trivial. // If all the AC components are zero, then the IDCT is trivial.
if(src[y8+1] == 0 && src[y8+2] == 0 && src[y8+3] == 0 && if(src[y8+1] == 0 && src[y8+2] == 0 && src[y8+3] == 0 &&
src[y8+4] == 0 && src[y8+5] == 0 && src[y8+6] == 0 && src[y8+7] == 0) src[y8+4] == 0 && src[y8+5] == 0 && src[y8+6] == 0 && src[y8+7] == 0)
{ {
int dc = src[y8+0] << 3; int dc = src[y8+0] << 3;
src[y8+0] = dc; src[y8+0] = dc;
src[y8+1] = dc; src[y8+1] = dc;
src[y8+2] = dc; src[y8+2] = dc;
src[y8+3] = dc; src[y8+3] = dc;
src[y8+4] = dc; src[y8+4] = dc;
src[y8+5] = dc; src[y8+5] = dc;
src[y8+6] = dc; src[y8+6] = dc;
src[y8+7] = dc; src[y8+7] = dc;
continue; continue;
} }
// Prescale. // Prescale.
int x0 = (src[y8+0] << 11) + 128; int x0 = (src[y8+0] << 11) + 128;
int x1 = src[y8+4] << 11; int x1 = src[y8+4] << 11;
int x2 = src[y8+6]; int x2 = src[y8+6];
int x3 = src[y8+2]; int x3 = src[y8+2];
int x4 = src[y8+1]; int x4 = src[y8+1];
int x5 = src[y8+7]; int x5 = src[y8+7];
int x6 = src[y8+5]; int x6 = src[y8+5];
int x7 = src[y8+3]; int x7 = src[y8+3];
// Stage 1. // Stage 1.
int x8 = w7 * (x4 + x5); int x8 = w7 * (x4 + x5);
x4 = x8 + w1mw7*x4; x4 = x8 + w1mw7*x4;
x5 = x8 - w1pw7*x5; x5 = x8 - w1pw7*x5;
x8 = w3 * (x6 + x7); x8 = w3 * (x6 + x7);
x6 = x8 - w3mw5*x6; x6 = x8 - w3mw5*x6;
x7 = x8 - w3pw5*x7; x7 = x8 - w3pw5*x7;
// Stage 2. // Stage 2.
x8 = x0 + x1; x8 = x0 + x1;
x0 -= x1; x0 -= x1;
x1 = w6 * (x3 + x2); x1 = w6 * (x3 + x2);
x2 = x1 - w2pw6*x2; x2 = x1 - w2pw6*x2;
x3 = x1 + w2mw6*x3; x3 = x1 + w2mw6*x3;
x1 = x4 + x6; x1 = x4 + x6;
x4 -= x6; x4 -= x6;
x6 = x5 + x7; x6 = x5 + x7;
x5 -= x7; x5 -= x7;
// Stage 3. // Stage 3.
x7 = x8 + x3; x7 = x8 + x3;
x8 -= x3; x8 -= x3;
x3 = x0 + x2; x3 = x0 + x2;
x0 -= x2; x0 -= x2;
x2 = (r2*(x4+x5) + 128) >> 8; x2 = (r2*(x4+x5) + 128) >> 8;
x4 = (r2*(x4-x5) + 128) >> 8; x4 = (r2*(x4-x5) + 128) >> 8;
// Stage 4. // Stage 4.
src[y8+0] = (x7 + x1) >> 8; src[y8+0] = (x7 + x1) >> 8;
src[y8+1] = (x3 + x2) >> 8; src[y8+1] = (x3 + x2) >> 8;
src[y8+2] = (x0 + x4) >> 8; src[y8+2] = (x0 + x4) >> 8;
src[y8+3] = (x8 + x6) >> 8; src[y8+3] = (x8 + x6) >> 8;
src[y8+4] = (x8 - x6) >> 8; src[y8+4] = (x8 - x6) >> 8;
src[y8+5] = (x0 - x4) >> 8; src[y8+5] = (x0 - x4) >> 8;
src[y8+6] = (x3 - x2) >> 8; src[y8+6] = (x3 - x2) >> 8;
src[y8+7] = (x7 - x1) >> 8; src[y8+7] = (x7 - x1) >> 8;
} }
// Vertical 1-D IDCT. // Vertical 1-D IDCT.
for(int x = 0; x < 8; x++) for(int x = 0; x < 8; x++)
{ {
// Similar to the horizontal 1-D IDCT case, if all the AC components are zero, then the IDCT is trivial. // Similar to the horizontal 1-D IDCT case, if all the AC components are zero, then the IDCT is trivial.
// However, after performing the horizontal 1-D IDCT, there are typically non-zero AC components, so // However, after performing the horizontal 1-D IDCT, there are typically non-zero AC components, so
// we do not bother to check for the all-zero case. // we do not bother to check for the all-zero case.
// Prescale. // Prescale.
int y0 = (src[8*0+x] << 8) + 8192; int y0 = (src[8*0+x] << 8) + 8192;
int y1 = src[8*4+x] << 8; int y1 = src[8*4+x] << 8;
int y2 = src[8*6+x]; int y2 = src[8*6+x];
int y3 = src[8*2+x]; int y3 = src[8*2+x];
int y4 = src[8*1+x]; int y4 = src[8*1+x];
int y5 = src[8*7+x]; int y5 = src[8*7+x];
int y6 = src[8*5+x]; int y6 = src[8*5+x];
int y7 = src[8*3+x]; int y7 = src[8*3+x];
// Stage 1. // Stage 1.
int y8 = w7*(y4+y5) + 4; int y8 = w7*(y4+y5) + 4;
y4 = (y8 + w1mw7*y4) >> 3; y4 = (y8 + w1mw7*y4) >> 3;
y5 = (y8 - w1pw7*y5) >> 3; y5 = (y8 - w1pw7*y5) >> 3;
y8 = w3*(y6+y7) + 4; y8 = w3*(y6+y7) + 4;
y6 = (y8 - w3mw5*y6) >> 3; y6 = (y8 - w3mw5*y6) >> 3;
y7 = (y8 - w3pw5*y7) >> 3; y7 = (y8 - w3pw5*y7) >> 3;
// Stage 2. // Stage 2.
y8 = y0 + y1; y8 = y0 + y1;
y0 -= y1; y0 -= y1;
y1 = w6*(y3+y2) + 4; y1 = w6*(y3+y2) + 4;
y2 = (y1 - w2pw6*y2) >> 3; y2 = (y1 - w2pw6*y2) >> 3;
y3 = (y1 + w2mw6*y3) >> 3; y3 = (y1 + w2mw6*y3) >> 3;
y1 = y4 + y6; y1 = y4 + y6;
y4 -= y6; y4 -= y6;
y6 = y5 + y7; y6 = y5 + y7;
y5 -= y7; y5 -= y7;
// Stage 3. // Stage 3.
y7 = y8 + y3; y7 = y8 + y3;
y8 -= y3; y8 -= y3;
y3 = y0 + y2; y3 = y0 + y2;
y0 -= y2; y0 -= y2;
y2 = (r2*(y4+y5) + 128) >> 8; y2 = (r2*(y4+y5) + 128) >> 8;
y4 = (r2*(y4-y5) + 128) >> 8; y4 = (r2*(y4-y5) + 128) >> 8;
// Stage 4. // Stage 4.
src[8*0+x] = (y7 + y1) >> 14; src[8*0+x] = (y7 + y1) >> 14;
src[8*1+x] = (y3 + y2) >> 14; src[8*1+x] = (y3 + y2) >> 14;
src[8*2+x] = (y0 + y4) >> 14; src[8*2+x] = (y0 + y4) >> 14;
src[8*3+x] = (y8 + y6) >> 14; src[8*3+x] = (y8 + y6) >> 14;
src[8*4+x] = (y8 - y6) >> 14; src[8*4+x] = (y8 - y6) >> 14;
src[8*5+x] = (y0 - y4) >> 14; src[8*5+x] = (y0 - y4) >> 14;
src[8*6+x] = (y3 - y2) >> 14; src[8*6+x] = (y3 - y2) >> 14;
src[8*7+x] = (y7 - y1) >> 14; src[8*7+x] = (y7 - y1) >> 14;
} }
} }
} }
} }

18
src/ImageProcessorCore/Formats/Jpg/JpegDecoder.cs

@ -8,7 +8,7 @@ namespace ImageProcessorCore.Formats
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using ImageProcessorCore.Formats.Jpg; using ImageProcessorCore.Formats.Jpg;
/// <summary> /// <summary>
/// Image decoder for generating an image out of a jpg stream. /// Image decoder for generating an image out of a jpg stream.
@ -95,22 +95,22 @@ namespace ImageProcessorCore.Formats
Guard.NotNull(image, "image"); Guard.NotNull(image, "image");
Guard.NotNull(stream, "stream"); Guard.NotNull(stream, "stream");
Decoder decoder = new Decoder(); Decoder decoder = new Decoder();
decoder.decode(stream, false); decoder.decode(stream, false);
int pixelWidth = decoder.width; int pixelWidth = decoder.width;
int pixelHeight = decoder.height; int pixelHeight = decoder.height;
float[] pixels = new float[pixelWidth * pixelHeight * 4]; float[] pixels = new float[pixelWidth * pixelHeight * 4];
if(decoder.nComp == 1) if(decoder.nComp == 1)
{ {
Parallel.For( Parallel.For(
0, 0,
pixelHeight, pixelHeight,
y => y =>
{ {
var yoff = decoder.img1.get_row_offset(y); var yoff = decoder.img1.get_row_offset(y);
for (int x = 0; x < pixelWidth; x++) for (int x = 0; x < pixelWidth; x++)
{ {
int offset = ((y * pixelWidth) + x) * 4; int offset = ((y * pixelWidth) + x) * 4;
@ -121,15 +121,15 @@ namespace ImageProcessorCore.Formats
pixels[offset + 3] = 1; pixels[offset + 3] = 1;
} }
}); });
} }
else if(decoder.nComp == 3) else if(decoder.nComp == 3)
{ {
Parallel.For( Parallel.For(
0, 0,
pixelHeight, pixelHeight,
y => y =>
{ {
var yoff = decoder.imgrgb.get_row_offset(y); var yoff = decoder.imgrgb.get_row_offset(y);
for (int x = 0; x < pixelWidth; x++) for (int x = 0; x < pixelWidth; x++)
{ {
int offset = ((y * pixelWidth) + x) * 4; int offset = ((y * pixelWidth) + x) * 4;

Loading…
Cancel
Save