diff -crB jpegdir/huffman.c jpegdir_patched/huffman.c *** jpegdir/huffman.c 1995-03-01 20:57:22.000000000 -0500 --- jpegdir_patched/huffman.c 2012-02-10 11:27:03.651217000 -0500 *************** *** 57,62 **** --- 57,63 ---- extern void MakeDhuff(); extern void UseACHuffman(); extern void UseDCHuffman(); + extern void UseDCHuffmanCheckingGEMSBug(); extern void SetACHuffman(); extern void SetDCHuffman(); extern void PrintHuffman(); *************** *** 678,683 **** --- 679,720 ---- int index; { BEGIN("UseDCHuffman"); + index = 0; + Xhuff = CImage->DCXhuff[index]; + Dhuff = CImage->DCDhuff[index]; + Ehuff = CImage->DCEhuff[index]; + if (!Dhuff && !Ehuff) + { + WHEREAMI(); + printf("Reference to nonexistent table %d.\n",index); + } + } + + /*BFUNC + + UseDCHuffmanCheckingGEMSBug() installs the DC Huffman structure from the CImage + structure. + + EFUNC*/ + + void UseDCHuffmanCheckingGEMSBug(index,detected_gems_predictor_bug) + int index; + int *detected_gems_predictor_bug; + { + BEGIN("UseDCHuffmanCheckingGEMSBug"); + + if (index == 1 + && !CImage->DCDhuff[index] && !CImage->DCEhuff[index] + && CImage->DCDhuff[0] && !CImage->DCEhuff[0]) + { + index = 0; + *detected_gems_predictor_bug = 1; + printf("GE table selection bug detected - assuming predictor bug also\n",index); + } + else + { + *detected_gems_predictor_bug = 0; + } Xhuff = CImage->DCXhuff[index]; Dhuff = CImage->DCDhuff[index]; diff -crB jpegdir/io.c jpegdir_patched/io.c *** jpegdir/io.c 1995-03-01 20:57:22.000000000 -0500 --- jpegdir_patched/io.c 2012-02-10 11:28:10.821427000 -0500 *************** *** 36,41 **** --- 36,42 ---- #include #include #endif + #include /* Functions which are local and which are exported. */ *************** *** 439,445 **** BUFFER *buffer; { BEGIN("ReadResizeBuffer"); ! int retval,diff,location,amount; diff = buffer->tptr - buffer->bptr; /* Find out the current usage */ if (len > buffer->size-1) /* calculate if we can hold it */ --- 440,447 ---- BUFFER *buffer; { BEGIN("ReadResizeBuffer"); ! int retval,diff,amount; ! off_t location; diff = buffer->tptr - buffer->bptr; /* Find out the current usage */ if (len > buffer->size-1) /* calculate if we can hold it */ *************** *** 490,500 **** { BEGIN("FlushBuffer"); int retval; #ifdef IO_DEBUG printf("WriteLseek %d\n",buffer->streamoffs+buffer->currentoffs); #endif ! lseek(buffer->iob->file,buffer->streamoffs+buffer->currentoffs,L_SET); if ((retval = write(buffer->iob->file, buffer->space, (buffer->bptr - buffer->space))) < 0) --- 492,504 ---- { BEGIN("FlushBuffer"); int retval; + off_t location; #ifdef IO_DEBUG printf("WriteLseek %d\n",buffer->streamoffs+buffer->currentoffs); #endif ! location=buffer->streamoffs+buffer->currentoffs; ! lseek(buffer->iob->file,location,L_SET); if ((retval = write(buffer->iob->file, buffer->space, (buffer->bptr - buffer->space))) < 0) *************** *** 747,766 **** void SeekEndIob() { BEGIN("SeekEndIob"); ! int size,tsize; static char Terminator[] = {0x80,0x00}; ! size = lseek(Iob->file,0,2); tsize = Iob->width*Iob->height*Iob->wsize; if (size != tsize) { WHEREAMI(); printf("End not flush, making flush (actual: %d != target:%d)\n", ! size,tsize); if (sizefile,tsize-1,0L); /* Seek and terminate */ write(Iob->file,Terminator,1); } else if (size > tsize) --- 751,775 ---- void SeekEndIob() { BEGIN("SeekEndIob"); ! off_t size,tsize; static char Terminator[] = {0x80,0x00}; + off_t location; + struct stat sb; ! location=0; ! /*size = lseek(Iob->file,location,2);*/ ! fstat(Iob->file,&sb); ! size=sb.st_size; tsize = Iob->width*Iob->height*Iob->wsize; if (size != tsize) { WHEREAMI(); printf("End not flush, making flush (actual: %d != target:%d)\n", ! (int)size,(int)tsize); if (sizefile,tsize-1,0); /* Seek and terminate */ write(Iob->file,Terminator,1); } else if (size > tsize) *************** *** 768,774 **** #ifdef NOTRUNCATE WHEREAMI(); printf("file is too large, only first %d bytes valid\n", ! tsize); #else ftruncate(Iob->file,tsize); /* simply truncate*/ #endif --- 777,783 ---- #ifdef NOTRUNCATE WHEREAMI(); printf("file is too large, only first %d bytes valid\n", ! (int)tsize); #else ftruncate(Iob->file,tsize); /* simply truncate*/ #endif *************** *** 885,891 **** void TerminateFile() { BEGIN("TerminateFile"); ! int i,size; static char Terminator[] = {0x80,0x00}; if (CFrame->GlobalHeight) --- 894,902 ---- void TerminateFile() { BEGIN("TerminateFile"); ! int i; ! off_t size; ! off_t location; static char Terminator[] = {0x80,0x00}; if (CFrame->GlobalHeight) *************** *** 907,922 **** CFrame->vf[CScan->ci[i]]); InstallIob(i); FlushIob(); ! size = lseek(CScan->Iob[i]->file,0,2); ! if (size != ! CFrame->Width[CScan->ci[i]]*CFrame->Height[CScan->ci[i]]* ! CScan->Iob[i]->wsize) { /* Terminate file */ ! lseek(CScan->Iob[i]->file, /* by seeking to end */ ! (CFrame->Width[CScan->ci[i]]* /* And writing byte */ ! CFrame->Height[CScan->ci[i]]* ! CScan->Iob[i]->wsize)-1, /* Making flush with */ ! 0L); /* Original size */ write(CScan->Iob[i]->file,Terminator,1); } } --- 918,931 ---- CFrame->vf[CScan->ci[i]]); InstallIob(i); FlushIob(); ! location=0; ! size = lseek(CScan->Iob[i]->file,location,2); ! location=CFrame->Width[CScan->ci[i]]*CFrame->Height[CScan->ci[i]]*CScan->Iob[i]->wsize; ! if (size != location) { /* Terminate file */ ! lseek(CScan->Iob[i]->file, /* by seeking to end and writing byte */ ! location-1, /* Making flush with */ ! 0); /* Original size */ write(CScan->Iob[i]->file,Terminator,1); } } diff -crB jpegdir/jpeg.c jpegdir_patched/jpeg.c *** jpegdir/jpeg.c 1995-03-01 20:57:21.000000000 -0500 --- jpegdir_patched/jpeg.c 2012-02-10 11:38:14.017735000 -0500 *************** *** 30,35 **** --- 30,38 ---- #include "tables.h" #include "globals.h" + #ifdef FCNTL_FOR_O_RDONLY + #include + #endif #ifdef SYSV #include #endif *************** *** 1358,1363 **** --- 1361,1368 ---- int MaxElem,CurrentElem,NumberElem; int StartofLine=1,UseType=1; /* Start with type 1 coding */ int *input; + int last_pixel; /* should initialize this sometime */ + int detected_gems_predictor_bug; PointTransform=CScan->SAL; for(j=0;jNumberComponents;j++) /* Important to rewind to start */ *************** *** 1379,1385 **** } } InstallIob(0); ! UseDCHuffman(CScan->td[0]); /* Install DC table */ if (CScan->NumberComponents==1) height=horfreq=1; else --- 1384,1390 ---- } } InstallIob(0); ! UseDCHuffmanCheckingGEMSBug(CScan->td[0],&detected_gems_predictor_bug); /* Install DC table */ if (CScan->NumberComponents==1) height=horfreq=1; else *************** *** 1466,1472 **** px = input[width]; break; case 2: ! px = input[1]; break; case 3: px = input[0]; --- 1471,1478 ---- px = input[width]; break; case 2: ! /*px = input[1];*/ ! px = detected_gems_predictor_bug ? last_pixel : input[1]; break; case 3: px = input[0]; *************** *** 1493,1499 **** else { value = LosslessDecodeDC(); ! input[width+1] = (value+px)&0xffff; if (Loud > MUTE) { printf("OUT=%d PX=%d VAL: %d\n", --- 1499,1511 ---- else { value = LosslessDecodeDC(); ! if (detected_gems_predictor_bug) { ! input[width+1] = (px-value)&0xffff; ! last_pixel = (px-value)&0xffff; ! } ! else { ! input[width+1] = (value+px)&0xffff; ! } if (Loud > MUTE) { printf("OUT=%d PX=%d VAL: %d\n", Only in jpegdir: lexer.c diff -crB jpegdir/makefile jpegdir_patched/makefile *** jpegdir/makefile 1995-03-01 20:57:26.000000000 -0500 --- jpegdir_patched/makefile 2012-02-10 12:01:05.173520000 -0500 *************** *** 7,22 **** # SYSV allows for SYSV system IO calls. NOTRUNCATE allows # for UNIX emulators without the ftruncate() call. # #DEFINES = -DSYSV -DNOTRUNCATE # ! DEFINES = JFLAGS = -O DEFS = system.h globals.h prototypes.h param.h BASELINE = jpeg.o codec.o huffman.o io.o chendct.o leedct.o lexer.o marker.o stream.o transform.o .c.o: ! cc $(JFLAGS) $(DEFINES) -c $*.c .c.ln: lint -c $*.c --- 7,26 ---- # SYSV allows for SYSV system IO calls. NOTRUNCATE allows # for UNIX emulators without the ftruncate() call. # + # For gcc on Solaris use DFCNTL_FOR_O_RDONLY to include not SYSV ` + # #DEFINES = -DSYSV -DNOTRUNCATE # ! DEFINES = -DFCNTL_FOR_O_RDONLY ! CC = gcc ! #LEXARGS = -ll JFLAGS = -O DEFS = system.h globals.h prototypes.h param.h BASELINE = jpeg.o codec.o huffman.o io.o chendct.o leedct.o lexer.o marker.o stream.o transform.o .c.o: ! $(CC) $(JFLAGS) $(DEFINES) -c $*.c .c.ln: lint -c $*.c *************** *** 24,33 **** all: jpeg clean: ! rm *.o jpeg jpeg: $(BASELINE) ! cc $(DEFINES) $(JFLAGS) $(BASELINE) -lm -o jpeg jpeg.o: jpeg.c $(DEFS) tables.h codec.o: codec.c $(DEFS) --- 28,37 ---- all: jpeg clean: ! rm -f *.o jpeg lexer.c jpeg: $(BASELINE) ! $(CC) $(DEFINES) $(JFLAGS) $(BASELINE) -lm -o jpeg jpeg.o: jpeg.c $(DEFS) tables.h codec.o: codec.c $(DEFS) *************** *** 54,60 **** # Caution: Sometimes -ll is required. # # ! #lexer.c: lexer.l ! # lex lexer.l ! # mv lex.yy.c lexer.c ! # --- 58,69 ---- # Caution: Sometimes -ll is required. # # ! lexer.c: lexer.l ! lex $(LEXARGS) lexer.l ! #mv lex.yy.c lexer.c ! echo "#ifdef FCNTL_FOR_O_RDONLY" >lexer.c ! echo "#include " >>lexer.c ! echo "#endif" >>lexer.c ! cat lex.yy.c >>lexer.c ! rm lex.yy.c ! diff -crB jpegdir/marker.c jpegdir_patched/marker.c *** jpegdir/marker.c 1995-03-01 20:57:24.000000000 -0500 --- jpegdir_patched/marker.c 2012-02-10 11:39:23.586316000 -0500 *************** *** 32,37 **** --- 32,40 ---- #include "globals.h" #include "stream.h" #include "marker.h" + #ifdef FCNTL_FOR_O_RDONLY + #include + #endif #ifdef SYSV #include #endif diff -crB jpegdir/prototypes.h jpegdir_patched/prototypes.h *** jpegdir/prototypes.h 1995-03-01 20:57:18.000000000 -0500 --- jpegdir_patched/prototypes.h 2012-02-10 11:27:03.656610000 -0500 *************** *** 85,90 **** --- 85,91 ---- extern void MakeDhuff(); extern void UseACHuffman(); extern void UseDCHuffman(); + extern void UseDCHuffmanCheckingGEMSBug(); extern void SetACHuffman(); extern void SetDCHuffman(); extern void PrintHuffman(); diff -crB jpegdir/SETUP jpegdir_patched/SETUP *** jpegdir/SETUP 1995-03-01 20:57:30.000000000 -0500 --- jpegdir_patched/SETUP 2012-02-10 12:15:29.293354000 -0500 *************** *** 17,22 **** --- 17,27 ---- which allows for SYSV libraries to be used instead. The NOTRUNCATE flag avoids the lack of the ftruncate() call used in io.c. + For some gcc versions on Solaris, need to include not + otherwise O_RDONLY etc. are not defined; define + FCNTL_FOR_O_RDONLY. This also may need to be added to the lexer.c + output by lex to make it compile. + Caution: For the compilation, the lexer.l file should be older than the lexer.c file otherwise many machines will try and lex the lexer.l file (thus clobbering potentially the lexer.c file). In general, the