4Syntax10.Scn.Fnt3pVersionElemsAllocBeg#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntOut,LogOff pVersionElemsAllocEnd8FoldElemsNew88888a8288p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOnSyntax10.Scn.Fnt#8FoldElemsNew#Syntax10.Scn.Fnt?? BEGIN IF traceP THEN Out.String(msg);Out.Ln;END; END Trace; 8&PROCEDURE Trace(msg:ARRAY OF CHAR); LogOff p(8p8E8{p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("skipInputData");LogOff pP8G8}p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jpegInitSrc");LogOff p858%jp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.Fnt((Out.String(msg); Out.Ln;Out.Int(num,4);LogOff p878Ap#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntQQOut.String("$-------------------$"); Out.F("Found MRST at Pos # $",F.Pos(sr));LogOff p8=8R8C8T8>8i8@88B88?8^8888,88,88,88-8Z8.8'8,88,88,88,8828808818\81898583yp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("resyncToRestart");LogOff po878wp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("readRestartMarker");LogOff p8/8wp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitMarkerReader");LogOff p8A88+8)8J88K88D88E8c8?878^8_8b88.8848zp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("processRestart");LogOff p>8M8p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("decodeMCU");LogOff p 8.8(xp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitHuffDecoder");LogOff p808(81808,8888'88K8zp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("decompressData");LogOff pR8J8tp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitDCoefController");LogOff p8-8w88Eyp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jcopySampleRows");LogOff p/88i{p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("yccRGBConvert");LogOff p"88O}p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("nullConvert");LogOff pk88xp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("grayscaleConvert");LogOff pk838sp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitColorDeconverter");LogOff pw8/8wp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("startPassUpsample");LogOff p88Q}p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("sepUpsample");LogOff p88xp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("fullsizeUpsample");LogOff p88|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("noopUpsample");LogOff p88{}p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("intUpsample");LogOff p!88d|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("h2v1Upsample");LogOff p88i|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("h2v2Upsample");LogOff pZ8-8{zp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitUpsampler");LogOff p(88(xp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("postProcess1Pass");LogOff p828tp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitDPostController");LogOff p8m8sp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("processDataSimpleMain");LogOff p8J8Wtp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitDMainController");LogOff p8*848/8;wp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jpegCalcOutputDim");LogOff p8)8Y|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("perScanSetup");LogOff p8(8#~p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("finishPass");LogOff p838sp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitMasterDecompress");LogOff pT8R8p|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("putPixelRows");LogOff p-8R8]|p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("putPixelRows");LogOff pA868-p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jinitDest");LogOff p828tp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jpegCreateDecompress");LogOff pX858?qp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.Fnt!!Trace("defaultDecompressParams");LogOff p8,8818-up#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jpegStartDecompress");LogOff p8M8wp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntTrace("jpegReadScanlines");LogOff p868A8B888enp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.Fnt$$Out.F(" Entering at line # $",temp);LogOff p\p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.Fnt66Out.F("Leaving at line # $",ldr.cInfo.outputScanline);LogOff pp#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.Fnt  IF(ldr.res#Pictures.needData) THEN Out.String('FEHLER$');END; CASE ldr.res OF Pictures.needData:Out.String('NeedData$'); |Pictures.error:Out.String('Fehler$'); |Pictures.done:Out.String('Fertig$'); ELSE Out.String('??????????$'); END;LogOff p_up#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntOut.String(" BIN FERTIG$$$");LogOff p98888p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntvvIF ~risc THEN Out.String("No ");END; Out.String("risc$"); IF ~rbo THEN Out.String("No ");END; Out.String("rbo$");LogOff px88{p#Syntax10.Scn.Fnt logOn LogOffLogOfflogOn#Syntax10.Scn.FntOut.String('Test123$');LogOff p 89MODULE Jpeg; IMPORT S:=SYSTEM,F:=Files,Pictures,Display,Input,Out; CONST  DCTSIZE = 8; DCTSIZE2 = 64; NUMQUANTTBLS = 4; NUMHUFFTBLS = 4; NUMARITHTBLS = 16; MAXCOMPSINSCAN = 4; MAXSAMPFACTOR = 4; MAXBLOCKSINMCU = 10; BITSINJSAMPLE = 8; MAXCOMPONENTS = 4; (* nach JFIF bis 10 *) MAXJSAMPLE = 255; CENTERJSAMPLE = 128; JPEGMAXDIMENSION = 1024; (* nach JFIF bis 65500 *) HUFFLOOKAHEAD = 8; MINGETBITS = 25; JPEGHEADEROK = 0; JPEGHEADERTABLESONLY = 1; JPEGSUSPENDED = 2; JCSUNKNOWN = 0; JCSGRAYSCALE = 1; JCSRGB = 2; JCSYCBCR = 3; DSTATESTART = 200; DSTATEINHEADER = 201; DSTATEINITDEST=202; DSTATEREADY = 203; DSTATESCANNING = 204; (* For Speedupreason an ColorArray looks like RGBDRGBD *) RGBRED = 0; RGBGREEN = 1; RGBBLUE = 2; RGBDUMMY = 3; RGBPIXELSIZE = 4; FOUNDDRI = 67; FOUNDEOI = 68; FOUNDNOTHING = 69; MainPass = 0; PrereadPass = 1; OutputPass = 2; PostPass = 3; MSOF0 = 0C0X; MSOF1 = 0C1X; MSOF2 = 0C2X; MSOF3 = 0C3X; MSOF5 = 0C5X; MSOF6 = 0C6X; MSOF7 = 0C7X; MJPG = 0C8X; MSOF9 = 0C9X; MSOF10 = 0CAX; MSOF11 = 0CBX; MSOF13 = 0CDX; MSOF14 = 0CEX; MSOF15 = 0CFX; MDHT = 0C4X; MDAC = 0CCX; MRST0 = 0D0X; MRST1 = 0D1X; MRST2 = 0D2X; MRST3 = 0D3X; MRST4 = 0D4X; MRST5 = 0D5X; MRST6 = 0D6X; MRST7 = 0D7X; MSOI = 0D8X; MEOI = 0D9X; MSOS = 0DAX; MDQT = 0DBX; MDNL = 0DCX; MDRI = 0DDX; MAPP0 = 0E0X; MAPP1 = 0E1X; MAPP2 = 0E2X; MAPP3 = 0E3X; MAPP4 = 0E4X; MAPP5 = 0E5X; MAPP6 = 0E6X; MAPP7 = 0E7X; MAPP8 = 0E8X; MAPP9 = 0E9X; MAPP10 = 0EAX; MAPP11 = 0EBX; MAPP12 = 0ECX; MAPP13 = 0EDX; MAPP14 = 0EEX; MAPP15 = 0EFX; MCOM = 0FEX; MTEM = 001X; Max = 0FFFFFH;  TYPE  CInfoPtr = POINTER TO CInfoDesc; SrcPtr = POINTER TO SrcDesc; SrcDesc = RECORD rider: F.Rider; riderStart:LONGINT; lastDRIMarker:LONGINT; END ; JSampRow = POINTER TO ARRAY (JPEGMAXDIMENSION * RGBPIXELSIZE) OF CHAR; JSampArray = POINTER TO JSADesc; JSADesc = RECORD row: ARRAY (BITSINJSAMPLE * MAXSAMPFACTOR) OF JSampRow; END ; JSampImage = POINTER TO JSIDesc; JSIDesc = RECORD comp: ARRAY MAXCOMPONENTS OF JSampArray; END ; JBlock = POINTER TO ARRAY DCTSIZE2 OF INTEGER; DCTTablePtr = POINTER TO ARRAY DCTSIZE2 OF LONGINT; JPEGCompInfoPtr = POINTER TO JPEGCompInfoDesc; JPEGCompInfoDesc = RECORD componentID: INTEGER; componentIndex: INTEGER; hSampFactor: SHORTINT; vSampFactor: SHORTINT; quantTblNo: INTEGER; dcTblNo: SHORTINT; acTblNo: SHORTINT; widthInBlocks: LONGINT; heightInBlocks: LONGINT; (*DCTScaledSize: INTEGER;*) downSampledWidth: LONGINT; componentNeeded: BOOLEAN; MCUWidth: INTEGER; MCUHeight: INTEGER; MCUBlocks: INTEGER; MCUSampleWidth: INTEGER; lastColWidth: INTEGER; lastRowHeight: INTEGER; dctTable: DCTTablePtr; END ; MarkerPtr = POINTER TO MarkerDesc; MarkerDesc = RECORD sawSOI: BOOLEAN; sawSOF: BOOLEAN; nextRestartNum: INTEGER; END ; MasterPtr = POINTER TO MasterDesc; MasterDesc = RECORD passType: SHORTINT; passNumber: INTEGER; isLastPass: BOOLEAN; END ; JHuffTblPtr = POINTER TO JHuffTbl; JHuffTbl = RECORD bits: ARRAY 17 OF INTEGER; huffVal: ARRAY 256 OF INTEGER; END ; JQuantTblPtr = POINTER TO JQuantTbl; JQuantTbl = RECORD quantVal: ARRAY DCTSIZE2 OF LONGINT; END ; SavableState = RECORD getBuffer : LONGINT; bitsLeft: INTEGER; lastDcVal: ARRAY MAXCOMPSINSCAN OF INTEGER; END ; WorkingStatePtr = POINTER TO WorkingState; WorkingState = RECORD unreadMarker: CHAR; cur: SavableState; cInfo: CInfoPtr; END ; DDerivedTblPtr = POINTER TO DDerivedTbl; DDerivedTbl = RECORD mincode: ARRAY 17 OF LONGINT; maxcode: ARRAY 18 OF LONGINT; valptr: ARRAY 17 OF INTEGER; pub: JHuffTblPtr; lookNBits: ARRAY 256 OF INTEGER; lookSym: ARRAY 256 OF INTEGER; END ; EntropyPtr = POINTER TO EntropyDesc; EntropyDesc = RECORD saved: SavableState; restartsToGo: INTEGER; dcDerivedTbls: ARRAY NUMHUFFTBLS OF DDerivedTblPtr; acDerivedTbls: ARRAY NUMHUFFTBLS OF DDerivedTblPtr; END ; DestPtr = POINTER TO DestDesc; DestDesc = RECORD buffer : JSampArray; bufferHeight: LONGINT; curOutputRow: LONGINT; END ; UpsampleProc = PROCEDURE(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); UpsamplePtr = POINTER TO UpsampleDesc; UpsampleDesc = RECORD colorBuf: ARRAY MAXCOMPONENTS OF JSampArray; nextRowOut: INTEGER; rowsToGo: LONGINT; rowGroupHeight: ARRAY MAXCOMPONENTS OF INTEGER; hExpand: ARRAY MAXCOMPONENTS OF INTEGER; vExpand: ARRAY MAXCOMPONENTS OF INTEGER; methods: ARRAY MAXCOMPONENTS OF UpsampleProc; END ; MainPtr = POINTER TO MainDesc; MainDesc = RECORD numChunks :LONGINT; buffer: JSampImage; bufferFull: BOOLEAN; rowGroupCtr: LONGINT; END ; CoefPtr = POINTER TO CoefDesc; CoefDesc = RECORD MCUColNum: LONGINT; MCURowNum: LONGINT; MCUBuffer: ARRAY MAXBLOCKSINMCU OF JBlock; END ; PostPtr = POINTER TO PostDesc; PostDesc = RECORD buffer: JSampArray; stripHeight: LONGINT; END ; CConvertPtr = POINTER TO CConvertDesc; CConvertDesc = RECORD colorConvert: PROCEDURE(cInfo:CInfoPtr; inputBuf:ARRAY OF JSampArray; inputRow: LONGINT; outputBuf:JSampArray; outRowCtr: LONGINT; numRows:INTEGER); END ; CInfoDesc = RECORD globalState: INTEGER; imageWidth: LONGINT; imageHeight: LONGINT; numComponents: SHORTINT; jpegColorSpace: INTEGER; outColorSpace: INTEGER; sawJFIFMarker: BOOLEAN; sawAdobeMarker: BOOLEAN; AdobeTransform: INTEGER; compInfo: ARRAY MAXCOMPONENTS OF JPEGCompInfoPtr; unreadMarker: CHAR; restartInterval: LONGINT; arithDcL: ARRAY NUMARITHTBLS OF INTEGER; arithDcU: ARRAY NUMARITHTBLS OF INTEGER; arithAcK: ARRAY NUMARITHTBLS OF INTEGER; arithCode: BOOLEAN; densityUnit: INTEGER; XDensity, YDensity: LONGINT; dataPrecision: SHORTINT; compsInScan: SHORTINT; curCompInfo: ARRAY MAXCOMPSINSCAN OF JPEGCompInfoPtr; dcHuffTbl: ARRAY NUMHUFFTBLS OF JHuffTblPtr; acHuffTbl: ARRAY NUMHUFFTBLS OF JHuffTblPtr; quantTbl: ARRAY NUMQUANTTBLS OF JQuantTblPtr; outputScanline: LONGINT; MCUsPerRow: LONGINT; MCURowsInScan: LONGINT; maxHSampFactor: INTEGER; maxVSampFactor: INTEGER; blocksInMCU: INTEGER; MCUMembership: ARRAY MAXBLOCKSINMCU OF INTEGER; post: PostPtr; coef: CoefPtr; cconvert: CConvertPtr; upsample: UpsamplePtr; entropy: EntropyPtr; src: SrcPtr; marker: MarkerPtr; master: MasterPtr; main: MainPtr; END ; LoadInfo = POINTER TO LoadInfoDesc; LoadInfoDesc = RECORD (Pictures.LoadInfoDesc) cInfo: CInfoPtr; dest: DestPtr; numScanlines: LONGINT; zaehler: LONGINT; END ;  VAR  ZAG: ARRAY (DCTSIZE2 + 16) OF SHORTINT; ZIG : ARRAY DCTSIZE2 OF SHORTINT; RL: ARRAY 1024 OF INTEGER; i,x: INTEGER; crRTab,cbBTab: ARRAY 257 OF INTEGER; crGTab,cbGTab: ARRAY 257 OF LONGINT; fix14,fix17,fix07,fix03: LONGINT; extendTest: ARRAY 16 OF INTEGER; extendOff: ARRAY 16 OF INTEGER; actual:LoadInfo; rbo,risc:BOOLEAN; traceP:BOOLEAN;  count : ARRAY 8, 2 OF LONGINT; (* BitRoutinen*) (*PROCEDURE LAND(x, y: LONGINT): LONGINT; BEGIN RETURN S.VAL(LONGINT, S.VAL(SET, x) * S.VAL(SET, y)) END LAND;*) PROCEDURE ILSH(x: INTEGER; n: SHORTINT): INTEGER;BEGIN IF risc THEN RETURN SHORT(S.LSH(S.VAL(LONGINT, S.VAL(SET, LONG(x)) *S.VAL(SET, 0FFFFH)),n)) ELSE RETURN S.LSH(x, n) END END ILSH; PROCEDURE ISWAP(x: INTEGER): INTEGER; TYPE integer = ARRAY 2 OF CHAR; VAR a, b: integer; BEGIN a := S.VAL(integer, x); b[0] := a[1]; b[1] := a[0]; RETURN S.VAL(INTEGER, b) END ISWAP; (*PROCEDURE LLSH(x: LONGINT; n: SHORTINT): LONGINT; BEGIN RETURN S.LSH(x, n) END LLSH;*) (*PROCEDURE LSETBIT(VAR x: LONGINT; n: SHORTINT); BEGIN ASSERT((n >= 0) & (n <= 31)); IF rbo THEN INCL(S.VAL(SET, x), 31-n) ELSE INCL(S.VAL(SET, x), n) END END LSETBIT;*)   PROCEDURE UpdFileBytes(cInfo:CInfoPtr); BEGIN cInfo.src.riderStart:=F.Pos(cInfo.src.rider); actual.usedBytes:=cInfo.src.riderStart END UpdFileBytes;  PROCEDURE SkipInputData(cInfo: CInfoPtr; numBytes:LONGINT):BOOLEAN; VAR pos: LONGINT; BEGIN  IF numBytes > 0 THEN pos:=F.Pos(cInfo.src.rider); IF (pos+numBytes <= F.Length(F.Base(cInfo.src.rider))) THEN (*enough bytes here? *) F.Set(cInfo.src.rider,F.Base(cInfo.src.rider),pos + numBytes); UpdFileBytes(cInfo); RETURN TRUE ELSE RETURN FALSE END END ; UpdFileBytes(cInfo); RETURN TRUE; END SkipInputData;  PROCEDURE JpegInitSrc(cInfo: CInfoPtr; file:F.File;startPos:LONGINT); BEGIN  IF cInfo.src = NIL THEN NEW(cInfo.src) END ; F.Set(cInfo.src.rider,file,startPos); cInfo.src.riderStart:=startPos; cInfo.src.lastDRIMarker:=0; END JpegInitSrc;  PROCEDURE ErrMsg(msg: ARRAY OF CHAR; num: INTEGER); BEGIN actual.res:=Pictures.error;  HALT(99); END ErrMsg;  PROCEDURE FoundRestartMarker(cInfo:CInfoPtr):INTEGER; VAR sr:F.Rider; c1:CHAR; BEGIN F.Set(sr,F.Base(cInfo.src.rider),cInfo.src.riderStart); c1:=0X; WHILE ~sr.eof DO F.Read(sr,c1); IF c1=0FFX THEN F.Read(sr,c1); (* it has to be another marker than the last found as the last found is possibly not yet processed *) IF (c1>= MRST0) & (c1 <= MRST7) & (F.Pos(sr) > cInfo.src.lastDRIMarker )THEN cInfo.src.lastDRIMarker:=F.Pos(sr); RETURN FOUNDDRI END ; IF (c1 = MEOI) THEN RETURN FOUNDEOI END ; END ; END ; RETURN FOUNDNOTHING; END FoundRestartMarker;  PROCEDURE ReadChar(cInfo: CInfoPtr; VAR char:CHAR):BOOLEAN; BEGIN F.Read(cInfo.src.rider,char); RETURN ~cInfo.src.rider.eof; END ReadChar;  PROCEDURE ReadShort(cInfo: CInfoPtr; VAR short:SHORTINT):BOOLEAN; BEGIN F.Read(cInfo.src.rider,short); RETURN ~cInfo.src.rider.eof; END ReadShort;  PROCEDURE ReadInt(cInfo: CInfoPtr; VAR int:INTEGER):BOOLEAN; BEGIN F.ReadInt(cInfo.src.rider, int); int := ISWAP(int); RETURN ~cInfo.src.rider.eof ; END ReadInt;  PROCEDURE ReadUINT8(cInfo: CInfoPtr; VAR int:INTEGER):BOOLEAN; VAR char:CHAR; BEGIN F.Read(cInfo.src.rider,char); IF ~cInfo.src.rider.eof THEN int:=ORD(char); RETURN TRUE; ELSE RETURN FALSE; END ; END ReadUINT8;  PROCEDURE ReadUINT16(cInfo: CInfoPtr; VAR long:LONGINT):BOOLEAN; VAR int1,int0: INTEGER; ch: CHAR; BEGIN F.Read(cInfo.src.rider,ch); int1 := ORD(ch); F.Read(cInfo.src.rider,ch); int0 := ORD(ch); long := 256 * LONG(int1) + int0; RETURN ~cInfo.src.rider.eof ; END ReadUINT16;  PROCEDURE ByteSplit(int:INTEGER; VAR byte03,byte47:SHORTINT); BEGIN byte03 := SHORT(int MOD 10H); byte47 := SHORT((int DIV 10H) MOD 10H); END ByteSplit;  PROCEDURE CheckJpeg(f:F.File;pos : LONGINT) : BOOLEAN; VAR r : F.Rider; soiMarker : ARRAY 2 OF CHAR; BEGIN F.Set(r, f, pos); F.ReadBytes(r, soiMarker, 2); RETURN (soiMarker[0]=0FFX) & (soiMarker[1]= 0D8X) END CheckJpeg;  PROCEDURE GetSOI(cInfo: CInfoPtr):BOOLEAN; VAR i:INTEGER; BEGIN IF cInfo.marker.sawSOI THEN HALT(82) END ; i:=0; WHILE i< NUMARITHTBLS DO cInfo.arithDcL[i] :=0; cInfo.arithDcU[i] :=1; cInfo.arithAcK[i] :=5; INC(i); END ; cInfo.restartInterval := 0; cInfo.jpegColorSpace := JCSUNKNOWN; cInfo.sawJFIFMarker := FALSE; cInfo.densityUnit := 0; cInfo.XDensity := 1; cInfo.YDensity := 1; cInfo.sawAdobeMarker := FALSE; cInfo.AdobeTransform:=0; cInfo.marker.sawSOI :=TRUE; RETURN TRUE; END GetSOI;  PROCEDURE GetSOF(cInfo: CInfoPtr):BOOLEAN; VAR c,ci:INTEGER; length:INTEGER; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; IF ~ReadShort(cInfo,cInfo.dataPrecision) THEN RETURN FALSE END ; IF ~ReadUINT16(cInfo,cInfo.imageHeight) THEN RETURN FALSE END ; IF ~ReadUINT16(cInfo,cInfo.imageWidth) THEN RETURN FALSE END ; IF ~ReadShort(cInfo,cInfo.numComponents) THEN RETURN FALSE END ; DEC(length,8); IF cInfo.marker.sawSOF THEN ErrMsg("SOF-block found twice", 2) END ; IF (cInfo.imageHeight <=0) OR (cInfo.imageWidth<=0) OR (cInfo.numComponents <=0) THEN ErrMsg("not implemented", 3) END ; IF (cInfo.imageHeight > JPEGMAXDIMENSION) OR (cInfo.imageWidth > JPEGMAXDIMENSION) THEN ErrMsg("SOF-block: image too large", 4) END ; IF cInfo.dataPrecision # BITSINJSAMPLE THEN ErrMsg("SOF-block: data-precision # 8", 5) END ; IF cInfo.numComponents > MAXCOMPONENTS THEN ErrMsg("SOF-block: too many components", 6) END ; IF length # (cInfo.numComponents * 3) THEN ErrMsg("SOF-block: wrong block length", 7) END ; ci:=0; WHILE ci < cInfo.numComponents DO IF cInfo.compInfo[ci] = NIL THEN NEW(cInfo.compInfo[ci]) END ; cInfo.compInfo[ci].componentIndex := ci; IF ~ReadUINT8(cInfo,cInfo.compInfo[ci].componentID) THEN RETURN FALSE END ; IF ~ReadUINT8(cInfo,c) THEN RETURN FALSE END ; ByteSplit(c,cInfo.compInfo[ci].vSampFactor,cInfo.compInfo[ci].hSampFactor); IF ~ReadUINT8(cInfo,cInfo.compInfo[ci].quantTblNo) THEN RETURN FALSE END ; INC(ci); END ; cInfo.marker.sawSOF:=TRUE; RETURN TRUE; END GetSOF;  PROCEDURE GetSOS(cInfo: CInfoPtr):BOOLEAN; VAR c,ci,cc,ccc:INTEGER; i,n:SHORTINT; length:INTEGER; fehler: BOOLEAN; compptr: JPEGCompInfoPtr; BEGIN IF ~cInfo.marker.sawSOF THEN ErrMsg("SOS-block: no SOF block found", 8) END ; IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; IF ~ReadShort(cInfo,n) THEN RETURN FALSE END ; IF (length # (n*2 + 6)) OR (n<1) OR (n> MAXCOMPSINSCAN) THEN ErrMsg("SOS-block: wrong data length", 9) END ; cInfo.compsInScan:=n; i:=0; WHILE i= 14 THEN FOR buffp := 0 TO 4 DO IF ~ReadChar(cInfo,b[buffp]) THEN RETURN FALSE END ; END ; IF ~ReadUINT8(cInfo,version) THEN RETURN FALSE END ; IF ~ReadUINT8(cInfo,help) THEN RETURN FALSE END ; DEC(length,12); IF (b[0] = 4AX) & (b[1] = 46X) & (b[2] = 49X) & (b[3] = 46X) & (b[4] = 0X) THEN IF version # 1 THEN ErrMsg("App0-block: wrong version", 12) END ; cInfo.sawJFIFMarker:=TRUE; IF ~ReadUINT8(cInfo,cInfo.densityUnit) THEN RETURN FALSE END ; IF ~ReadUINT16(cInfo,cInfo.XDensity) THEN RETURN FALSE END ; IF ~ReadUINT16(cInfo,cInfo.YDensity) THEN RETURN FALSE END ; END ; END ; IF length > 0 THEN RETURN SkipInputData(cInfo,length) END ; RETURN TRUE; END GetApp0;  PROCEDURE GetApp14(cInfo: CInfoPtr):BOOLEAN; VAR b : ARRAY 5 OF CHAR; length,dummy,buffp :INTEGER; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; DEC(length,2); IF length >= 12 THEN FOR buffp := 0 TO 4 DO IF ~ReadChar(cInfo,b[buffp]) THEN RETURN FALSE END ; END ; IF ~ReadInt(cInfo,dummy) THEN RETURN FALSE END ; IF ~ReadInt(cInfo,dummy) THEN RETURN FALSE END ; IF ~ReadInt(cInfo,dummy) THEN RETURN FALSE END ; IF ~ReadUINT8(cInfo,cInfo.AdobeTransform) THEN RETURN FALSE END ; DEC(length,12); IF (b[0] = 41X) & (b[1] = 64X) & (b[2] = 6FX) & (b[3] = 62X) & (b[4] = 65X) THEN cInfo.sawAdobeMarker:=TRUE; ELSE ErrMsg("App14-Block: bad Adobe-Marker", 13) END ; ELSE ErrMsg("App14-Block: bad Adobe-Marker", 14) END ; IF length > 0 THEN RETURN SkipInputData(cInfo,length) END ; RETURN TRUE; END GetApp14;  PROCEDURE GetDAC(cInfo: CInfoPtr):BOOLEAN; VAR index,help1,help2: SHORTINT; length,val :INTEGER; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; DEC(length,2); WHILE length > 0 DO IF ~ReadShort(cInfo,index) THEN RETURN FALSE END ; IF ~ReadUINT8(cInfo,val) THEN RETURN FALSE END ; DEC(length,2); IF (index < 0) OR (index >= (2*NUMARITHTBLS)) THEN ErrMsg("DAC-Block: bad DAC-Index", 15) END ; IF index >= NUMARITHTBLS THEN cInfo.arithAcK[index - NUMARITHTBLS] := val; ELSE ByteSplit(val,help1,help2); cInfo.arithDcL[index]:=help1; cInfo.arithDcU[index]:=help2; IF cInfo.arithDcL[index] > cInfo.arithDcU[index] THEN ErrMsg("DAC-Block: bad DAC-Value", 16) END ; END ; END ; RETURN TRUE; END GetDAC;  PROCEDURE GetDHT(cInfo: CInfoPtr):BOOLEAN; VAR bits: ARRAY 17 OF INTEGER; huffVal: ARRAY 256 OF INTEGER; length,i,index,count :INTEGER; htblptr: JHuffTblPtr; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; DEC(length,2); WHILE length > 0 DO IF ~ReadUINT8(cInfo,index) THEN RETURN FALSE END ; bits[0] :=0; count:=0; FOR i:=1 TO 16 DO IF ~ReadUINT8(cInfo,bits[i]) THEN RETURN FALSE END ; INC(count,bits[i]); END ; DEC(length,17); IF (count > 256) OR (count > length) THEN ErrMsg("DHT-block: bad summe", 17) END ; FOR i:=0 TO count -1 DO IF ~ReadUINT8(cInfo,huffVal[i]) THEN RETURN FALSE END ; END ; DEC(length,count); IF index >= NUMARITHTBLS THEN DEC(index,NUMARITHTBLS); IF cInfo.acHuffTbl[index] = NIL THEN NEW(cInfo.acHuffTbl[index]) END ; htblptr:= cInfo.acHuffTbl[index]; ELSE IF cInfo.dcHuffTbl[index] = NIL THEN NEW(cInfo.dcHuffTbl[index]) END ; htblptr:= cInfo.dcHuffTbl[index]; END ; IF (index < 0) OR (index >= NUMHUFFTBLS) THEN ErrMsg("DHT-block: bad index", 18) END ; FOR i:=0 TO 16 DO htblptr.bits[i]:=bits[i] END ; FOR i:=0 TO count -1 DO htblptr.huffVal[i]:=huffVal[i] END ; END ; RETURN TRUE; END GetDHT;  PROCEDURE GetDQT(cInfo: CInfoPtr):BOOLEAN; VAR quantptr: JQuantTblPtr; length,i,n,tmp :INTEGER; prec,index :SHORTINT; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; DEC(length,2); WHILE length > 0 DO IF ~ReadUINT8(cInfo,n) THEN RETURN FALSE END ; ByteSplit(n,index,prec); IF cInfo.quantTbl[index] = NIL THEN NEW(cInfo.quantTbl[index]) END ; quantptr:=cInfo.quantTbl[index]; FOR i:=0 TO DCTSIZE2 - 1 DO IF prec # 0 THEN IF ~ReadUINT16(cInfo,quantptr.quantVal[i]) THEN RETURN FALSE END ; ELSE IF ~ReadUINT8(cInfo,tmp) THEN RETURN FALSE END ; quantptr.quantVal[i]:=tmp; END ; END ; DEC(length,DCTSIZE2 + 1); IF prec # 0 THEN DEC(length,DCTSIZE2) END ; END ; RETURN TRUE; END GetDQT;  PROCEDURE GetDRI(cInfo: CInfoPtr):BOOLEAN; VAR length :INTEGER; BEGIN IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; IF length # 4 THEN ErrMsg("DRI-block: wrng length", 19) END ; IF ~ReadUINT16(cInfo,cInfo.restartInterval) THEN RETURN FALSE END ; RETURN TRUE; END GetDRI;  PROCEDURE SkipVariable(cInfo: CInfoPtr):BOOLEAN; VAR length :INTEGER; BEGIN (* 1st 2 Bytes of marker are always length of it *) IF ~ReadInt(cInfo,length) THEN RETURN FALSE END ; DEC(length,2); RETURN SkipInputData(cInfo,length); END SkipVariable;  PROCEDURE NextMarker(cInfo: CInfoPtr):BOOLEAN; VAR c:CHAR; BEGIN LOOP IF ~ReadChar(cInfo,c) THEN RETURN FALSE END ; (* Marker always starts with FF *) WHILE c # 0FFX DO IF ~ReadChar(cInfo,c) THEN RETURN FALSE END ; END ; (*second byte of marker must not be FF *) REPEAT IF ~ReadChar(cInfo,c) THEN RETURN FALSE END ; UNTIL c # 0FFX; IF c # 0X THEN EXIT END ; END ; (*Loop*) (* marker to analyze *) cInfo.unreadMarker := c; RETURN TRUE; END NextMarker;  PROCEDURE FirstMarker(cInfo: CInfoPtr):BOOLEAN; VAR c,c2:CHAR; BEGIN IF ~ReadChar(cInfo,c) THEN RETURN FALSE END ; IF ~ReadChar(cInfo,c2) THEN RETURN FALSE END ; (* File must have these 2 Bytes at start *) IF (c # 0FFX) OR (c2 # MSOI) THEN ErrMsg("firstMarker: no MSOI marker found", 1); RETURN FALSE END ; cInfo.unreadMarker := c2; UpdFileBytes(cInfo); RETURN TRUE; END FirstMarker;  PROCEDURE ReadMarkers(cInfo: CInfoPtr):INTEGER; BEGIN (* JPEGSUSPENDED = Marker could not be read successfull *) LOOP IF cInfo.unreadMarker = 0X THEN IF ~cInfo.marker.sawSOI THEN IF ~ FirstMarker(cInfo) THEN RETURN JPEGSUSPENDED END ; ELSE IF ~ NextMarker(cInfo) THEN RETURN JPEGSUSPENDED END ; END ; END ; CASE cInfo.unreadMarker OF MSOI: (* Has got no Data *) IF ~GetSOI(cInfo) THEN RETURN JPEGSUSPENDED END ; | MSOF0: cInfo.arithCode:=FALSE; IF ~GetSOF(cInfo) THEN cInfo.marker.sawSOF:=FALSE;RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MSOF1: cInfo.arithCode:=FALSE; IF ~GetSOF(cInfo) THEN cInfo.marker.sawSOF:=FALSE;RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MSOF9: cInfo.arithCode:=TRUE; IF ~GetSOF(cInfo) THEN cInfo.marker.sawSOF:=FALSE;RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MSOF2: ErrMsg("Progressive Huffmann not supported", 20) | MSOF3: ErrMsg("Lossless Huffmann not supported", 21) | MSOF5: ErrMsg("Differential seq. Huffmann not supported", 22) | MSOF6: ErrMsg("Differential prog. Huffmann not supported", 23) | MSOF7: ErrMsg("Differential loss. Huffmann not supported", 24) | MJPG: ErrMsg("MJPG not supported", 25) | MSOF10: ErrMsg("Progressive arithmetic not supported", 26) | MSOF11: ErrMsg("Lossless arithmetic not supported", 27) | MSOF13: ErrMsg("Differential seq. arithmetic not supported", 28) | MSOF14: ErrMsg("Differential prog. arithmetic not supported", 29) | MSOF15: ErrMsg("Differential loss. arithmetic not supported", 30) | MSOS: IF ~GetSOS(cInfo) THEN RETURN JPEGSUSPENDED END ; cInfo.unreadMarker := 0X; UpdFileBytes(cInfo); RETURN JPEGHEADEROK; | MEOI: UpdFileBytes(cInfo); RETURN JPEGHEADERTABLESONLY; (*end of image after header reached :( *) | MDAC: IF ~GetDAC(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MDHT: IF ~GetDHT(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MDQT: IF ~GetDQT(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MDRI: IF ~GetDRI(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MAPP0: IF ~GetApp0(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo); END ; (* Application specific headers.... dont have got infos about them.. *) | MAPP1: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MAPP2: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MAPP3: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MAPP4: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MAPP5: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MAPP6: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP7: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP8: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP9: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP10: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP11: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP12: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP13: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MAPP14: IF ~GetApp14(cInfo) THEN RETURN JPEGSUSPENDED ELSE UpdFileBytes(cInfo) END ; | MAPP15: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; | MCOM: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END | MRST0: (* nothing to do *) | MRST1: (* nothing to do *) | MRST2: (* nothing to do *) | MRST3: (* nothing to do *) | MRST4: (* nothing to do *) | MRST5: (* nothing to do *) | MRST6: (* nothing to do *) | MRST7: (* nothing to do *) | MTEM: (* nothing to do *) | MDNL: IF ~SkipVariable(cInfo) THEN RETURN JPEGSUSPENDED END ; ELSE ErrMsg("inknown marker", 31) END ; cInfo.unreadMarker:=0X; END (* Loop *); END ReadMarkers;  PROCEDURE ResyncToRestart(cInfo: CInfoPtr):BOOLEAN; VAR marker:CHAR; desired,action:INTEGER; BEGIN  action:=1; desired := cInfo.marker.nextRestartNum; marker := cInfo.unreadMarker; LOOP IF marker < MSOF0 THEN action:=2 ELSIF (marker < MRST0) OR (marker > MRST7) THEN action := 3 ELSE IF (ORD(marker) = (208 + ((desired + 1) MOD 8))) OR (ORD(marker) = (208 + ((desired + 2) MOD 8))) THEN action:=3 ELSIF (ORD(marker) = (208 + ((desired - 1) MOD 8))) OR (ORD(marker) = (208 + ((desired - 2) MOD 8))) THEN action:=2 ELSE action := 1 END ; END ; CASE action OF 1:(*everything ok, i have to live with a wrong mrst marker *) cInfo.unreadMarker := 0X; RETURN TRUE; | 2: (*Sof marker found or a premature MRSTmarker found.. so lets get next marker *) IF ~NextMarker(cInfo) THEN RETURN FALSE END ; marker := cInfo.unreadMarker; | 3: (*another marker was found *) RETURN TRUE; END ; END ; (* Loop *) END ResyncToRestart;  PROCEDURE ReadRestartMarker(cInfo: CInfoPtr):BOOLEAN; BEGIN  IF cInfo.unreadMarker = 0X THEN IF ~NextMarker(cInfo) THEN RETURN FALSE END ; END ; (* found wrong mrst marker? *) IF ORD(cInfo.unreadMarker) = (208 + cInfo.marker.nextRestartNum) THEN cInfo.unreadMarker:= 0X; ELSE IF ~ResyncToRestart(cInfo) THEN RETURN FALSE END ; END ; cInfo.marker.nextRestartNum := (cInfo.marker.nextRestartNum + 1) MOD 8; RETURN TRUE; END ReadRestartMarker;  PROCEDURE JinitMarkerReader(cInfo: CInfoPtr); BEGIN  IF cInfo.marker = NIL THEN NEW(cInfo.marker) END ; cInfo.unreadMarker := 0X; cInfo.marker.sawSOI := FALSE; cInfo.marker.sawSOF := FALSE; END JinitMarkerReader;  PROCEDURE FixHuffTbl(htbl: JHuffTblPtr; pdtbl: DDerivedTblPtr); VAR p,i,I,si,k: INTEGER; lookbits: LONGINT; huffsize: ARRAY 257 OF INTEGER; huffcode: ARRAY 257 OF LONGINT; code,ctr: LONGINT; BEGIN pdtbl.pub := htbl; (*make Table of Huffman code length for each symbol (in code lenght order) *) p := 0; FOR I := 1 TO 16 DO i := 1; WHILE i <= htbl.bits[I] DO huffsize[p] := I; INC(p); INC(i); END ; END ; huffsize[p] := 0; (* Generate Codes themselves (again in codelength order *) code := 0; si := huffsize[0]; p:= 0; WHILE huffsize[p] # 0 DO WHILE huffsize[p] = si DO huffcode[p] := code; INC(p); INC(code); END ; code := code * 2; INC(si); END ; (* fill encoding tables *) p := 0; FOR I := 1 TO 16 DO IF htbl.bits[I] # 0 THEN pdtbl.valptr[I] := p; pdtbl.mincode[I] := huffcode[p]; p := htbl.bits[I] + p; pdtbl.maxcode[I] := huffcode[p-1]; ELSE pdtbl.maxcode[I] := -1; END ; END ; (* ensures huff_decode to terminate *) pdtbl.maxcode[17] := Max; FOR p:=0 TO 255 DO pdtbl.lookNBits[p] := 0 END ; p:= 0; (* Generate table of symbol and length of the symbol *) FOR k:=1 TO HUFFLOOKAHEAD DO i:= 1; WHILE i<= htbl.bits[k] DO lookbits:= ASH(huffcode[p],(HUFFLOOKAHEAD - k)); ctr := ASH(1,(HUFFLOOKAHEAD - k)); WHILE ctr > 0 DO pdtbl.lookNBits[lookbits] := k; pdtbl.lookSym[lookbits] := htbl.huffVal[p]; INC(lookbits); DEC(ctr); END ; INC(p); INC(i); END ; END ; END FixHuffTbl;  PROCEDURE StartPassHuff(cInfo: CInfoPtr); VAR ci,dctbl,actbl: INTEGER; compptr: JPEGCompInfoPtr; BEGIN FOR ci:= 0 TO cInfo.compsInScan - 1 DO compptr := cInfo.curCompInfo[ci]; dctbl := compptr.dcTblNo; actbl := compptr.acTblNo; IF (dctbl < 0) OR (dctbl >= NUMHUFFTBLS) OR (cInfo.dcHuffTbl[dctbl] = NIL) THEN ErrMsg("Huff-startPass: bad Huffman dc - Table", 32) END ; IF (actbl < 0) OR (actbl >= NUMHUFFTBLS) OR (cInfo.acHuffTbl[actbl] = NIL) THEN ErrMsg("Huff-startPass: bad Huffman ac - Table", 33) END ; IF cInfo.entropy.dcDerivedTbls[dctbl] = NIL THEN NEW(cInfo.entropy.dcDerivedTbls[dctbl]); END ; IF cInfo.entropy.acDerivedTbls[actbl] = NIL THEN NEW(cInfo.entropy.acDerivedTbls[actbl]); END ; (* Fill ac and dc coefficent table with derived values *) FixHuffTbl(cInfo.dcHuffTbl[dctbl],cInfo.entropy.dcDerivedTbls[dctbl]); FixHuffTbl(cInfo.acHuffTbl[actbl],cInfo.entropy.acDerivedTbls[actbl]); cInfo.entropy.saved.lastDcVal[ci] := 0; END ; cInfo.entropy.saved.bitsLeft := 0; cInfo.entropy.restartsToGo := SHORT(cInfo.restartInterval); END StartPassHuff;  PROCEDURE FillBitBuffer(state: WorkingStatePtr; nbits: INTEGER):BOOLEAN; VAR getBuffer: LONGINT; bitsLeft,x,i,k: INTEGER; c: CHAR; source:SrcPtr; BEGIN bitsLeft := state.cur.bitsLeft; getBuffer := state.cur.getBuffer; source:=state.cInfo.src; (* *) LOOP (* Attempt to load at least MINGETBITS into getbits *) IF bitsLeft >= MINGETBITS THEN EXIT END ; IF state.unreadMarker # 0X THEN IF bitsLeft >= nbits THEN EXIT END ; (*data ok *) c := 0X; ELSE (*IF ~ReadChar(state.cInfo,c) THEN RETURN FALSE END ;*) (*F.Read(state.cInfo.src.rider,c);*) F.Read(source.rider,c); IF source.rider.eof THEN RETURN FALSE END ; IF c = 0FFX THEN REPEAT (*IF ~ReadChar(state.cInfo,c) THEN RETURN FALSE END ;*) (*F.Read(state.cInfo.src.rider,c);*) F.Read(source.rider,c); IF source.rider.eof THEN RETURN FALSE END ; UNTIL c # 0FFX; IF c = 0X THEN c:= 0FFX; ELSE state.unreadMarker := c; IF bitsLeft >= nbits THEN EXIT END ; c := 0X; END ; END ; END ; (* load c into getBuffer *) (*getBuffer := LLSH(getBuffer, 8);OK*) getBuffer:=S.LSH(getBuffer, 8); x := ORD(c); k := 128; i := 8; (* Bit by Bit *) WHILE i > 0 DO DEC(i); IF (x DIV k) > 0 THEN (*LSETBIT(getBuffer, SHORT(i))*) IF rbo THEN INCL(S.VAL(SET, getBuffer), 31-SHORT(i)) ELSE INCL(S.VAL(SET, getBuffer), SHORT(i)) END END ; x := x MOD k; k := k DIV 2; END ; (* New 8 bits in Buffer *) INC(bitsLeft,8); END ; state.cur.getBuffer := getBuffer; state.cur.bitsLeft := bitsLeft; RETURN TRUE; END FillBitBuffer;  PROCEDURE CheckBitBuffer(state: WorkingStatePtr; nbits: INTEGER):BOOLEAN; BEGIN (* Fill Bitbuffer if not enough bytes in it *) IF state.cur.bitsLeft < nbits THEN RETURN FillBitBuffer(state,nbits) ; END ; RETURN TRUE; END CheckBitBuffer;  PROCEDURE GetBits(state: WorkingStatePtr; nbits: INTEGER):INTEGER; VAR i: INTEGER; helpSet,helpSet2: LONGINT; BEGIN helpSet:=S.LSH(state.cur.getBuffer,SHORT(-(state.cur.bitsLeft-nbits))); helpSet2 := 0; FOR i:=0 TO nbits - 1 DO (* get andbitmask *) IF rbo THEN INCL(S.VAL(SET, helpSet2), 31-SHORT(i)) ELSE INCL(S.VAL(SET, helpSet2), SHORT(i)) END END ; (* Delete possible upper set bits *) helpSet:=S.VAL(LONGINT, S.VAL(SET, helpSet) * S.VAL(SET, helpSet2)); DEC(state.cur.bitsLeft,nbits); RETURN SHORT(helpSet); END GetBits;  PROCEDURE PeekBits(state: WorkingStatePtr; nbits: INTEGER):INTEGER; VAR i: INTEGER; helpSet,helpSet2: LONGINT; BEGIN (*Same as GetBits but without deceasing number of bytes *) (*helpSet := LLSH(state.cur.getBuffer,SHORT(-(state.cur.bitsLeft-nbits)));*) helpSet:=S.LSH(state.cur.getBuffer,SHORT(-(state.cur.bitsLeft-nbits))); helpSet2 := 0; FOR i:=0 TO nbits - 1 DO (*LSETBIT(helpSet2, SHORT(i)) END ;*) IF rbo THEN INCL(S.VAL(SET, helpSet2), 31-SHORT(i)) ELSE INCL(S.VAL(SET, helpSet2), SHORT(i)) END END ; (*helpSet := LAND(helpSet, helpSet2);*) helpSet:=S.VAL(LONGINT, S.VAL(SET, helpSet) * S.VAL(SET, helpSet2)); RETURN SHORT(helpSet); END PeekBits;  (*PROCEDURE DropBits(state: WorkingStatePtr; nbits: INTEGER); BEGIN DEC(state.cur.bitsLeft,nbits); END DropBits;*)  PROCEDURE SlowDECODE(state: WorkingStatePtr; htbl: DDerivedTblPtr; minBits:INTEGER):INTEGER; VAR i: INTEGER; code: LONGINT; codeset: LONGINT; BEGIN i := minBits; IF ~CheckBitBuffer(state,i) THEN RETURN -1 END ; code := GetBits(state,i);(* Get Code *) WHILE code > htbl.maxcode[i] DO (*code has to be bigger than largest code of i+1*) codeset := code*2; (*make code 1 bit bigger *) IF ~CheckBitBuffer(state,1) THEN RETURN -1 END ; (*IF GetBits(state,1) = 1 THEN LSETBIT(codeset,0) END ;*)(*set last bit if next bit in buffer =1*) IF GetBits(state,1) = 1 THEN IF rbo THEN INCL(S.VAL(SET, codeset), 31) ELSE INCL(S.VAL(SET, codeset), 0) END END ; code := codeset; INC(i); (* next loop i -> i+1 *) END ; IF i > 16 THEN (* shouldnt be *) RETURN 0; END ; (*1st symbol of this length+ code(=offset)- smallest code= index *) RETURN htbl.pub.huffVal[htbl.valptr[i] + code - htbl.mincode[i]]; END SlowDECODE;  PROCEDURE HuffDECODE(VAR result: INTEGER; state: WorkingStatePtr; htbl: DDerivedTblPtr):BOOLEAN; VAR nb,look,i: INTEGER; helpSet,helpSet2: LONGINT; BEGIN IF state.cur.bitsLeft < HUFFLOOKAHEAD THEN IF ~FillBitBuffer(state,0) THEN RETURN FALSE END ; IF state.cur.bitsLeft < HUFFLOOKAHEAD THEN (* not enough Bits in Hufflookahead*) result := SlowDECODE(state,htbl,1); RETURN result >=0 ; END ; END ; (* look how many bits of code are useable *) (*look := PeekBits(state,HUFFLOOKAHEAD);*) helpSet:=S.LSH(state.cur.getBuffer,SHORT(-(state.cur.bitsLeft-HUFFLOOKAHEAD))); helpSet2 := 0; FOR i:=0 TO HUFFLOOKAHEAD - 1 DO (*LSETBIT(helpSet2, SHORT(i)) END ;*) IF rbo THEN INCL(S.VAL(SET, helpSet2), 31-SHORT(i)) ELSE INCL(S.VAL(SET, helpSet2), SHORT(i)) END END ; helpSet:=S.VAL(LONGINT, S.VAL(SET, helpSet) * S.VAL(SET, helpSet2)); look := SHORT(helpSet); nb := htbl.lookNBits[look]; IF nb # 0 THEN (* drop the useable bits*) (*DropBits(state,nb);*) DEC(state.cur.bitsLeft,nb); result := htbl.lookSym[look]; (* and get the symbol *) ELSE (* ouch. code is longer than 8 Bits *) result := SlowDECODE(state,htbl,HUFFLOOKAHEAD + 1); IF result < 0 THEN RETURN FALSE END ; END ; RETURN TRUE; END HuffDECODE;  (*PROCEDURE HuffEXTEND(x,s:INTEGER):INTEGER; BEGIN (* sth bit not set? -> set it with add else everything is ok *) IF x < extendTest[s] THEN RETURN x + extendOff[s] ELSE RETURN x END ; END HuffEXTEND ;*)  PROCEDURE ProcessRestart(cInfo: CInfoPtr):BOOLEAN; VAR ci: INTEGER; BEGIN  (* empty buffer *) cInfo.entropy.saved.bitsLeft := 0; IF ~ReadRestartMarker(cInfo) THEN RETURN FALSE END ; (* New dc-values *) FOR ci := 0 TO cInfo.compsInScan - 1 DO cInfo.entropy.saved.lastDcVal[ci] := 0; END ; cInfo.entropy.restartsToGo := SHORT(cInfo.restartInterval); RETURN TRUE; END ProcessRestart;  PROCEDURE DecodeMCU(cInfo: CInfoPtr; VAR MCUData: ARRAY OF JBlock):BOOLEAN; VAR s,k,r,blkn,ci: INTEGER; set: LONGINT; block: JBlock; state: WorkingStatePtr; dctbl,actbl: DDerivedTblPtr; compptr: JPEGCompInfoPtr; (* From GetBits *) i: INTEGER; helpSet,helpSet2: LONGINT; BEGIN  set := 15; NEW(state); IF (cInfo.restartInterval # 0) & (cInfo.entropy.restartsToGo = 0) THEN IF ~ProcessRestart(cInfo) THEN RETURN FALSE END ; END ; state.unreadMarker := cInfo.unreadMarker; state.cur := cInfo.entropy.saved; state.cInfo := cInfo; FOR blkn := 0 TO cInfo.blocksInMCU -1 DO block := MCUData[blkn];(*copy important data of mcu for this block *) ci := cInfo.MCUMembership[blkn]; compptr := cInfo.curCompInfo[ci]; (* like the component the mcu is member *) dctbl := cInfo.entropy.dcDerivedTbls[compptr.dcTblNo];(* and of course the ac and dc*) actbl := cInfo.entropy.acDerivedTbls[compptr.acTblNo];(*coefficient tables *) IF ~HuffDECODE(s,state,dctbl) THEN RETURN FALSE END ; IF s#0 THEN (* remove signed bit of DC component *) IF ~CheckBitBuffer(state,s) THEN RETURN FALSE END ; r := GetBits(state,s); (*s := HuffEXTEND(r,s);*) IF r < extendTest[s] THEN s := r + extendOff[s] ELSE s:= r END END ; IF compptr.componentNeeded THEN INC(s,state.cur.lastDcVal[ci]); state.cur.lastDcVal[ci] := s; block[0] := s; k := 1; WHILE k < DCTSIZE2 DO IF ~HuffDECODE(s,state,actbl) THEN RETURN FALSE END ; (*r := ILSH(s, -4);*) IF risc THEN r := SHORT(S.LSH(S.VAL(LONGINT, S.VAL(SET, LONG(s)) *S.VAL(SET, 0FFFFH)),-4)) ELSE r:= S.LSH(s, -4) END ; (*s := SHORT(LAND(LONG(s), set));*) s:=SHORT(S.VAL(LONGINT, S.VAL(SET, LONG(s)) * S.VAL(SET, set))); IF s#0 THEN INC(k,r); IF ~CheckBitBuffer(state,s) THEN RETURN FALSE END ; r := GetBits(state,s); (*s := HuffEXTEND(r,s);*) IF r < extendTest[s] THEN s := r + extendOff[s] ELSE s:= r END ; (* ZAG[k] -> in Zig-ZagAnordnung in Matrix bringen *) block[ZAG[k]] := s; ELSE IF r # 15 THEN k:=DCTSIZE2 ELSE INC(k,15); END ; END ; INC(k);(* Next pos in Matrix *) END ; ELSE k := 1; WHILE k < DCTSIZE2 DO IF ~HuffDECODE(s,state,actbl) THEN RETURN FALSE END ; (*r := ILSH(s, -4);*) IF risc THEN r := SHORT(S.LSH(S.VAL(LONGINT, S.VAL(SET, LONG(s)) *S.VAL(SET, 0FFFFH)),-4)) ELSE r:= S.LSH(s, -4) END ; (*s := SHORT(LAND(LONG(s), set));*) s:=SHORT(S.VAL(LONGINT, S.VAL(SET, LONG(s)) * S.VAL(SET, set))); IF s#0 THEN INC(k,r); IF ~CheckBitBuffer(state,s) THEN RETURN FALSE END ; (*DropBits(state,s);*) DEC(state.cur.bitsLeft,s); ELSE IF r # 15 THEN k:=DCTSIZE2 ELSE INC(k,15); END ; END ; INC(k); END ; END ; END ; cInfo.unreadMarker := state.unreadMarker; cInfo.entropy.saved := state.cur; DEC(cInfo.entropy.restartsToGo); RETURN TRUE; END DecodeMCU;  PROCEDURE JinitHuffDecoder(cInfo: CInfoPtr); VAR i: INTEGER; e:EntropyPtr; BEGIN  NEW(cInfo.entropy); e:=cInfo.entropy; FOR i:= 0 TO NUMHUFFTBLS -1 DO e.dcDerivedTbls[i] := NIL; e.acDerivedTbls[i] := NIL; END ; END JinitHuffDecoder;  PROCEDURE StartInputPassIDCT(cInfo: CInfoPtr); VAR ci,qtblno,i: INTEGER; compptr: JPEGCompInfoPtr; qtbl: JQuantTblPtr; si: ARRAY DCTSIZE2 OF INTEGER; BEGIN (* values needed for IDCT *) si[0] := 16384; si[1] := 22725; si[2] := 21407; si[3] := 19266; si[4] := 16384; si[5] := 12873; si[6] := 8867; si[7] := 4520; si[8] := 22725; si[9] := 31521; si[10] := 29692; si[11] := 26722; si[12] := 22725; si[13] := 17855; si[14] := 12299; si[15] := 6270; si[16] := 21407; si[17] := 29692; si[18] := 27969; si[19] := 25172; si[20] := 21407; si[21] := 16819; si[22] := 11585; si[23] := 5906; si[24] := 19266; si[25] := 26722; si[26] := 25172; si[27] := 22654; si[28] := 19266; si[29] := 15137; si[30] := 10426; si[31] := 5315; si[32] := 16384; si[33] := 22725; si[34] := 21407; si[35] := 19266; si[36] := 16384; si[37] := 12873; si[38] := 8867; si[39] := 4520; si[40] := 12873; si[41] := 17855; si[42] := 16819; si[43] := 15137; si[44] := 12873; si[45] := 10114; si[46] := 6967; si[47] := 3552; si[48] := 8867; si[49] := 12299; si[50] := 11585; si[51] := 10426; si[52] := 8867; si[53] := 6967; si[54] := 4799; si[55] := 2446; si[56] := 4520; si[57] := 6270; si[58] := 5906; si[59] := 5315; si[60] := 4520; si[61] := 3552; si[62] := 2446; si[63] := 1247; FOR ci:=0 TO cInfo.compsInScan - 1 DO compptr := cInfo.curCompInfo[ci]; qtblno := compptr.quantTblNo; IF (qtblno < 0) OR (qtblno >= NUMQUANTTBLS) OR (cInfo.quantTbl[qtblno] = NIL) THEN ErrMsg("IDCT-startInputPass: bad file", 34) END ; (* Get quantization Table that belongs to this component *) qtbl := cInfo.quantTbl[qtblno]; IF compptr.dctTable = NIL THEN NEW(compptr.dctTable); (* Dequantization of Values in Matrix *) FOR i:= 0 TO DCTSIZE2 -1 DO compptr.dctTable[i] := ASH(qtbl.quantVal[ZIG[i]] * si[i] + 2048,-12); END ; END ; END ;(* FOR *) END StartInputPassIDCT;  PROCEDURE StartOutputPassIDCT(cInfo: CInfoPtr); VAR ci: INTEGER; compptr: JPEGCompInfoPtr; BEGIN FOR ci:=0 TO cInfo.numComponents - 1 DO compptr := cInfo.compInfo[ci]; IF compptr.componentNeeded & (compptr.dctTable = NIL) THEN ErrMsg("IDCT-startOutputPass: component not found", 36) END ;(* IF *) END ; (* FOR *) END StartOutputPassIDCT;  (*PROCEDURE RangeLimit(x:INTEGER):INTEGER; BEGIN x := x MOD 400H; (* get first 10 Bit of x *) RETURN RL[x]; (* and get the Rangelimit out of table *) END RangeLimit;  *) PROCEDURE JpegIDCTIFast(compptr: JPEGCompInfoPtr; coefBlock: JBlock; outputBuf: JSampArray; outputRow, outputCol: LONGINT); VAR tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp10,tmp11,tmp12,tmp13: LONGINT; z5,z10,z11,z12,z13,dcval1: LONGINT; dcval: CHAR; inptr: JBlock; quantptr,wsptr: DCTTablePtr; inws,ctr: INTEGER; outptr: JSampRow; BEGIN inptr :=coefBlock; quantptr := compptr.dctTable; NEW(wsptr); FOR ctr:=0 TO DCTSIZE -1 DO IF (inptr[DCTSIZE * 1 + ctr] = 0) & (inptr[DCTSIZE * 2 + ctr] = 0) & (inptr[DCTSIZE * 3 + ctr] = 0) & (inptr[DCTSIZE * 4 + ctr] = 0) & (inptr[DCTSIZE * 5 + ctr] = 0) & (inptr[DCTSIZE * 6 + ctr] = 0) & (inptr[DCTSIZE * 7 + ctr] = 0) THEN dcval1 := LONG(inptr[ctr]) * quantptr[ctr]; wsptr[ctr] := dcval1; wsptr[DCTSIZE * 1 +ctr] := dcval1; wsptr[DCTSIZE * 2 +ctr] := dcval1; wsptr[DCTSIZE * 3 +ctr] := dcval1; wsptr[DCTSIZE * 4 +ctr] := dcval1; wsptr[DCTSIZE * 5 +ctr] := dcval1; wsptr[DCTSIZE * 6 +ctr] := dcval1; wsptr[DCTSIZE * 7 +ctr] := dcval1; ELSE tmp0 := LONG(inptr[ctr]) * quantptr[ctr]; tmp1 := LONG(inptr[DCTSIZE * 2 + ctr]) * quantptr[DCTSIZE * 2 + ctr]; tmp2 := LONG(inptr[DCTSIZE * 4 + ctr]) * quantptr[DCTSIZE * 4 + ctr]; tmp3 := LONG(inptr[DCTSIZE * 6 + ctr]) * quantptr[DCTSIZE * 6 + ctr]; tmp10 := tmp0 + tmp2; tmp11 := tmp0 - tmp2; tmp13 := tmp1 + tmp3; tmp12 := ASH((tmp1 - tmp3) * 362, -8) - tmp13; tmp0 := tmp10 + tmp13; tmp3 := tmp10 - tmp13; tmp1 := tmp11 + tmp12; tmp2 := tmp11 - tmp12; tmp4 := LONG(inptr[DCTSIZE * 1 + ctr]) * quantptr[DCTSIZE * 1 + ctr]; tmp5 := LONG(inptr[DCTSIZE * 3 + ctr]) * quantptr[DCTSIZE * 3 + ctr]; tmp6 := LONG(inptr[DCTSIZE * 5 + ctr]) * quantptr[DCTSIZE * 5 + ctr]; tmp7 := LONG(inptr[DCTSIZE * 7 + ctr]) * quantptr[DCTSIZE * 7 + ctr]; z13 := tmp6 + tmp5; z10 := tmp6 - tmp5; z11 := tmp4 + tmp7; z12 := tmp4 - tmp7; tmp7 := z11 + z13; tmp11 := ASH((z11 - z13) * 362, -8); z5 := ASH((z10 + z12) * 473, -8); tmp10 := ASH(277 * z12, -8) - z5; tmp12 := ASH(-669 * z10, -8) + z5; tmp6 := tmp12 - tmp7; tmp5 := tmp11 - tmp6; tmp4 := tmp10 + tmp5; wsptr[ctr] := tmp0 + tmp7; wsptr[DCTSIZE * 7 +ctr] := tmp0 - tmp7; wsptr[DCTSIZE * 1 +ctr] := tmp1 + tmp6; wsptr[DCTSIZE * 6 +ctr] := tmp1 - tmp6; wsptr[DCTSIZE * 2 +ctr] := tmp2 + tmp5; wsptr[DCTSIZE * 5 +ctr] := tmp2 - tmp5; wsptr[DCTSIZE * 4 +ctr] := tmp3 + tmp4; wsptr[DCTSIZE * 3 +ctr] := tmp3 - tmp4; END ; END ; inws := 0; FOR ctr := 0 TO DCTSIZE -1 DO outptr := outputBuf.row[ctr + outputRow]; IF (wsptr[1 + inws] = 0) & (wsptr[2 + inws] = 0) & (wsptr[3 + inws] = 0) & (wsptr[4 + inws] = 0) & (wsptr[5 + inws] = 0) & (wsptr[6 + inws] = 0) & (wsptr[7 + inws] = 0) THEN (*dcval := CHR(RangeLimit(SHORT(ASH(wsptr[inws] + 16, -5))));*) dcval := CHR(RL[(SHORT(ASH(wsptr[inws] + 16, -5))) MOD 400H]); outptr[0 + outputCol] := dcval; outptr[1 + outputCol] := dcval; outptr[2 + outputCol] := dcval; outptr[3 + outputCol] := dcval; outptr[4 + outputCol] := dcval; outptr[5 + outputCol] := dcval; outptr[6 + outputCol] := dcval; outptr[7 + outputCol] := dcval; ELSE tmp10 := wsptr[inws] + wsptr[4 + inws]; tmp11 := wsptr[inws] - wsptr[4 + inws]; tmp13 := wsptr[2 + inws] + wsptr[6 + inws]; tmp12 := ASH((wsptr[2 + inws] - wsptr[6 + inws]) * 362, -8) - tmp13; tmp0 := tmp10 + tmp13; tmp3 := tmp10 - tmp13; tmp1 := tmp11 + tmp12; tmp2 := tmp11 - tmp12; z13 := wsptr[5 + inws] + wsptr[3 + inws]; z10 := wsptr[5 + inws] - wsptr[3 + inws]; z11 := wsptr[1 + inws] + wsptr[7 + inws]; z12 := wsptr[1 + inws] - wsptr[7 + inws]; tmp7 := z11 + z13; tmp11 := ASH((z11 -z13) * 362, -8); z5 := ASH((z10 + z12) * 473, -8); tmp10 := ASH(277 * z12, -8) - z5; tmp12 := ASH(-669 * z10, -8) + z5; tmp6 := tmp12 - tmp7; tmp5 := tmp11 - tmp6; tmp4 := tmp10 + tmp5; outptr[0 + outputCol] :=CHR(RL[(SHORT(ASH(tmp0+ tmp7 + 16, -5))) MOD 400H]); outptr[7 + outputCol] :=CHR(RL[(SHORT(ASH(tmp0 - tmp7 + 16, -5))) MOD 400H]); outptr[1 + outputCol] :=CHR(RL[(SHORT(ASH(tmp1 + tmp6 + 16, -5))) MOD 400H]); outptr[6 + outputCol] :=CHR(RL[(SHORT(ASH(tmp1 - tmp6 + 16, -5))) MOD 400H]); outptr[2 + outputCol] :=CHR(RL[(SHORT(ASH(tmp2 + tmp5 + 16, -5))) MOD 400H]); outptr[5 + outputCol] :=CHR(RL[(SHORT(ASH(tmp2 - tmp5 + 16, -5))) MOD 400H]); outptr[4 + outputCol] :=CHR(RL[(SHORT(ASH(tmp3 + tmp4 + 16, -5))) MOD 400H]); outptr[3 + outputCol] :=CHR(RL[(SHORT(ASH(tmp3 - tmp4 + 16, -5))) MOD 400H]); END ; INC(inws,DCTSIZE); END ; END JpegIDCTIFast;  PROCEDURE JinitIDCT(cInfo: CInfoPtr); VAR (*compptr: JPEGCompInfoPtr;*) ci: INTEGER; BEGIN FOR ci := 0 TO cInfo.numComponents - 1 DO (*compptr := cInfo.compInfo[ci]; compptr.dctTable := NIL;*) cInfo.compInfo[ci].dctTable:=NIL END ; END JinitIDCT;  PROCEDURE DecompressData(cInfo: CInfoPtr; outputBuf: JSampImage):BOOLEAN; VAR MCUColNum, lastMCUCol, lastMCURow, startCol, outputCol, outputRow: LONGINT; blkn, ci, i, j, xindex, yindex, usefulWidth: INTEGER; compptr: JPEGCompInfoPtr; outputPtr: JSampArray; BEGIN  lastMCUCol := cInfo.MCUsPerRow - 1; lastMCURow := cInfo.MCURowsInScan - 1; FOR MCUColNum :=cInfo.coef.MCUColNum TO lastMCUCol DO FOR j:=0 TO MAXBLOCKSINMCU - 1 DO FOR i:=0 TO DCTSIZE2 - 1 DO (* initialize every Matrix of every column*) cInfo.coef.MCUBuffer[j][i]:=0; END ; END ; IF ~DecodeMCU(cInfo,cInfo.coef.MCUBuffer) THEN cInfo.coef.MCUColNum := MCUColNum;(* defined dummy value *) RETURN FALSE; END ; blkn := 0; FOR ci:= 0 TO cInfo.compsInScan - 1 DO compptr := cInfo.curCompInfo[ci]; IF ~compptr.componentNeeded THEN (* jump over all blocks with not needed components *) INC(blkn,compptr.MCUBlocks); ELSE IF MCUColNum < lastMCUCol THEN usefulWidth := compptr.MCUWidth;(*whole MCU can be displayed *) ELSE usefulWidth := compptr.lastColWidth;(*take the width of this component *) END ; outputPtr := outputBuf.comp[ci]; outputRow := 0; (*starting position of this MCU *) startCol := MCUColNum * compptr.MCUSampleWidth; (*every line of MCU *) FOR yindex := 0 TO compptr.MCUHeight - 1 DO (* end of line reached? -> go to next line *) IF (cInfo.coef.MCURowNum < lastMCURow) OR (yindex < compptr.lastRowHeight) THEN outputCol := startCol; FOR xindex:=0 TO usefulWidth - 1 DO JpegIDCTIFast(compptr,cInfo.coef.MCUBuffer[blkn + xindex], outputPtr,outputRow,outputCol); (*next output x-position *) (*outputCol:=outputCol + compptr.DCTScaledSize;*) outputCol:=outputCol + DCTSIZE; END ; END ; (* Mcu got bigger *) INC(blkn,compptr.MCUWidth); (* and got more rows now *) (*outputRow := outputRow + compptr.DCTScaledSize;*) outputRow := outputRow + DCTSIZE; END ; END ; END ; END ; cInfo.coef.MCUColNum := 0; INC(cInfo.coef.MCURowNum); RETURN TRUE; END DecompressData;  PROCEDURE JinitDCoefController(cInfo: CInfoPtr; needFullBuffer:BOOLEAN); VAR i: INTEGER; BEGIN  NEW(cInfo.coef); IF needFullBuffer THEN ErrMsg("Coef-jinitDCoefController: mode not implemented", 40) ELSE FOR i:=0 TO MAXBLOCKSINMCU -1 DO NEW(cInfo.coef.MCUBuffer[i]); END ; END ; END JinitDCoefController;  (*PROCEDURE RangeLimit2(x:INTEGER):INTEGER; BEGIN IF x<0 THEN RETURN 0 ELSIF x > MAXJSAMPLE THEN RETURN MAXJSAMPLE ELSE RETURN x END ; END RangeLimit2; *) PROCEDURE JcopySampleRows(inputArray: JSampArray; sourceRow:INTEGER; outputArray: JSampArray; destRow: INTEGER; numRows:INTEGER; numCols: LONGINT); VAR outptr,inptr: JSampRow; row,i,j: INTEGER; x: LONGINT; BEGIN  i:= sourceRow; j:= destRow; row := numRows; WHILE row >= 1 DO inptr := inputArray.row[i]; INC(i);(* next row *) outptr := outputArray.row[j]; INC(j); FOR x:= 0 TO numCols - 1 DO outptr[x] := inptr[x];(* copy values by pointermanipulation *) END ; DEC(row); END ; END JcopySampleRows;  PROCEDURE YccRGBConvert(cInfo: CInfoPtr; inputBuf:ARRAY OF JSampArray; inputRow: LONGINT; outputBuf: JSampArray; outRowCtr: LONGINT; numRows:INTEGER); VAR y,cb,cr,x,test: INTEGER; outptr,inptr0,inptr1,inptr2: JSampRow; col,numCols,out: LONGINT; BEGIN  out := 0; numCols := cInfo.imageWidth; DEC(numRows); WHILE numRows >= 0 DO inptr0 := inputBuf[0].row[inputRow];(* Y component s*) inptr1 := inputBuf[1].row[inputRow];(* CB components*) inptr2 := inputBuf[2].row[inputRow];(* CR components *) INC(inputRow);(* next row *) outptr := outputBuf.row[out]; INC(out); x := 0; FOR col:=0 TO numCols -1 DO y := ORD(inptr0[col]); cb := ORD(inptr1[col]); cr := ORD(inptr2[col]); (* Transformation by lookup-tables *) test := y + crRTab[cr]; IF test < 0 THEN outptr[RGBRED +x]:= CHR(0); ELSIF test >MAXJSAMPLE THEN outptr[RGBRED +x]:= CHR(MAXJSAMPLE); ELSE outptr[RGBRED +x]:= CHR(test) END ; test := y + cbBTab[cb]; IF test < 0 THEN outptr[RGBBLUE +x]:= CHR(0); ELSIF test >MAXJSAMPLE THEN outptr[RGBBLUE +x]:= CHR(MAXJSAMPLE); ELSE outptr[RGBBLUE +x]:= CHR(test) END ; test := y + SHORT(ASH(cbGTab[cb] + crGTab[cr],-16)); IF test < 0 THEN outptr[RGBGREEN +x]:= CHR(0); ELSIF test >MAXJSAMPLE THEN outptr[RGBGREEN +x]:= CHR(MAXJSAMPLE); ELSE outptr[RGBGREEN +x]:= CHR(test) END ; outptr[RGBDUMMY +x]:=CHR(0); (* standard dummy init *) INC(x, RGBPIXELSIZE);(* row looks like RGBDRGBDRGBDRGBD (bytestream *) END ; DEC(numRows); END ; END YccRGBConvert;  PROCEDURE NullConvert(cInfo: CInfoPtr; inputBuf:ARRAY OF JSampArray; inputRow: LONGINT; outputBuf: JSampArray; outRowCtr: LONGINT; numRows:INTEGER); VAR x: INTEGER; outptr,inptr: JSampRow; numCols,count,out: LONGINT; BEGIN  out := 0; numCols := cInfo.imageWidth; DEC(numRows); WHILE numRows >= 0 DO inptr := inputBuf[0].row[inputRow]; outptr := outputBuf.row[out]; x:=0; (* simple copy whole row by twisting the pointers *) FOR count:=0 TO numCols -1 DO outptr[x] := inptr[count]; INC(x); END ; INC(inputRow); INC(out); DEC(numRows); END ; END NullConvert;  PROCEDURE GrayscaleConvert(cInfo: CInfoPtr; inputBuf:ARRAY OF JSampArray; inputRow: LONGINT; outputBuf: JSampArray; outRowCtr: LONGINT; numRows:INTEGER); BEGIN  JcopySampleRows(inputBuf[0],SHORT(inputRow),outputBuf,0,numRows,cInfo.imageWidth); END GrayscaleConvert;  PROCEDURE JinitColorDeconverter(cInfo: CInfoPtr); VAR ci: INTEGER; BEGIN  NEW(cInfo.cconvert); (* All colorspaces i can handle *) IF (cInfo.jpegColorSpace # JCSRGB) & (cInfo.jpegColorSpace # JCSYCBCR) & (cInfo.jpegColorSpace # JCSGRAYSCALE) THEN ErrMsg("CConvert-jinitColorDeconverter: bad jpegColorSpace", 41) END ; (* select fitting color-conver routine *) IF cInfo.outColorSpace = JCSGRAYSCALE THEN IF (cInfo.jpegColorSpace = JCSYCBCR) OR (cInfo.jpegColorSpace = JCSGRAYSCALE) THEN cInfo.cconvert.colorConvert := GrayscaleConvert; (* Grayscale only needs one component *) FOR ci := 1 TO cInfo.numComponents - 1 DO cInfo.compInfo[ci].componentNeeded := FALSE; END ; ELSE ErrMsg("CConvert-jinitColorDeconverter: bad jpegColorSpace", 42) END ; ELSIF cInfo.outColorSpace = JCSRGB THEN IF cInfo.jpegColorSpace = JCSYCBCR THEN cInfo.cconvert.colorConvert := YccRGBConvert; ELSIF (cInfo.jpegColorSpace = JCSRGB) & (RGBPIXELSIZE = 3) THEN cInfo.cconvert.colorConvert := NullConvert; ELSE ErrMsg("CConvert-jinitColorDeconverter: bad jpegColorSpace", 43) END ; ELSE ErrMsg("CConvert-jinitColorDeconverter: bad jpegColorSpace", 44) END ; END JinitColorDeconverter;  PROCEDURE StartPassUpsample(cInfo: CInfoPtr); BEGIN  (* set width an heigth *) cInfo.upsample.nextRowOut := cInfo.maxVSampFactor; cInfo.upsample.rowsToGo := cInfo.imageHeight; END StartPassUpsample;  PROCEDURE ControlUpsample(cInfo: CInfoPtr; inputBuf: JSampImage; VAR inRowGroupCtr: LONGINT; outputBuf: JSampArray; VAR outRowCtr: LONGINT; outRowsAvail: LONGINT); VAR ci: INTEGER; compptr: JPEGCompInfoPtr; numRows,inRowCtr: LONGINT; BEGIN  IF cInfo.upsample.nextRowOut >= cInfo.maxVSampFactor THEN (* do the fitting upsample (fullsize, h2v1,..., routine for every component *) FOR ci := 0 TO cInfo.numComponents -1 DO compptr := cInfo.compInfo[ci]; inRowCtr := inRowGroupCtr * cInfo.upsample.rowGroupHeight[ci]; (* create the upsample buffer *) IF cInfo.upsample.colorBuf[ci] = NIL THEN NEW(cInfo.upsample.colorBuf[ci]) END ; cInfo.upsample.methods[ci](cInfo,compptr,inputBuf.comp[ci],inRowCtr, cInfo.upsample.colorBuf[ci]); END ; cInfo.upsample.nextRowOut := 0; END ; (* compute how many rows *) numRows := cInfo.maxVSampFactor - cInfo.upsample.nextRowOut; IF numRows > cInfo.upsample.rowsToGo THEN numRows := cInfo.upsample.rowsToGo END ; DEC(outRowsAvail,outRowCtr); IF numRows > outRowsAvail THEN numRows := outRowsAvail END ; (* colorconvert the upsampled components *) cInfo.cconvert.colorConvert(cInfo,cInfo.upsample.colorBuf,cInfo.upsample.nextRowOut, outputBuf,outRowCtr,SHORT(numRows)); INC(outRowCtr,numRows); DEC(cInfo.upsample.rowsToGo,numRows); cInfo.upsample.nextRowOut := SHORT(cInfo.upsample.nextRowOut + numRows); IF cInfo.upsample.nextRowOut >= cInfo.maxVSampFactor THEN INC(inRowGroupCtr) END ; END ControlUpsample;  PROCEDURE FullsizeUpsample(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); VAR x: INTEGER; BEGIN  x:=0; (* only data copy *) WHILE x < cInfo.maxVSampFactor DO outputData.row[x] := inputData.row[x + inRowCtr]; INC(x); END ; END FullsizeUpsample;  PROCEDURE NoopUpsample(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); VAR x: INTEGER; BEGIN  x:=0; (* forget this component *) WHILE x < cInfo.maxVSampFactor DO outputData.row[x] := NIL; INC(x); END ; END NoopUpsample;  PROCEDURE IntUpsample(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); VAR inptr,outptr : JSampRow; invalue: CHAR; h,outOffset,inOffset,outend,hExpand,vExpand,inrow,outrow : INTEGER; BEGIN  hExpand := cInfo.upsample.hExpand[compptr.componentIndex]; vExpand := cInfo.upsample.vExpand[compptr.componentIndex]; inrow := SHORT(inRowCtr); outrow := 0; WHILE outrow < (cInfo.maxVSampFactor) DO inptr := inputData.row[inrow]; outptr := outputData.row[outrow]; outend := SHORT(cInfo.imageWidth); outOffset := 0; inOffset := 0; WHILE outOffset < outend DO invalue := inptr[inOffset]; INC(inOffset); (* copy one point hExpand times horizontal*) FOR h := 0 TO hExpand -1 DO outptr[outOffset] := invalue; INC(outOffset); END ; END ; (* copy this row vExpand times (vertical)*) IF vExpand > 1 THEN JcopySampleRows(outputData,outrow,outputData,outrow + 1,vExpand - 1,cInfo.imageWidth); END ; INC(inrow); INC(outrow,vExpand); END ; END IntUpsample;  PROCEDURE H2v1Upsample(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); VAR inptr,outptr : JSampRow; invalue: CHAR; h,outOffset,inOffset,outend,inrow : INTEGER; BEGIN  inrow := SHORT(inRowCtr); FOR h := 0 TO cInfo.maxVSampFactor - 1 DO inptr := inputData.row[inrow]; outptr := outputData.row[h]; outend := SHORT(cInfo.imageWidth); outOffset := 0; inOffset := 0; WHILE outOffset < outend DO invalue := inptr[inOffset]; INC(inOffset); outptr[outOffset] := invalue; (*set point one time *) INC(outOffset); outptr[outOffset] := invalue; (*and a second time *) INC(outOffset); END ; INC(inrow); END ; END H2v1Upsample;  PROCEDURE H2v2Upsample(cInfo: CInfoPtr; compptr: JPEGCompInfoPtr; inputData: JSampArray; inRowCtr: LONGINT; outputData: JSampArray); VAR inptr,outptr : JSampRow; invalue: CHAR; outOffset,inOffset,outend,inrow,outrow : INTEGER; BEGIN  inrow := SHORT(inRowCtr); outrow := 0; WHILE outrow < (cInfo.maxVSampFactor) DO inptr := inputData.row[inrow]; outptr := outputData.row[outrow]; outend := SHORT(cInfo.imageWidth); outOffset := 0; inOffset := 0; WHILE outOffset < outend DO invalue := inptr[inOffset]; INC(inOffset); outptr[outOffset] := invalue;(*set point *) INC(outOffset); outptr[outOffset] := invalue; (*and again *) INC(outOffset); END ; JcopySampleRows(outputData,outrow,outputData,outrow + 1,1,cInfo.imageWidth); (* copy one line *) INC(inrow); INC(outrow,2); END ; END H2v2Upsample;  PROCEDURE JinitUpsampler(cInfo: CInfoPtr); VAR i,ci,hInGroup,vInGroup,hOutGroup,vOutGroup: INTEGER; needBuffer,doFancy: BOOLEAN; compptr: JPEGCompInfoPtr; BEGIN  NEW(cInfo.upsample); FOR ci:=0 TO cInfo.numComponents -1 DO compptr := cInfo.compInfo[ci]; (* width = sampilinfactor*Size of ScaledDCT*) (* groups= width/Size of one normal DCT *) (*hInGroup := (LONG(compptr.hSampFactor) * compptr.DCTScaledSize ) DIV DCTSIZE; vInGroup := (LONG(compptr.vSampFactor) * compptr.DCTScaledSize) DIV DCTSIZE;*) hInGroup := LONG(compptr.hSampFactor); vInGroup := LONG(compptr.vSampFactor); hOutGroup := cInfo.maxHSampFactor; vOutGroup := cInfo.maxVSampFactor; cInfo.upsample.rowGroupHeight[ci] := vInGroup; needBuffer := TRUE; IF ~compptr.componentNeeded THEN cInfo.upsample.methods[ci] := NoopUpsample;(* component set to NIL so no buffer needed*) needBuffer := FALSE; ELSIF (hInGroup = hOutGroup) & (vInGroup = vOutGroup) THEN cInfo.upsample.methods[ci] := FullsizeUpsample; needBuffer := FALSE;(* components get copied, no buffer neccesary too *) ELSIF ((hInGroup * 2) = hOutGroup) & (vInGroup = vOutGroup) THEN cInfo.upsample.methods[ci] := H2v1Upsample;(* in order not to destroy the inputbuffer*) ELSIF ((hInGroup * 2) = hOutGroup) & ((vInGroup * 2) = vOutGroup) THEN (*i hae to use a new*) cInfo.upsample.methods[ci] := H2v2Upsample;(* buffer here *) ELSIF ((hOutGroup MOD hInGroup) = 0) & ((vOutGroup MOD vInGroup) = 0) THEN (* seldom sample rate *) cInfo.upsample.methods[ci] := IntUpsample; cInfo.upsample.hExpand[ci] := hOutGroup DIV hInGroup; (* memorize x,y expandationfactor *) cInfo.upsample.vExpand[ci] := vOutGroup DIV vInGroup; ELSE ErrMsg("Upsample-jinitUpsampler: Upsampling not possible", 46) END ; IF needBuffer THEN NEW(cInfo.upsample.colorBuf[ci]); FOR i:= 0 TO cInfo.maxVSampFactor DO NEW(cInfo.upsample.colorBuf[ci].row[i]); END ; END ; END ; END JinitUpsampler;  PROCEDURE PostProcess1Pass(cInfo: CInfoPtr; inputBuf: JSampImage; VAR inRowGroupCtr:LONGINT; VAR outRowCtr: LONGINT;VAR outRowsAvail: LONGINT); VAR numRows,maxRows : LONGINT; BEGIN  maxRows := outRowsAvail - outRowCtr; (* cant handle more lines than size of buffer *) IF maxRows > cInfo.post.stripHeight THEN maxRows := cInfo.post.stripHeight END ; numRows := 0; ControlUpsample(cInfo, inputBuf, inRowGroupCtr, cInfo.post.buffer, numRows, maxRows); (* numrows lines processed *) INC(outRowCtr,numRows); (*insert beautifing routines afterwards *) END PostProcess1Pass;  PROCEDURE JinitDPostController(cInfo: CInfoPtr); VAR i: INTEGER; BEGIN  NEW(cInfo.post); cInfo.post.stripHeight := cInfo.maxVSampFactor; NEW(cInfo.post.buffer); FOR i:=0 TO cInfo.maxVSampFactor -1 DO NEW(cInfo.post.buffer.row[i]); END ; END JinitDPostController;  PROCEDURE ProcessDataSimpleMain(cInfo: CInfoPtr; VAR outRowCtr:LONGINT; outRowsAvail:LONGINT); BEGIN  IF ~cInfo.main.bufferFull THEN (* a new iMCU can be decoded *) IF~DecompressData(cInfo,cInfo.main.buffer) THEN RETURN END ; cInfo.main.bufferFull := TRUE; END ; (* Process the decoded MCU *) PostProcess1Pass(cInfo,cInfo.main.buffer,cInfo.main.rowGroupCtr ,outRowCtr,outRowsAvail); IF cInfo.main.rowGroupCtr >= DCTSIZE THEN cInfo.main.bufferFull := FALSE; cInfo.main.rowGroupCtr :=0; END ; END ProcessDataSimpleMain;  PROCEDURE JinitDMainController(cInfo: CInfoPtr; needFullBuffer:BOOLEAN); VAR ci,rgroup,ngroups : INTEGER; compptr : JPEGCompInfoPtr; t, i : LONGINT; BEGIN  NEW(cInfo.main); IF needFullBuffer THEN ErrMsg("Main-jinitDMainController: buffer mode not implemented", 53) END ; ngroups := DCTSIZE; NEW(cInfo.main.buffer); FOR ci := 0 TO cInfo.numComponents - 1 DO compptr := cInfo.compInfo[ci]; (* compute multiplikator of size *) (*t := (LONG(LONG(compptr.vSampFactor)) * LONG(compptr.DCTScaledSize)) DIV LONG(DCTSIZE);*) t := (LONG(LONG(compptr.vSampFactor)) * LONG(DCTSIZE)) DIV LONG(DCTSIZE); rgroup := SHORT(t); NEW(cInfo.main.buffer.comp[ci]); (* i need a minimum of 8 lines * samplingfactor *) FOR i:=0 TO LONG(rgroup) * LONG(ngroups) -1 DO NEW(cInfo.main.buffer.comp[ci].row[i]); END END ; END JinitDMainController;  PROCEDURE RoundUp(a,b: LONGINT):LONGINT; BEGIN RETURN ENTIER((a + b -1) / b); END RoundUp;  PROCEDURE JpegCalcOutputDim(cInfo: CInfoPtr); VAR ci,ssize: INTEGER; compptr: JPEGCompInfoPtr; BEGIN  (* due to JFIF 0th component of Grayscale must not be upsampled *) IF cInfo.numComponents = 1 THEN cInfo.compInfo[0].hSampFactor := 1; cInfo.compInfo[0].vSampFactor := 1; END ; cInfo.maxHSampFactor := 1; cInfo.maxVSampFactor := 1; FOR ci:=0 TO cInfo.numComponents -1 DO compptr:= cInfo.compInfo[ci]; (* check range of sampling *) IF (compptr.hSampFactor <= 0) OR (compptr.hSampFactor > MAXSAMPFACTOR) OR (compptr.vSampFactor <= 0) OR (compptr.vSampFactor > MAXSAMPFACTOR) THEN ErrMsg("Master-CalcOutputDimensions: bad factor", 55) END ; (* correct MaxSampling to Maximum of Components*) IF cInfo.maxHSampFactor < compptr.hSampFactor THEN cInfo.maxHSampFactor :=compptr.hSampFactor END ; IF cInfo.maxVSampFactor < compptr.vSampFactor THEN cInfo.maxVSampFactor :=compptr.vSampFactor END ; END ; (*FOR ci:=0 TO cInfo.numComponents -1 DO compptr:= cInfo.compInfo[ci]; ssize := DCTSIZE; compptr.DCTScaledSize := ssize; Out.F('DCTScaled-Size # $',compptr.DCTScaledSize); END ;*) FOR ci:=0 TO cInfo.numComponents -1 DO compptr:= cInfo.compInfo[ci]; compptr.widthInBlocks := RoundUp(cInfo.imageWidth * LONG(compptr.hSampFactor), cInfo.maxHSampFactor * DCTSIZE); compptr.heightInBlocks := RoundUp(cInfo.imageHeight * LONG(compptr.vSampFactor), cInfo.maxVSampFactor * DCTSIZE); (*compptr.downSampledWidth := RoundUp(cInfo.imageWidth * LONG(compptr.hSampFactor) * compptr.DCTScaledSize, cInfo.maxHSampFactor * DCTSIZE);*) compptr.downSampledWidth := RoundUp(cInfo.imageWidth * LONG(compptr.hSampFactor) * DCTSIZE, cInfo.maxHSampFactor * DCTSIZE); compptr.componentNeeded := TRUE; END ; END JpegCalcOutputDim;  PROCEDURE ForScanSetup(cInfo:CInfoPtr); VAR ci,mcublks,tmp: INTEGER; compptr: JPEGCompInfoPtr; BEGIN (* initial settings *)  IF cInfo.compsInScan = 1 THEN compptr := cInfo.curCompInfo[0]; cInfo.MCUsPerRow := compptr.widthInBlocks; cInfo.MCURowsInScan := compptr.heightInBlocks; compptr.MCUWidth := 1; compptr.MCUHeight := 1; compptr.MCUBlocks := 1; (*compptr.MCUSampleWidth := compptr.DCTScaledSize;*) compptr.MCUSampleWidth := DCTSIZE; compptr.lastColWidth := 1; compptr.lastRowHeight := 1; cInfo.blocksInMCU := 1; cInfo.MCUMembership[0] := 0; ELSE (*check components in 1 scan *) IF (cInfo.compsInScan <= 0) OR (cInfo.compsInScan > MAXCOMPSINSCAN) THEN ErrMsg("Master-perScanSetup: bad number", 56) END ; cInfo.MCUsPerRow := RoundUp(cInfo.imageWidth, LONG(cInfo.maxHSampFactor) * DCTSIZE); cInfo.MCURowsInScan := RoundUp(cInfo.imageHeight, LONG(cInfo.maxVSampFactor) * DCTSIZE); cInfo.blocksInMCU := 0; FOR ci := 0 TO cInfo.compsInScan - 1 DO (*setup MCU settings per component *) compptr := cInfo.curCompInfo[ci]; compptr.MCUWidth := compptr.hSampFactor; compptr.MCUHeight := compptr.vSampFactor; compptr.MCUBlocks := SHORT(LONG(compptr.MCUWidth) * LONG(compptr.MCUHeight)); (*compptr.MCUSampleWidth := SHORT(LONG(compptr.MCUWidth) * LONG(compptr.DCTScaledSize));*) compptr.MCUSampleWidth := SHORT(LONG(compptr.MCUWidth) * LONG(DCTSIZE)); tmp :=SHORT(compptr.widthInBlocks MOD compptr.MCUWidth); (* from 0..MCUWidth-1 to 1..MCUWidth*) IF tmp = 0 THEN tmp := compptr.MCUWidth END ; compptr.lastColWidth := tmp; tmp :=SHORT(compptr.heightInBlocks MOD compptr.MCUHeight); IF tmp = 0 THEN tmp := compptr.MCUHeight END ; compptr.lastRowHeight := tmp; mcublks := compptr.MCUBlocks; IF (cInfo.blocksInMCU + mcublks) > MAXBLOCKSINMCU THEN ErrMsg("Master-perScanSetup: bad MCU size", 57) END ; WHILE (mcublks) > 0 DO DEC(mcublks); cInfo.MCUMembership[cInfo.blocksInMCU] := ci; INC(cInfo.blocksInMCU); END ; END ; END ; END ForScanSetup;  PROCEDURE FinishPass(cInfo: CInfoPtr); BEGIN (* check for right pass*)  CASE cInfo.master.passType OF MainPass: INC(cInfo.master.passNumber); cInfo.master.passType := PostPass; | OutputPass: INC(cInfo.master.passNumber); cInfo.master.passType := PostPass; ELSE ErrMsg("Master-finishPass: bad pass mode", 62) END ; END FinishPass;  PROCEDURE JinitMasterDecompress(cInfo: CInfoPtr); BEGIN (* init all i can *)  NEW(cInfo.master); cInfo.master.passNumber := 0; IF cInfo.compsInScan = cInfo.numComponents THEN cInfo.master.passType := MainPass; ELSE ErrMsg("Master-masterDecompress: Mulitscan Files not iplemented", 58) END ; JinitColorDeconverter(cInfo); JinitUpsampler(cInfo); JinitDPostController(cInfo); JinitIDCT(cInfo); IF cInfo.arithCode THEN ErrMsg("Master-masterDecompress: Arith. decoding not implemented", 60) ELSE JinitHuffDecoder(cInfo); END ; JinitDCoefController(cInfo,(cInfo.master.passType = PrereadPass)); JinitDMainController(cInfo,FALSE); END JinitMasterDecompress;  (* PROCEDURE PutPixelRows(cInfo: CInfoPtr; dest: DestPtr; numScanLines:LONGINT); VAR col,i,zeile: LONGINT; last: LONGINT; color1,color2,color3: INTEGER; last1,last2,last3: INTEGER; BEGIN  i:=0; WHILE i < numScanLines DO zeile := actual.picture.height - dest.curOutputRow -1; last := 0; IF cInfo.outColorSpace = JCSGRAYSCALE THEN (* only one component here *) last1 := ORD(cInfo.post.buffer.row[i][0]); FOR col := 1 TO cInfo.imageWidth - 1 DO color1 := ORD(cInfo.post.buffer.row[i][col]); IF last1 # color1 THEN actual.picture.SetColorRGB(last1,last1,last1); actual.picture.ReplConst(SHORT(last),SHORT(zeile),SHORT(col-last),1,Display.replace); last := col; last1 := color1 END END ; actual.picture.SetColorRGB(last1,last1,last1); actual.picture.ReplConst(SHORT(last),SHORT(zeile),SHORT(cInfo.imageWidth-last),1,Display.replace) ELSE (*all 3 components *) last1 := ORD(cInfo.post.buffer.row[i][0]); last2 := ORD(cInfo.post.buffer.row[i][1]); last3 := ORD(cInfo.post.buffer.row[i][2]); FOR col := 1 TO cInfo.imageWidth - 1 DO color1 := ORD(cInfo.post.buffer.row[i][col*3]); color2 := ORD(cInfo.post.buffer.row[i][col*3+1]); color3 := ORD(cInfo.post.buffer.row[i][col*3+2]); IF (last1 # color1) OR (last2 # color2) OR (last3 # color3) THEN actual.picture.SetColorRGB(last1,last2,last3); actual.picture.ReplConst(SHORT(last),SHORT(zeile),SHORT(col-last),1,Display.replace); last := col; last1 := color1; last2 := color2; last3 := color3; END ; END ; actual.picture.SetColorRGB(last1,last2,last3); actual.picture.ReplConst(SHORT(last),SHORT(zeile),SHORT(cInfo.imageWidth-last),1,Display.replace) END ; INC(i); INC(dest.curOutputRow); END ; END PutPixelRows;  *) PROCEDURE PutPixelRows(cInfo: CInfoPtr; dest: DestPtr; numScanLines:LONGINT); VAR col,i,zeile: LONGINT; dots: POINTER TO ARRAY OF CHAR; x : JSampRow; ch:CHAR; BEGIN  NEW(dots, cInfo.imageWidth * 4); i:=0; WHILE i < numScanLines DO zeile := actual.picture.height - dest.curOutputRow -1; x := cInfo.post.buffer.row[i]; IF cInfo.outColorSpace = JCSGRAYSCALE THEN (* only one component here *) FOR col := 0 TO cInfo.imageWidth - 1 DO ch:=x[col]; dots[col*4] := ch; dots[col*4+1] := ch; dots[col*4+2] := ch END ; actual.picture.SetScanLine(dots^, SHORT(zeile), 1) ELSE actual.picture.SetScanLine(cInfo.post.buffer.row[i]^, SHORT(zeile), 1) END ; INC(i); INC(dest.curOutputRow); END END PutPixelRows;  PROCEDURE JinitDest(cInfo: CInfoPtr; dest: DestPtr); BEGIN (* init picture and final buffer *)  JpegCalcOutputDim(cInfo); actual.picture.Init(SHORT(cInfo.imageWidth),SHORT(cInfo.imageHeight),24); dest.bufferHeight := 1; dest.curOutputRow := 0; NEW(dest.buffer); NEW(dest.buffer.row[0]); END JinitDest;  PROCEDURE JpegCreateDecompress(cInfo: CInfoPtr); VAR i:INTEGER; BEGIN  cInfo.src := NIL; FOR i:=0 TO NUMQUANTTBLS -1 DO cInfo.quantTbl[i] := NIL; END ; (* be sure that no wrong data will confuse the proggy *) FOR i:=0 TO NUMHUFFTBLS -1 DO cInfo.dcHuffTbl[i]:=NIL; cInfo.acHuffTbl[i]:=NIL; END ; cInfo.marker:=NIL; JinitMarkerReader(cInfo); cInfo.globalState:= DSTATESTART; END JpegCreateDecompress;  PROCEDURE DefaultDecompressParams(cInfo: CInfoPtr); VAR cid0,cid1,cid2:INTEGER; BEGIN (* Handle colorspaces *)  CASE cInfo.numComponents OF 1: cInfo.jpegColorSpace:= JCSGRAYSCALE; cInfo.outColorSpace := JCSGRAYSCALE; | 3: IF cInfo.sawJFIFMarker THEN cInfo.jpegColorSpace:= JCSYCBCR; ELSIF cInfo.sawAdobeMarker THEN (* Handle special colorspace of Adobe *) CASE cInfo.AdobeTransform OF 0: cInfo.jpegColorSpace:= JCSRGB; | 1: cInfo.jpegColorSpace:= JCSYCBCR; ELSE cInfo.jpegColorSpace:= JCSYCBCR; END ; ELSE (* try to find out what components are used *) cid0:=cInfo.compInfo[0].componentID; cid1:=cInfo.compInfo[1].componentID; cid2:=cInfo.compInfo[2].componentID; IF (cid0=1) & (cid1=2) & (cid2=3) THEN cInfo.jpegColorSpace:= JCSYCBCR; ELSIF (cid0=82) & (cid1=71) & (cid2=66) THEN cInfo.jpegColorSpace:= JCSRGB; ELSE cInfo.jpegColorSpace:= JCSYCBCR; END ; END ; cInfo.outColorSpace := JCSRGB; | 4: ErrMsg("JPEG: 4 not implemented", 63) ELSE ErrMsg("JPEG: ? not implemented", 64) END ; END DefaultDecompressParams;  PROCEDURE JpegReadHeader(cInfo: CInfoPtr); VAR retcode:INTEGER; BEGIN (* set new state *) IF cInfo.globalState = DSTATESTART THEN cInfo.globalState := DSTATEINHEADER; ELSIF cInfo.globalState # DSTATEINHEADER THEN ErrMsg("bad header state", 65) END ; (* try to read markers *) retcode := ReadMarkers(cInfo); CASE retcode OF (* found at least SOS *) JPEGHEADEROK: DefaultDecompressParams(cInfo); cInfo.globalState:= DSTATEINITDEST; | JPEGHEADERTABLESONLY: ErrMsg("Keine SOS-Bloecke vorhanden --> Kein Bild vorhanden ", 71); | JPEGSUSPENDED:(* maybe red some markers, but not reached end of header *) cInfo.unreadMarker:=0X;(* fileposition sollte vor 1.markerbyte sein *) END ; END JpegReadHeader;  PROCEDURE JpegStartDecompress(cInfo: CInfoPtr); VAR chunkCtr,lastChunkCtr: LONGINT; BEGIN  cInfo.globalState := DSTATEREADY; JinitMasterDecompress(cInfo); CASE cInfo.master.passType OF MainPass: ForScanSetup(cInfo); cInfo.master.isLastPass := TRUE; StartPassUpsample(cInfo); StartInputPassIDCT(cInfo); StartOutputPassIDCT(cInfo); StartPassHuff(cInfo); cInfo.coef.MCUColNum := 0; cInfo.coef.MCURowNum := 0; cInfo.main.numChunks := cInfo.imageHeight; ELSE ErrMsg("Master-prepareForPass: bad pass mode", 61) END ; cInfo.outputScanline := 0; cInfo.globalState := DSTATESCANNING; END JpegStartDecompress;  PROCEDURE JpegReadScanlines(cInfo: CInfoPtr; VAR maxLines:LONGINT):LONGINT; VAR rowCtr: LONGINT; BEGIN  IF cInfo.globalState # DSTATESCANNING THEN ErrMsg("ReadScanliness: Falscher globaler Zustand", 73); END ; rowCtr:=0; ProcessDataSimpleMain(cInfo,rowCtr,maxLines); INC(cInfo.outputScanline,rowCtr); RETURN rowCtr; END JpegReadScanlines;  PROCEDURE JpegFinishDecompress(VAR cInfo: CInfoPtr); BEGIN cInfo:=NIL; actual.dest:=NIL; END JpegFinishDecompress;  PROCEDURE Loader* (f: F.File; pos: LONGINT) : Pictures.LoadInfo; VAR ldr : LoadInfo; i, j : INTEGER; BEGIN IF CheckJpeg (f, pos) THEN (* old version: NEW(ldr);NEW(ldr.picture); *) (* changed version (ak): *) NEW(ldr);ldr.picture := NIL; (**) ldr.res:=Pictures.needData; NEW(ldr.cInfo); NEW(ldr.dest); JpegCreateDecompress(ldr.cInfo); JpegInitSrc(ldr.cInfo,f,pos); END ; FOR i := 0 TO 7 DO FOR j := 0 TO 1 DO count[i, j] := 0 END END ; RETURN ldr END Loader;  PROCEDURE (ldr:LoadInfo) Do*; VAR searchRes:INTEGER; temp:LONGINT; BEGIN INC(count[0, 0]); DEC(count[0, 1], Input.Time()); (* enter only if you have to *) IF ldr.res # Pictures.needData THEN RETURN;END ; actual:=ldr; (* set global state for reentrace of readmarkers *) IF ldr.cInfo.globalState=DSTATEINHEADER THEN ldr.cInfo.globalState:=DSTATESTART;END ; IF ldr.res = Pictures.needData THEN (* set rider behind last processed Pos *) F.Set(ldr.cInfo.src.rider,F.Base(ldr.cInfo.src.rider),ldr.cInfo.src.riderStart); (* read header as long as possible *) WHILE (ldr.cInfo.globalState = DSTATESTART) DO INC(count[1, 0]); DEC(count[1, 1], Input.Time()); JpegReadHeader(ldr.cInfo); INC(count[1, 1], Input.Time()); END ; IF ldr.res=Pictures.error THEN RETURN END ; (* init all *) IF ldr.cInfo.globalState = DSTATEINITDEST THEN INC(count[2, 0]); DEC(count[2, 1], Input.Time()); JinitDest(ldr.cInfo,ldr.dest); INC(count[2, 1], Input.Time()); INC(count[3, 0]); DEC(count[3, 1], Input.Time()); JpegStartDecompress(ldr.cInfo) ;INC(count[3, 1], Input.Time()); END ; (* enter only if headers are red (state) *) IF (ldr.cInfo.globalState= DSTATESCANNING) & (ldr.res=Pictures.needData) THEN INC(count[4, 0]); DEC(count[4, 1], Input.Time()); REPEAT (*!!!!NEW solange bis daten gebraucht werden oder bild fertig oder bildfehler*) searchRes:=FoundRestartMarker(ldr.cInfo); INC(count[4, 1], Input.Time()); (* i can read some lines now *) IF (searchRes # FOUNDNOTHING) THEN (* Out.F("Entering at pos # $",F.Pos(ldr.cInfo.src.rider));*) (* decode upsample and draw one whole buffer *) temp:=ldr.cInfo.outputScanline;  REPEAT INC(count[5, 0]); DEC(count[5, 1], Input.Time()); ldr.numScanlines := JpegReadScanlines(ldr.cInfo,ldr.dest.bufferHeight); INC(count[5, 1], Input.Time()); ldr.zaehler := ldr.zaehler + ldr.numScanlines; INC(count[6, 0]); DEC(count[6, 1], Input.Time()); PutPixelRows(ldr.cInfo,ldr.dest,ldr.numScanlines); INC(count[6, 1], Input.Time()); INC(count[7, 0]); DEC(count[7, 1], Input.Time()); UpdFileBytes(ldr.cInfo) ;INC(count[7, 1], Input.Time()); UNTIL ~ldr.cInfo.main.bufferFull OR (ldr.cInfo.outputScanline >= ldr.cInfo.imageHeight) ; ldr.picture.Update(NIL,0,SHORT(ldr.cInfo.imageHeight-ldr.cInfo.outputScanline), SHORT(ldr.cInfo.imageWidth), SHORT(ldr.cInfo.outputScanline - temp));  (* now im ready *)  IF (searchRes = FOUNDEOI) & (ldr.cInfo.outputScanline >= ldr.cInfo.imageHeight) THEN  ldr.res:=Pictures.done END END ; IF ldr.res= Pictures.done THEN (*free some mem *) JpegFinishDecompress(ldr.cInfo); END (* IF ldr.res= *) UNTIL (searchRes = FOUNDNOTHING) OR ( ldr.res = Pictures.done) OR ( ldr.res = Pictures.error); END END ; INC(count[0, 1], Input.Time()); END Do;  PROCEDURE Install*; BEGIN END Install;  PROCEDURE SetRisc; VAR long : LONGINT; int : INTEGER;se:SET; BEGIN long := 1; S.GET(S.ADR(long), int); risc := int = 0; se:={0};long:=S.VAL(LONGINT,se); rbo:=~(long=1);  IF rbo THEN Out.String('rbo ') END ; IF risc THEN Out.String('risc') END ; (* on pc: rbo,risc false *) END SetRisc;  BEGIN SetRisc; Pictures.RegisterFormat(Loader); traceP:=FALSE; ZAG[0] := 0; ZAG[1] := 1; ZAG[2] := 8; ZAG[3] := 16; ZAG[4] := 9; ZAG[5] := 2; ZAG[6] := 3; ZAG[7] := 10; ZAG[8] := 17; ZAG[9] := 24; ZAG[10] := 32; ZAG[11] := 25; ZAG[12] := 18; ZAG[13] := 11; ZAG[14] := 4; ZAG[15] := 5; ZAG[16] := 12; ZAG[17] := 19; ZAG[18] := 26; ZAG[19] := 33; ZAG[20] := 40; ZAG[21] := 48; ZAG[22] := 41; ZAG[23] := 34; ZAG[24] := 27; ZAG[25] := 20; ZAG[26] := 13; ZAG[27] := 6; ZAG[28] := 7; ZAG[29] := 14; ZAG[30] := 21; ZAG[31] := 28; ZAG[32] := 35; ZAG[33] := 42; ZAG[34] := 49; ZAG[35] := 56; ZAG[36] := 57; ZAG[37] := 50; ZAG[38] := 43; ZAG[39] := 36; ZAG[40] := 29; ZAG[41] := 22; ZAG[42] := 15; ZAG[43] := 23; ZAG[44] := 30; ZAG[45] := 37; ZAG[46] := 44; ZAG[47] := 51; ZAG[48] := 58; ZAG[49] := 59; ZAG[50] := 52; ZAG[51] := 45; ZAG[52] := 38; ZAG[53] := 31; ZAG[54] := 39; ZAG[55] := 46; ZAG[56] := 53; ZAG[57] := 60; ZAG[58] := 61; ZAG[59] := 54; ZAG[60] := 47; ZAG[61] := 55; ZAG[62] := 62; ZAG[63] := 63; ZAG[64] := 0; ZAG[65] := 0; ZAG[66] := 0; ZAG[67] := 0; ZAG[68] := 0; ZAG[69] := 0; ZAG[70] := 0; ZAG[71] := 0; ZAG[72] := 0; ZAG[73] := 0; ZAG[74] := 0; ZAG[75] := 0; ZAG[76] := 0; ZAG[77] := 0; ZAG[78] := 0; ZAG[79] := 0; ZIG[0] := 0; ZIG[1] := 1; ZIG[2] := 5; ZIG[3] := 6; ZIG[4] := 14; ZIG[5] := 15; ZIG[6] := 27; ZIG[7] := 28; ZIG[8] := 2; ZIG[9] := 4; ZIG[10] := 7; ZIG[11] := 13; ZIG[12] := 16; ZIG[13] := 26; ZIG[14] := 29; ZIG[15] := 42; ZIG[16] := 3; ZIG[17] := 8; ZIG[18] := 12; ZIG[19] := 17; ZIG[20] := 25; ZIG[21] := 30; ZIG[22] := 41; ZIG[23] := 43; ZIG[24] := 9; ZIG[25] := 11; ZIG[26] := 18; ZIG[27] := 24; ZIG[28] := 31; ZIG[29] := 40; ZIG[30] := 44; ZIG[31] := 53; ZIG[32] := 10; ZIG[33] := 19; ZIG[34] := 23; ZIG[35] := 32; ZIG[36] := 39; ZIG[37] := 45; ZIG[38] := 52; ZIG[39] := 54; ZIG[40] := 20; ZIG[41] := 22; ZIG[42] := 33; ZIG[43] := 38; ZIG[44] := 46; ZIG[45] := 51; ZIG[46] := 55; ZIG[47] := 60; ZIG[48] := 21; ZIG[49] := 34; ZIG[50] := 37; ZIG[51] := 47; ZIG[52] := 50; ZIG[53] := 56; ZIG[54] := 59; ZIG[55] := 61; ZIG[56] := 35; ZIG[57] := 36; ZIG[58] := 48; ZIG[59] := 49; ZIG[60] := 57; ZIG[61] := 58; ZIG[62] := 62; ZIG[63] := 63; FOR i:= 0 TO CENTERJSAMPLE - 1 DO RL[i] := i + CENTERJSAMPLE END ; FOR i:= CENTERJSAMPLE TO 511 DO RL[i] := MAXJSAMPLE END ; FOR i:= 512 TO 895 DO RL[i] := 0 END ; FOR i:= 896 TO 1023 DO RL[i] := i - 896 END ; fix14 := ENTIER(1.40200 * 65536 +0.5); fix17 := ENTIER(1.77200 * 65536 +0.5); fix07 := ENTIER(0.71414 * 65536 +0.5); fix03 := ENTIER(0.34414 * 65536 +0.5); x := - CENTERJSAMPLE; FOR i := 0 TO MAXJSAMPLE DO crRTab[i] := SHORT(ASH(fix14 * x + 32768,-16)); cbBTab[i] := SHORT(ASH(fix17 * x + 32768,-16)); crGTab[i] := -fix07 * x; cbGTab[i] := -fix03 * x + 32768; INC(x); END ; extendTest[0] := 0; extendTest[1] := 1; extendTest[2] := 2; extendTest[3] := 4; extendTest[4] := 8; extendTest[5] := 16; extendTest[6] := 32; extendTest[7] := 64; extendTest[8] := 128; extendTest[9] := 256; extendTest[10] := 512; extendTest[11] := 1024; extendTest[12] := 2048; extendTest[13] := 4096; extendTest[14] := 8192; extendTest[15] := 16384; i:= -1; extendOff[0] := 0; extendOff[1] := ILSH(i,1) + 1; extendOff[2] := ILSH(i,2) + 1; extendOff[3] := ILSH(i,3) + 1; extendOff[4] := ILSH(i,4) + 1; extendOff[5] := ILSH(i,5) + 1; extendOff[6] := ILSH(i,6) + 1; extendOff[7] := ILSH(i,7) + 1; extendOff[8] := ILSH(i,8) + 1; extendOff[9] := ILSH(i,9) + 1; extendOff[10] := ILSH(i,10) + 1; extendOff[11] := ILSH(i,11) + 1; extendOff[12] := ILSH(i,12) + 1; extendOff[13] := ILSH(i,13) + 1; extendOff[14] := ILSH(i,14) + 1; extendOff[15] := ILSH(i,15) + 1;  END Jpeg.