unit DCT; // FIXME. {$MODE OBJFPC} interface uses sysutils, classes, custom_decoders, type_fixes; type // The input format, signed 12-bit integers. TMatrix = {bitpacked} array[0..7] of array[0..7] of ShortInt; // [row, column]. TDecoder = class(custom_decoders.TCustomDirectDecoder) private //procedure BufferByte(aValue : Byte); inline; //procedure BufferTuple(aValue : Cardinal; aDecodedCount : Cardinal); inline; // decoding shrinks from 5 byte to 4 byte. //procedure Decode(aInput : Byte); inline; published procedure Finish(); override; function FinishedP() : Boolean; override; protected procedure DecodeBlock(aEncodedBuffer : PByte; aEncodedBufferCount : Cardinal); override; function GetPermittedReadCount(aBufferAvailableSpace : Cardinal) : Cardinal; override; end; implementation function IDCTTransform(const aInput : TMatrix) : TMatrix; var vN : Integer; vM : Integer; vXF : Integer; vYF : Integer; function CellValue() : Single; inline; var vIX : Integer; // input. vIY : Integer; // input. begin Result := 0; for vIY := 0 to vN - 1 do begin for vIX := 0 to vM - 1 do begin // 2x+1 => 1, 3, 5, ... Result := Result + aInput[vIY][vIX] * cos(vXF * vIX * pi / (2 * vM)) * cos(vYF * vIY * pi / (2 * vN)); if (vIX = 0) and (vIY = 0) then Result := Result / 2.0; // *1² / SQRT(2.0)²; end; end; end; // For a different way, see . var vX : Integer; vY : Integer; vScale : Single; vValue : Single; begin vN := Length(aInput); // number of rows. vM := Length(aInput[0]); // number of columns. // FIXME assert vN power of 2, vM power of 2, >0. vScale := 2.0 / SQRT(vM * vN); vYF := 1; // 2y+1. for vY := 0 to vN - 1 do begin vXF := 1; // 2x+1 first value. for vX := 0 to vM - 1 do begin Result[vY][vX] := Trunc(vScale * CellValue()); Inc(vXF, 2); end; Inc(vYF, 2); end; //vXF := (vIX shl 1) + 1; //vYF := (vIY shl 1) + 1; // DCT-III (IDCT) // X_k = \frac{1}{2} x_0 + \sum_{n=1}^{N-1} x_n \cos \left[\frac{\pi}{N} n \left(k+\frac{1}{2}\right) \right] \quad \quad k = 0, \dots, N-1. { f(x,y) = (2 / sqrt(MN)) * sum[m := 0,M)sum[n := 0,N) C(m)C(n)F(m,n)cos((2x+1)m*pi/2M)*cos((2y+1)n*pi/2N) where F(m,n) is the DCT of the signal f(x,y) and C(m),C(n) = 1/sqrt(2) for m,n = 0 and C(m),C(n) = 1 otherwise. M power of 2. N power of 2. } end; procedure TDecoder.Finish(); begin end; function TDecoder.FinishedP() : Boolean; begin Result := True; end; procedure TDecoder.DecodeBlock(aEncodedBuffer : PByte; aEncodedBufferCount : Cardinal); begin raise EReadError.Create('not implemented yet.'); end; function TDecoder.GetPermittedReadCount(aBufferAvailableSpace : Cardinal) : Cardinal; begin Result := 0; end; end.