sam2p-0.49.2/main.hpp0000644000175100017510000000045212211371426012465 0ustar ptspts/* main.hpp -- provide functions for the GUI * by pts@fazekas.hu at 2002.12.28 */ #ifdef __GNUC__ #pragma interface #endif #ifndef MAIN_HPP #define MAIN_HPP 1 #include "gensi.hpp" extern void init_applier(); extern void init_loader(); extern void init_sam2p_engine(char const*argv0); #endif sam2p-0.49.2/config-vc6.h0000644000175100017510000001131212211371426013137 0ustar ptspts/* config-vc6.h. config.h replacement for MS Visual C++ 6.0 */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define if type char is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* #undef __CHAR_UNSIGNED__ */ #endif /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define if you have the ANSI # stringizing operator in cpp. */ /* #undef HAVE_STRINGIZE */ /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if you have the ANSI C header files. */ /* #undef STDC_HEADERS */ /* A type name of a signed integral type of exactly 16 bits. Always defined. */ #define PTS_INT16_T short /* A type name of a signed integral type of exactly 32 bits. Always defined. */ #define PTS_INT32_T int /* A type name of a signed integral type of exactly 64 bits. Maybe left * 0-defined. */ #define PTS_INT64_T long long /* A type name of a signed integral type of exactly 128 bits. Maybe left * 0-defined. */ #define PTS_INT128_T 0 /* A type name of a signed integral type which has space to hold a pointer. * Always defined. */ #define PTS_INTP_T int /* Imp: document this */ #define PTS_INTP_OK 1 /* Imp: document this */ /* #undef PTS_mode_t */ /* Imp: document this */ /* #undef PTS_off_t */ /* Imp: document this */ /* #undef PTS_pid_t */ /* Imp: document this */ #define PTS_size_t unsigned int /* Just a dummy, non-existent type. */ /* #undef PTS_size_tt */ /* Imp: document this */ /* #undef PTS_uid_t */ /* Imp: document this */ /* #undef PTS_gid_t */ /* Imp: document this */ /* #undef PTS_dev_t */ /* Does the C compiler support prototypes? */ #define HAVE_PROTOTYPES 1 /* Define to empty if the keyword does not work. */ /* #undef volatile */ /* Imp: document this */ #define HAVE_strcpy_in_string 1 /* Imp: document this */ /* #undef HAVE_strcpy_in_strings */ /* Imp: document these */ /* #undef HAVE_MEMCMPY_BUILTIN */ #define HAVE_getc_in_stdio 1 #define HAVE_fgetc_in_stdio 1 #define HAVE_putc_in_stdio 1 #define HAVE_fputc_in_stdio 1 #define HAVE_atoi_in_stdlib 1 /* #undef HAVE_malloc_in_malloc */ #define HAVE_malloc_in_stdlib 1 #define HAVE_memcpy_in_stringxs 1 #define HAVE_sprintf_in_stdio 1 #define HAVE_write_in_unistd 1 #define HAVE_system_in_stdlib 1 /* #undef HAVE_lstat_in_sys_stat */ #define HAVE_PTS_STDC 1 /* #undef HAVE_SWITCH_ENUM_BUG */ #define HAVE_ASCII_SYSTEM 1 #define PTS_CFG_P_TMPDIR 0 /* Is the file c_gcc.cpp required for gcc when linking C++ programs? */ #define HAVE_PTS_C_LGCC_CPP_REQUIRED 1 /* #undef HAVE_PTS_C_LGCC3_CPP_REQUIRED */ /** Does the C library have a working vsnprintf()? */ /* #undef HAVE_PTS_VSNPRINTF */ /* #undef HAVE_PTS_VSNPRINTF_OLD */ /* #undef HAVE_PTS_VSNPRINTF_C99 */ /** What shell does the C library system(3) function call? */ #define HAVE_PTS_SYSTEMF 1 #define HAVE_PTS_SYSTEMF_WIN32 1 /* #undef HAVE_PTS_SYSTEMF_UNIX */ /* #undef HAVE_PTS_SYSTEMF_OTHER */ /** popen("...","wb") and "rb" works binary */ /* #undef HAVE_PTS_POPEN_B */ /** popen("...","w") and "r" works binary */ /* #undef HAVE_PTS_POPEN_ */ /* The number of bytes in a __int64. */ #define SIZEOF___INT64 0 /* The number of bytes in a bool. */ #define SIZEOF_BOOL 1 /* The number of bytes in a char. */ #define SIZEOF_CHAR 1 /* The number of bytes in a char *. */ #define SIZEOF_CHAR_P 4 /* The number of bytes in a int. */ #define SIZEOF_INT 4 /* The number of bytes in a long. */ #define SIZEOF_LONG 4 /* The number of bytes in a long long. */ #define SIZEOF_LONG_LONG 8 /* The number of bytes in a short. */ #define SIZEOF_SHORT 2 /* The number of bytes in a very long. */ #define SIZEOF_VERY_LONG 0 /* The number of bytes in a void *. */ #define SIZEOF_VOID_P 4 /* Can have static const int VARNAME=1; inside a class { ... } ? */ /* #undef HAVE_STATIC_CONST */ /* sam2p-specific */ #define USE_BUILTIN_ZIP 1 #define USE_BUILTIN_FAXE 1 #define USE_BUILTIN_LZW 1 #define USE_IN_GIF 1 #define USE_OUT_GIF 1 sam2p-0.49.2/sam2p16.ico0000644000175100017510000000047612211371426012723 0ustar ptspts(( NDLpv91>x–nZ^֮vnV\}KLew'N""xwBDDBwzrDDKDwx``kwf='alԪc_00a30݈03= w~$̇wK̘$DKDw~"݈$@DUU3DDD@::DA@3DADsam2p-0.49.2/sam2p32.ico0000644000175100017510000000137612211371426012721 0ustar ptspts ( @hT`~TTw /* OSVERSIONINFO etc. */ //#include /* _getpid() */ static unsigned long win32_os_id(void) { static OSVERSIONINFO osver; static DWORD w32_platform = (DWORD)-1; if (w32_platform==-1 || osver.dwPlatformId != w32_platform) { memset(&osver, 0, sizeof(OSVERSIONINFO)); osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osver); w32_platform = osver.dwPlatformId; } return (unsigned long)w32_platform; } static inline bool IsWin95(void) { return (win32_os_id() == VER_PLATFORM_WIN32_WINDOWS); } // static int win32_getpid(void) { int getpid(void) { int pid; pid = _getpid(); /* Windows 9x appears to always reports a pid for threads and processes * that has the high bit set. So we treat the lower 31 bits as the * "real" PID for Perl's purposes. */ if (IsWin95() && pid < 0) pid = -pid; return pid; } #endif // Global Variables: HINSTANCE hInst; // current instance // TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK dialogRun(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, // !! int nCmdShow) { // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings // LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_VCSAM2P, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_VCSAM2P); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage is only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; /*CS_HREDRAW | CS_VREDRAW;*/ wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SAM2P32); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_VCSAM2P; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SAM2P16); return RegisterClassEx(&wcex); } /* --- */ /** An image that can be rendered onto a window really quickly */ class WinFastImage { HDC hmemdc; HBITMAP hbitmap; slen_t wd, ht; public: // WinFastImage::WinFastImage(slen_t wd_, slen_t ht_); WinFastImage(); ~WinFastImage(); /** Constructs a WinFastImage that can be drawn fast onto hdc. */ WinFastImage(HDC hdc, HBITMAP hsrc); /** Constructs a WinFastImage that can be drawn fast onto hwnd and all compatible HDCs. */ WinFastImage(HWND hwnd, HBITMAP hsrc); slen_t getWd() const { return wd; } slen_t getHt() const { return ht; } /* @param hdc dc on which fast rendering is desired * @param hsrc source bitmap containing the data */ void set(HDC hdc, HBITMAP hsrc); inline void drawTo(HDC hdc, slen_t dstX, slen_t dstY) const { drawTo(hdc, dstX, dstY, wd, ht, 0, 0); } inline void drawTo(HDC hdc, slen_t dstX, slen_t dstY, slen_t dstWd, slen_t dstHt, slen_t srcX, slen_t srcY) const { BitBlt(hdc,dstX,dstY,dstWd,dstHt,hmemdc,srcX,srcY,SRCCOPY); } // void drawTo(HDC hdc, slen_t dstX, slen_t dstY); // void drawTo(HDC hdc, slen_t dstX, slen_t dstY, slen_t dstWd, slen_t dstHt, slen_t srcX, slen_t srcY); /** MSDN says hbitmap must be a DDB, but it worked fine for me with a DIB */ static void getSize(HBITMAP hbitmap, slen_t &wd, slen_t &ht); }; void WinFastImage::getSize(HBITMAP hbitmap, slen_t &wd, slen_t &ht) { /* It took me 1 hour to figure this out. Not documented anywhere! */ BITMAPINFOHEADER h2; h2.biSize=sizeof(h2); h2.biBitCount=0; // h2.biWidth=11; h2.biHeight=22; h2.biPlanes=1; HDC hxdc=CreateDC("DISPLAY",NULL,NULL,NULL); GetDIBits(hxdc, hbitmap, 0, 0, NULL, (BITMAPINFO*)&h2, DIB_RGB_COLORS); wd=h2.biWidth; ht=h2.biHeight; DeleteDC(hxdc); } WinFastImage::WinFastImage(): hmemdc(NULL), hbitmap(NULL), wd(0), ht(0) {} WinFastImage::WinFastImage(HDC hdc, HBITMAP hsrc): hmemdc(NULL), hbitmap(NULL) { set(hdc, hsrc); } WinFastImage::WinFastImage(HWND hwnd, HBITMAP hsrc): hmemdc(NULL), hbitmap(NULL) { HDC hdc=GetDC(hwnd); set(hdc, hsrc); ReleaseDC(hwnd, hdc); } WinFastImage::~WinFastImage() { if (hmemdc!=NULL) DeleteDC(hmemdc); if (hbitmap!=NULL) DeleteObject(hbitmap); } void WinFastImage::set(HDC hdc, HBITMAP hsrc) { if (hmemdc!=NULL) DeleteDC(hmemdc); if (hbitmap!=NULL) DeleteObject(hbitmap); /* Imp: error handling */ getSize(hsrc, wd, ht); hmemdc=CreateCompatibleDC(hdc); hbitmap=CreateCompatibleBitmap(hdc, wd, ht); /* BUGFIX at 22:07 */ DeleteObject(SelectObject(hmemdc, hbitmap)); HDC hsrcdc=CreateCompatibleDC(hmemdc); SelectObject(hsrcdc, hsrc); BitBlt(hmemdc,0,0,wd,ht,hsrcdc,0,0,SRCCOPY); DeleteDC(hsrcdc); } /* --- */ class CopyableImage { public: virtual slen_t vi_getWd() const =0; virtual slen_t vi_getHt() const =0; /** Copies an row in RGB PPM8 format from (this) to `to' */ virtual void copyRGBRow(char *to, slen_t whichRow) const =0; }; /** A rectangular RGB image, suitable for displaying in Win32 API */ class WinImageRGB { /** Number of bytes per scanline */ slen_t rlen; HBITMAP hbitmap; /** data[0] is blue of upper left pixel, data[1] is green, data[2] is red. Rows * are aligned to 4-byte boundary */ char *data; BITMAPINFOHEADER header; void init(slen_t wd_, slen_t ht_); public: inline WinImageRGB(slen_t wd_, slen_t ht_) { init(wd_, ht_); } WinImageRGB(CopyableImage const&); ~WinImageRGB(); inline slen_t getWd() const { return header.biWidth; } inline slen_t getHt() const { return -header.biHeight; } virtual inline slen_t vi_getWd() const { return header.biWidth; } virtual inline slen_t vi_getHt() const { return -header.biHeight; } virtual void copyRGBRow(char *to, slen_t whichRow) const; inline slen_t getRlen() const { return rlen; } inline char* getData() const { return data; } inline HBITMAP getHbitmap() const { return hbitmap; } void drawTo(HDC hdc, slen_t dstX, slen_t dstY) const; void drawTo(HDC hdc, slen_t dstX, slen_t dstY, slen_t dstWd, slen_t dstHt, slen_t srcX, slen_t srcY) const; /** Copies image data from an other image in the PPM8 format: ppm8_data[0] * is red, ppm8_data[1] is green, pp8_data[2] is blue. Rows are aligned to * byte boundary. */ void fromPPM8(char const*ppm8_data); void fill(char r, char g, char b); void putPixel(slen_t x, slen_t y, char r, char g, char b); }; void WinImageRGB::init(slen_t wd_, slen_t ht_) { rlen=(wd_*3+3)&~3; header.biSize=sizeof(header); header.biWidth=wd_; header.biHeight=0-ht_; header.biPlanes=1; header.biBitCount=24; header.biCompression=BI_RGB; header.biSizeImage=0; header.biXPelsPerMeter=1000; /* returned by GetBitmapDimensionEx */ header.biXPelsPerMeter=1000; header.biClrUsed=0; header.biClrImportant=0; hbitmap=CreateDIBSection(NULL, (CONST BITMAPINFO*)&header, DIB_RGB_COLORS, (void**)&data, NULL, 0); // slen_t xx=GetDeviceCaps(hbitmap, HORZRES); } WinImageRGB::WinImageRGB(CopyableImage const& other) { init(other.vi_getWd(), other.vi_getHt()); char *buf=new char[rlen]; slen_t pad=(header.biWidth)&3, x, y=0, ym=header.biHeight; char *p=data; char const *ppm8_data; while (ym++!=0) { other.copyRGBRow(buf, y++); ppm8_data=buf; x=header.biWidth; while (x--!=0) { p[2]=*ppm8_data++; p[1]=*ppm8_data++; p[0]=*ppm8_data++; p+=3; } p+=pad; } delete buf; } WinImageRGB::~WinImageRGB() { DeleteObject(hbitmap); } void WinImageRGB::copyRGBRow(char *to, slen_t whichRow) const { if (whichRow<0U-header.biHeight) { char *p=data+rlen*whichRow, *pend=p+rlen; while (p!=pend) { to[0]=p[2]; to[1]=p[1]; to[2]=p[0]; p+=3; to+=3; } } } void WinImageRGB::drawTo(HDC hdc, slen_t dstX, slen_t dstY) const { drawTo(hdc, dstX, dstY, header.biWidth, -header.biHeight, 0, 0); } void WinImageRGB::drawTo(HDC hdc, slen_t dstX, slen_t dstY, slen_t dstWd, slen_t dstHt, slen_t srcX, slen_t srcY) const { HDC hmemdc=CreateCompatibleDC(hdc); DeleteObject(SelectObject(hmemdc, hbitmap)); /* ^^^ set the bitmap for hmemdc that Rectangle (hmemdc etc.) will draw to, to (this) */ // slen_t xx=GetDeviceCaps(hdc, HORZRES); // HPEN hpen=CreatePen(PS_SOLID, 0, RGB(255,0,0)); // HANDLE hold=SelectObject(hmemdc, hpen); // Rectangle(hmemdc,10,10,200,100); // SelectObject(hmemdc, hold); // DeleteObject(hpen); BitBlt(hdc,dstX,dstY,dstWd,dstHt,hmemdc,srcX,srcY,SRCCOPY); DeleteDC(hmemdc); } void WinImageRGB::fromPPM8(char const* ppm8_data) { /* Dat: biWidth*3 is considered when calculating pad */ slen_t pad=(header.biWidth)&3, x, y=header.biHeight; char *p=data; while (y++!=0) { x=header.biWidth; while (x--!=0) { p[2]=*ppm8_data++; p[1]=*ppm8_data++; p[0]=*ppm8_data++; p+=3; } p+=pad; } } void WinImageRGB::fill(char r, char g, char b) { /* Dat: biWidth*3 is considered when calculating pad */ slen_t pad=(header.biWidth)&3, x, y=header.biHeight; char *p=data; while (y++!=0) { x=header.biWidth; while (x--!=0) { *p++=b; *p++=g; *p++=r; } p+=pad; } } void WinImageRGB::putPixel(slen_t x, slen_t y, char r, char g, char b) { if (x<(slen_t)header.biWidth && y<(slen_t)-header.biHeight) { char *p=data+rlen*y+x; p[0]=b; p[1]=g; p[2]=r; } } /* --- */ /** Implements the CopyableImage interface for the sam2p Image::Sampled class. */ class CopyableAdapter: public CopyableImage { Image::Sampled const& img; public: inline CopyableAdapter(Image::Sampled const& img_): img(img_) {} inline virtual slen_t vi_getHt() const { return img.getHt(); } inline virtual slen_t vi_getWd() const { return img.getWd(); } inline virtual void copyRGBRow(char *to, slen_t whichRow) const { img.copyRGBRow(to, whichRow); } }; /* --- */ /** Size of previous open image */ static slen_t wd_last=0, ht_last=0; /** Size of window including decorations !! exclude decorations */ static const unsigned wd_def=150, ht_def=90; static WinImageRGB *imgr=NULL; static WinFastImage *imgf=NULL; static HWND hwnd_main; /** Changed since last save? */ static bool dirty=false; /** File loaded. NULL if no/new; begins with "* " for a dirty file, ": " for a normal file */ static char *filename2=NULL; static bool first_paint_p=true; // static char szHello[MAX_LOADSTRING]; /* OK: not resizable: WM_... */ /* Imp: clipboard copy-paste image */ /* !! about editbox non-grey disabled */ /* !! open rxvt_bug.bmp wrong window size */ /* !! test larger image than screen */ /* !! SetWindowText() LineScroll() */ /* !! bongeszo ne irjon felul ablakot */ /* !! transparent images */ /* void CHistoryEdit::AppendString(CString str) { SendMessage(EM_SETSEL,0xFFFFFFFF,-1); SendMessage(EM_REPLACESEL,FALSE,(LPARAM)(LPCTSTR)str); } */ // PURPOSE: Saves instance handle and creates main window // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { init_sam2p_engine("vcsam2p"); hInst = hInstance; // Store instance handle in our global variable hwnd_main = CreateWindow(szWindowClass, Error::banner0, WS_OVERLAPPED| WS_CAPTION| WS_SYSMENU| WS_MINIMIZEBOX| WS_BORDER| WS_THICKFRAME, // WS_THICKFRAME: resizable (has sizing border) // WS_MAXIMIZEBOX, WS_OVERLAPPEDWINDOW CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hwnd_main) return FALSE; SetWindowPos(hwnd_main, NULL, 0, 0, wd_def, ht_def, SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); #if 0 imgr=new WinImageRGB(226, 33); if (imgr==NULL) return FALSE; imgr->fill(0,0,(char)255); HDC hdc_main=GetDC(hwnd_main); imgf=new WinFastImage(hdc_main, imgr->getHbitmap()); #endif ShowWindow(hwnd_main, nCmdShow); // ReleaseDC(hwnd_main, hdc_main); UpdateWindow(hwnd_main); // imgr->fill((char)255,0,0); return TRUE; } static void do_ask_save_as() { // !! implement this } /** @return true iff save successful */ static bool do_save(bool ask_save_as) { /* !! implement this */ if (!dirty) return true; if (filename2==NULL && ask_save_as) do_ask_save_as(); if (filename2==NULL) return false; if (IDYES==MessageBox(hwnd_main, "Saving... Success?", NULL, MB_YESNO)) { dirty=false; return true; } return false; } static void do_save_as(void) { char *old_filename2=filename2; filename2=NULL; do_ask_save_as(); if (filename2!=NULL) { if (do_save(false)) { delete [] old_filename2; return; } delete [] filename2; } filename2=old_filename2; } /** no@@return true iff should exit */ static void do_exit(void) { if (dirty) { int i=MessageBox(hwnd_main, "Save changes before exit?", "Confirm exit", MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_DEFBUTTON1); if (i==IDCANCEL || (i==IDYES && !do_save(true))) return; } DestroyWindow(hwnd_main); } static void getFrameSize(HWND hwnd, LONG &wd_ret, LONG &ht_ret) { RECT wr; GetWindowRect(hwnd, &wr); RECT cr; GetClientRect(hwnd, &cr); wd_ret=(wr.right-wr.left)-(cr.right-cr.left); ht_ret=(wr.bottom-wr.top)-(cr.bottom-cr.top); } extern Image::Loader in_bmp_loader; struct SamArgs { typedef void* (WINAPI*samfun_t)(SamArgs const*); }; struct SamImageLoad: public SamArgs { char const *filename; SimBuffer::Flat *loadHints; }; void* WINAPI do_image_load(SamImageLoad const* args) { // Error::sev((Error::level_t) 2) << "a lma" << (Error*)0; return Image::load(args->filename, *(args->loadHints)); } void* do_samfun(SamArgs::samfun_t samfun, SamArgs const* args) { SimBuffer::B log; GenBuffer::Writable *old_serr=Error::serr; Error::pushPolicy((Error::level_t)0, (Error::level_t)-99, (Error::level_t)-199, &log); // Error::serr=&log; HANDLE hthread; DWORD res=0, tid; /* printf("Creating thread.\n"); */ if (NULL==(hthread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)samfun, (void*)args, CREATE_SUSPENDED, &tid))) { log << "CreateThread() failed\n"; on_error: Error::serr=old_serr; log.term0(); MessageBox(hwnd_main, log(), Error::banner0, 0); return NULL; } /* printf("Resuming thread (h=0x%x tid=0x%x).\n", hthread, tid); */ if (0==1+ResumeThread(hthread)) { log << "ResumeThread() failed\n"; on_thread_error: TerminateThread(hthread, 0); CloseHandle(hthread); goto on_error; } /* printf("Waiting for thread.\n"); */ if (WAIT_FAILED==WaitForSingleObject(hthread, INFINITE)) { log << "WaitForSingleObject() failed\n"; goto on_thread_error; } if (0==GetExitCodeThread(hthread, &res)) { log << "GetExitCodeThread() failed\n"; goto on_thread_error; } Error::popPolicy(); CloseHandle(hthread); Error::serr=old_serr; // !! vvv 0 == NULL, exit(1), exit(2) is if (res+0U<10U) { /* log << "return(NULL);\n1\n"; */ goto on_error; } /* printf("Done, thread has returned=%u\n", res); */ return (void*)res; } /** Load image from disk, update imgr and imgf * @return true on success */ static bool do_open_image(char const* filename) { // MessageBox(NULL, filename, "opening image", 0); if (imgf!=NULL) { if (imgr!=NULL) { delete imgr; imgr=NULL; } delete imgf; imgf=NULL; if (filename2!=NULL) filename2[0]='-'; /* mark file closed */ } // !! free // !! check for errors // !! generalize SimBuffer::B loadHints; #if 0 Image::Loader::reader_t reader=in_bmp_loader.checker( "BM\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0", "", opt); FILE *f=fopen(filename, "rb"); if (f==NULL) return false; Image::Sampled *img=reader((Image::filep_t)f, loadHints); fclose(f); #endif init_loader(); SamImageLoad args; args.filename=filename; args.loadHints=&loadHints; Image::Sampled *img=(Image::Sampled*)do_samfun((SamArgs::samfun_t)do_image_load, &args); if (img==NULL) return false; // Image::load(filename, loadHints); imgr=new WinImageRGB(CopyableAdapter(*img)); // Image::Sampled *imgrgb=img->toRGB(8); // imgr=new WinImageRGB(img->getWd(), img->getHt()); // imgr->fill(0,0,(char)255); // imgr->fromPPM8(imgrgb->getRowbeg()); assert(imgr!=NULL); /* `operator new' never returns NULL */ // HDC hdc_main=GetDC(hwnd_main); imgf=new WinFastImage(hwnd_main, imgr->getHbitmap()); wd_last=imgf->getWd(); ht_last=imgf->getHt(); // ReleaseDC(hwnd_main, hdc_main); slen_t len=strlen(filename); if (filename2!=NULL) delete [] filename2; strcpy(filename2=new char[len+3], ": "); strcpy(filename2+2, filename); SetWindowText(hwnd_main, filename2); SetWindowLong(hwnd_main, GWL_STYLE, GetWindowLong(hwnd_main, GWL_STYLE)&~WS_THICKFRAME); /* ^^^ The Win32 API way to say hwnd_main.setResizable(false); :-) */ InvalidateRect(hwnd_main, NULL, TRUE); #if 0 LONG fr_wd, fr_ht; getFrameSize(hwnd_main, fr_wd, fr_ht); // !! handle minimum window size SetWindowPos(hwnd_main, NULL, 0, 0, fr_wd+imgf->getWd(), fr_ht+imgf->getHt(), SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); GdiFlush(); { /* Dat: strange, two iterations of getFrameSize + SetWindowPos is needed !! still bad */ getFrameSize(hwnd_main, fr_wd, fr_ht); SetWindowPos(hwnd_main, NULL, 0, 0, fr_wd+imgf->getWd(), fr_ht+imgf->getHt(), SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); } BOOL CYourWndOrDialog::ResizeClient (int nWidth, int nHeight, BOOL bRedraw) { RECT rcWnd; GetClientRect (&rcWnd); if(nWidth != -1) rcWnd.right = nWidth; if(nHeight != -1) rcWnd.bottom = nHeight; if(!::AdjustWindowRectEx(&rcWnd, GetStyle(), (!(GetStyle() & WS_CHILD) && GetMenu() != NULL)), GetExStyle())) return FALSE; UINT uFlags = SWP_NOZORDER | SWP_NOMOVE; if(!bRedraw) uFlags |= SWP_NOREDRAW; return SetWindowPos(NULL, 0, 0, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top, uFlags); } // CYourWndOrDialog::ResizeClient #endif RECT rt; rt.left=0; rt.right=imgf->getWd(); rt.top=0; rt.bottom=imgf->getHt(); AdjustWindowRect(&rt, GetWindowLong(hwnd_main, GWL_STYLE), TRUE); // !! true SetWindowPos(hwnd_main, NULL, 0,0, rt.right-rt.left, rt.bottom-rt.top, SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); return true; } static char const* loadImageFilter= "all loadable images\0*.tiff;*.tif;*.jpeg;*.jpg;*.gif;*.png;*.pnm;*.pgm;*.ppm;*.xpm;*.lbm;*.tga;*.pcx;*.bmp\0" "TIFF images\0*.tiff;*.tif\0" "JPEG images\0*.jpeg;*.jpg\0" "GIF images\0*.gif\0" "PNG images\0*.png\0" "PNM images\0*.pnm;*.pbm;*.pgm;*.ppm\0" "PBM images\0*.pbm\0" "PGM images\0*.pgm\0" "PPM images\0*.ppm\0" "XPM images\0*.xpm\0" "IFF ILBM images\0*.lbm\0" // "EPS figures\0*.eps\0" // "PostScript documents\0*.ps\0" // "PDF figures\0*.pdf\0" // "XWD screen shots\0*.xwd\0" // "PAM images\0*.pam\0" // "Image meta information\0*.meta\0" "Targa TGA images\0*.tga\0" "PCX images\0*.pcx\0" "Windows BMP bitmaps\0*.bmp\0" "All files (*)\0*\0"; static char const* saveImageFilter= "all saveable images\0*.tiff;*.tif;*.jpeg;*.jpg;*.gif;*.png" ";*.pnm;*.pgm;*.ppm;*.xpm;*.lbm;*.tga;*.pcx;*.bmp;*.eps;*.ps;*.pdf;*.xwd;*.pam;*.meta\0" "TIFF images\0*.tiff;*.tif\0" "JPEG images\0*.jpeg;*.jpg\0" "GIF images\0*.gif\0" "PNG images\0*.png\0" "PNM images\0*.pnm;*.pbm;*.pgm;*.ppm\0" "PBM images\0*.pbm\0" "PGM images\0*.pgm\0" "PPM images\0*.ppm\0" "XPM images\0*.xpm\0" "IFF ILBM images\0*.lbm\0" "EPS figures\0*.eps\0" "PostScript documents\0*.ps\0" "PDF figures\0*.pdf\0" "XWD screen shots\0*.xwd\0" // "PAM images\0*.pam\0" "Image meta information\0*.meta\0" "Targa TGA images\0*.tga\0" "PCX images\0*.pcx\0" "Windows BMP bitmaps\0*.bmp\0" "All files (*)\0*\0"; static void do_open(void) { OPENFILENAME ofn; // ZeroMemory(&ofn, sizeof(ofn)); char szFileName[MAX_PATH]; szFileName[0]='\0'; ofn.lpstrTitle="Open image with sam2p"; ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW ofn.hwndOwner = NULL; // hwnd; ofn.lpstrFilter=loadImageFilter; ofn.lpstrDefExt=NULL; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST /*|OFN_HIDEREADONLY*/ |OFN_EXTENSIONDIFFERENT /*|OFN_NODEREFERENCELINKS*/ |OFN_READONLY; ofn.lpstrDefExt = "txt"; ofn.hInstance=NULL; ofn.lpstrCustomFilter=NULL; // !! ofn.nMaxCustFilter=0; // !! ofn.nFilterIndex=0; // use Custom Filter ofn.lpstrFileTitle=NULL; ofn.nMaxFileTitle=0; ofn.lpstrInitialDir=NULL; // use current directory ofn.nFileOffset=0; ofn.nFileExtension=0; ofn.lCustData=NULL; ofn.lpfnHook=NULL; ofn.lpTemplateName=NULL; // MessageBox(NULL, "hello", "world", 0); if (GetOpenFileName(&ofn)) { do_open_image(szFileName); } } static void do_new(void) { if (imgf!=NULL) { if (filename2!=NULL) filename2[0]='-'; if (imgr!=NULL) { delete imgr; imgr=NULL; } delete imgf; imgf=NULL; #if 0 if (filename2!=NULL) { delete [] filename2; filename2=NULL; } SetWindowText(hwnd_main, Error::banner0); #endif SetWindowLong(hwnd_main, GWL_STYLE, GetWindowLong(hwnd_main, GWL_STYLE)|WS_THICKFRAME); /* ^^^ The Win32 API way to say hwnd_main.setResizable(true); :-) */ InvalidateRect(hwnd_main, NULL, TRUE); // SetWindowPos(hwnd_main, NULL, 0, 0, wd_def, ht_def, SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); /* ^^^ Do _not_ revert to default window size */ SendMessage(hwnd_main, WM_SIZE, 0, 0); /* calls updateBgText() */ } else if (wd_last!=0 || ht_last!=0) { if (filename2!=NULL) { delete [] filename2; filename2=NULL; } SetWindowText(hwnd_main, Error::banner0); wd_last=0; ht_last=0; SendMessage(hwnd_main, WM_SIZE, 0, 0); /* calls updateBgText() */ } } /** Rectangle to draw the background text into */ static RECT bgRect={0,0,0,0}; static char bgText[128]; /** @param hwnd hwnd_main */ static void updateBgText(HWND hwnd, slen_t x, slen_t y) { RECT rt; HDC hdc=GetDC(hwnd); GetClientRect(hwnd, &rt); bgRect=rt; sprintf(bgText, "%s\n%lu\327%lu", Error::banner0, x+0UL, y+0UL); // DrawText(hdc, msg, strlen(msg), &rt, DT_CENTER|DT_VCENTER|DT_SINGLELINE); int textht=DrawText(hdc, bgText, -1, &rt, DT_CENTER|DT_CALCRECT); bgRect.top+=(bgRect.bottom-bgRect.top-textht)/2; ReleaseDC(hwnd, hdc); } //void CDECL AfxTrace(LPCTSTR lpszFormat, ...); /** Processes messages for the main window. */ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT *rp, rt; int i; switch (message) { case WM_PAINT: if (first_paint_p) { first_paint_p=false; // LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); } hdc = BeginPaint(hwnd, &ps); if (imgf==NULL) { /* no image is loaded yet */ DrawText(hdc, bgText, -1, &bgRect, DT_CENTER); } else { GetClientRect(hwnd, &rt); bool xbad=0U+rt.right-rt.left>imgf->getWd(), ybad=0U+rt.bottom-rt.top>imgf->getHt(); if (ps.fErase && (xbad || ybad)) { /* Erase only region not part of the image; to avoid flicker */ // HDC hdc=GetDC(hwnd); // HBRUSH hbrush=(HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND); HBRUSH hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH); HGDIOBJ holdbrush=SelectObject(hdc, hbrush); HPEN hpen=(HPEN)GetStockObject(WHITE_PEN); /* always used */ HGDIOBJ holdpen=SelectObject(hdc, hpen); Rectangle(hdc, imgf->getWd(), rt.top, rt.right, rt.bottom); Rectangle(hdc, rt.left, imgf->getHt(), imgf->getWd(), rt.bottom); SelectObject(hdc, holdpen); SelectObject(hdc, holdbrush); // ReleaseDC(hwnd, hdc); } // if (imgf==NULL) imgf=new WinFastImage(hdc, imgr->getHbitmap()); // rt.right-=rt.left; rt.bottom-=rt.top; imgf->drawTo(hdc, rt.left, rt.top); if (xbad) { /* show the borders of the image inside the window */ MoveToEx(hdc, rt.left+imgf->getWd(), rt.top, NULL); LineTo(hdc, rt.left+imgf->getWd(), rt.bottom-1); LineTo(hdc, rt.right-1, rt.top); } if (ybad) { /* show the borders of the image inside the window */ MoveToEx(hdc, rt.left, imgf->getHt()+rt.top, NULL); LineTo(hdc, rt.left+imgf->getWd(), rt.bottom-1); LineTo(hdc, rt.left, imgf->getHt()+rt.top); } } EndPaint(hwnd, &ps); return 0; case WM_COMMAND: /* int wmId=LOWORD(wParam), wmEvent=HIWORD(wParam); */ switch (LOWORD(wParam)) { case IDM_SAVE: do_save(true); return 0; case IDM_SAVE_AS: { char *argv[]={"(progname)","pts.ppm","pts.ps",NULL}; int argc=3; char result[30]; int ret=main(argc, argv); // int ret=getpid(); sprintf(result, "main run: %d", ret); MessageBox(hwnd, result, NULL, 0); /* unreached !! */ } do_save_as(); return 0; case IDM_WEBSITE: /* Dat: it seems to be impossible to force the browser to open the URL * in a new window (instead of overwriting the current window). There * are OLE/DDE solutions for Netscape4 and Internet Explorer, but no * generic solution. */ ShellExecute(hwnd, "open", "http://www.inf.bme.hu/~pts/sam2p/", 0, 0, SW_SHOWDEFAULT); return 0; case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hwnd, (DLGPROC)About); return 0; case IDM_OPEN: do_open(); return 0; case IDM_NEW: do_new(); return 0; case IDM_PARAMETERS: DialogBox(hInst, (LPCTSTR)IDD_RUN, hwnd, (DLGPROC)dialogRun); return 0; case IDM_EXIT: do_exit(); return 0; default: MessageBox(hwnd,"Unimplemented.", Error::banner0, 0); return 0; } case WM_SIZING: /* possibly override resize requests */ if (imgf!=NULL) { /* resize the window to perfectly fit the image */ rp=(RECT*)lParam; // RECT wr; GetWindowRect(hwnd, &wr); // RECT cr; GetClientRect(hwnd, &cr); // rp->right=rp->left+imgf->getWd()+(wr.right-wr.left)-(cr.right-cr.left); // rp->bottom=rp->top+imgf->getHt()+(wr.bottom-wr.top)-(cr.bottom-cr.top); getFrameSize(hwnd, rp->right, rp->bottom); rp->right+=rp->left+imgf->getWd(); rp->bottom+=rp->top+imgf->getHt(); return TRUE; } else return FALSE; case WM_ERASEBKGND: if (imgf!=NULL) return FALSE; break; /* Dat: upon window resize, WM_SIZING, WM_SIZE, WM_ERASEBKGND and WM_PAINT is sent in this order */ case WM_SIZE: /* we have been resized; let's invalidate the window contents */ GetClientRect(hwnd, &rt); if (wd_last==0 && ht_last==0) updateBgText(hwnd, rt.right-rt.left, rt.bottom-rt.top); else updateBgText(hwnd, wd_last, ht_last); InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_CLOSE: /* user has clicked button X on the title bar; confirm exit first */ do_exit(); return 0; case WM_DESTROY: /* exit already confirmed */ PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } #if 0 char *s="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; #endif // Mesage handler for about box. LRESULT CALLBACK About(HWND hdlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) { switch (message) { case WM_INITDIALOG: { HFONT hfont=CreateFont(10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 0, /*"System"*/ "MS Sans Serif"); SendMessage(GetDlgItem(hdlg, IDC_PRODUCT), WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0)); // !! DeleteObject SetDlgItemText(hdlg, IDC_PRODUCT, Error::banner0); SetDlgItemText(hdlg, IDC_INFO, "This is the Win32 GUI of sam2p.\r\n" " sam2p is a UNIX command line utility written in ANSI C++ that converts many " "raster (bitmap) image formats into Adobe PostScript or PDF files and several " "other formats. The images " "are not vectorized. sam2p gives full control to the user to specify " "standards-compliance, compression, and bit depths. In some cases sam2p can " "compress an image 100 times smaller than the PostScript output of many other " "common image converters. sam2p provides ZIP, RLE and LZW (de)compression " "filters even on Level1 devices.\r\n"); } return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { { CHOOSEFONT cf; ZeroMemory(&cf, sizeof(cf)); cf.lStructSize=sizeof(cf); cf.rgbColors=0; /* black */ cf.Flags=CF_EFFECTS|CF_FORCEFONTEXIST|CF_NOSIMULATIONS|CF_NOVERTFONTS|CF_SCREENFONTS; cf.hwndOwner=NULL; cf.hDC=NULL; ChooseFont(&cf); } EndDialog(hdlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; } LRESULT CALLBACK dialogRun(HWND hdlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) { switch (message) { case WM_INITDIALOG: { HWND hwnd=GetDlgItem(hdlg, IDC_ELOG); HFONT hfont=CreateFont(10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0,"Fixedsys"); SendMessage(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0)); // DeleteObject(hfont); /* Imp: where to do DeleteObject()? */ /* PostMessage doesn't work, either */ unsigned i; char buf[222]; for (i=0;i<100;i++) { SendMessage(hwnd,EM_SETSEL,0U-1,0U-1); sprintf(buf, "%d Hello, World! 0123456789 1111111111 222222222 333333333\r\n", i); SendMessage(hwnd,EM_REPLACESEL,FALSE,(LPARAM)(LPCTSTR)buf); } SendMessage(hwnd,EM_SCROLLCARET,0,0); InvalidateRect(hwnd,NULL,FALSE); /* no effect */ // !! EM_REPLACESEL doesn't make the end of the edit box text } return TRUE; #if 0 case WM_ACTIVATE: { // HWND hwnd=GetDlgItem(hdlg, IDC_ELOG); // MessageBox(NULL,"Hello","",0); //SendMessage(hwnd,EM_SETSEL,-1,2000); //SendMessage(hwnd,EM_SCROLLCARET,0,0); //InvalidateRect(hwnd,NULL,FALSE); /* no effect */ } return TRUE; #endif case WM_COMMAND: if (LOWORD(wParam) == IDOK) { HWND hwnd=GetDlgItem(hdlg, IDC_ELOG); SendMessage(hwnd,EM_SETSEL,0xFFFFFFFF,-1); SendMessage(hwnd,EM_REPLACESEL,FALSE,(LPARAM)(LPCTSTR)"Append."); break; } if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hdlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; } sam2p-0.49.2/vcsam2p.dsp0000644000175100017510000001555312211371426013123 0ustar ptspts# Microsoft Developer Studio Project File - Name="vcsam2p" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 CFG=vcsam2p - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "vcsam2p.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "vcsam2p.mak" CFG="vcsam2p - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "vcsam2p - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "vcsam2p - Win32 Debug" (based on "Win32 (x86) Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "vcsam2p - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c # SUBTRACT CPP /YX /Yc /Yu # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 !ELSEIF "$(CFG)" == "vcsam2p - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /W4 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "vcsam2p - Win32 Release" # Name "vcsam2p - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\appliers.cpp # End Source File # Begin Source File SOURCE=.\crc32.c # End Source File # Begin Source File SOURCE=.\encoder.cpp !IF "$(CFG)" == "vcsam2p - Win32 Release" !ELSEIF "$(CFG)" == "vcsam2p - Win32 Debug" # ADD CPP /W4 /GX- /Od /YX"config2.h" !ENDIF # End Source File # Begin Source File SOURCE=.\error.cpp # End Source File # Begin Source File SOURCE=.\gensi.cpp # End Source File # Begin Source File SOURCE=.\gensio.cpp # End Source File # Begin Source File SOURCE=.\image.cpp # End Source File # Begin Source File SOURCE=.\in_bmp.cpp # End Source File # Begin Source File SOURCE=.\in_gif.cpp # End Source File # Begin Source File SOURCE=.\in_jai.cpp # End Source File # Begin Source File SOURCE=.\in_jpeg.cpp # End Source File # Begin Source File SOURCE=.\in_lbm.cpp # End Source File # Begin Source File SOURCE=.\in_pcx.cpp # End Source File # Begin Source File SOURCE=.\in_png.cpp # End Source File # Begin Source File SOURCE=.\in_pnm.cpp # End Source File # Begin Source File SOURCE=.\in_tga.cpp # End Source File # Begin Source File SOURCE=.\in_tiff.cpp # End Source File # Begin Source File SOURCE=.\in_xpm.cpp # End Source File # Begin Source File SOURCE=.\mapping.cpp # End Source File # Begin Source File SOURCE=.\minips.cpp # End Source File # Begin Source File SOURCE=.\out_gif.cpp # End Source File # Begin Source File SOURCE=.\pts_defl.c # End Source File # Begin Source File SOURCE=.\pts_fax.c # End Source File # Begin Source File SOURCE=.\pts_lzw.c # End Source File # Begin Source File SOURCE=.\rule.cpp # End Source File # Begin Source File SOURCE=.\sam2p_main.cpp # End Source File # Begin Source File SOURCE=.\snprintf.c # End Source File # Begin Source File SOURCE=.\StdAfx.cpp # ADD CPP /Yc"stdafx.h" # End Source File # Begin Source File SOURCE=.\vcsam2p.cpp # End Source File # Begin Source File SOURCE=.\vcsam2p.rc # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\at_bitmap.h # End Source File # Begin Source File SOURCE=.\cgif.h # End Source File # Begin Source File SOURCE=.\config.h # End Source File # Begin Source File SOURCE=.\config2.h # End Source File # Begin Source File SOURCE=.\crc32.h # End Source File # Begin Source File SOURCE=.\pts_defl.h # End Source File # Begin Source File SOURCE=.\pts_fax.h # End Source File # Begin Source File SOURCE=.\pts_lzw.h # End Source File # Begin Source File SOURCE=.\resource.h # End Source File # Begin Source File SOURCE=.\snprintf.h # End Source File # Begin Source File SOURCE=.\StdAfx.h # End Source File # Begin Source File SOURCE=.\tmp.h # End Source File # Begin Source File SOURCE=.\vcsam2p.h # End Source File # Begin Source File SOURCE=.\xpmc.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=.\small.ico # End Source File # Begin Source File SOURCE=.\vcsam2p.ico # End Source File # End Group # Begin Source File SOURCE=.\ReadMe.txt # End Source File # End Target # End Project sam2p-0.49.2/vcsam2p.h0000644000175100017510000000047512211371426012561 0ustar ptspts #if !defined(AFX_VCSAM2P_H__26C24785_06B6_11D7_846E_0004E2009304__INCLUDED_) #define AFX_VCSAM2P_H__26C24785_06B6_11D7_846E_0004E2009304__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "resource.h" #endif // !defined(AFX_VCSAM2P_H__26C24785_06B6_11D7_846E_0004E2009304__INCLUDED_) sam2p-0.49.2/vcsam2p.ico0000644000175100017510000000206612211371426013102 0ustar ptspts &(( @( sam2p-0.49.2/vcsam2p.rc0000644000175100017510000000771312211371426012740 0ustar ptspts//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS #include "resource.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_SAM2P16 ICON DISCARDABLE "sam2p16.ico" IDI_SAM2P32 ICON DISCARDABLE "sam2p32.ico" ///////////////////////////////////////////////////////////////////////////// // // Menu // IDC_VCSAM2P MENU DISCARDABLE BEGIN POPUP "&Image" BEGIN MENUITEM "&New/Close", IDM_NEW MENUITEM "&Open...", IDM_OPEN MENUITEM "&Save", IDM_SAVE MENUITEM "Save &as...", IDM_SAVE_AS MENUITEM "&Parameters...", IDM_PARAMETERS MENUITEM SEPARATOR MENUITEM "E&xit", IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&About sam2p...", IDM_ABOUT MENUITEM "&Web site", IDM_WEBSITE END END ///////////////////////////////////////////////////////////////////////////// // // Accelerator // IDC_VCSAM2P ACCELERATORS MOVEABLE PURE BEGIN "?", IDM_ABOUT, ASCII, ALT "/", IDM_ABOUT, ASCII, ALT END ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 142, 76 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "System" BEGIN ICON IDI_SAM2P32,IDC_MYICON,2,3,16,16 LTEXT "vcsam2p Version 1.0",IDC_PRODUCT,19,5,90,8,SS_NOPREFIX LTEXT "Copyright (C) 2002 pts",IDC_STATIC,1,20,139,52 DEFPUSHBUTTON "OK",IDOK,110,4,30,11,WS_GROUP END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 2 TEXTINCLUDE DISCARDABLE BEGIN "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""resource.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_ABOUTBOX, DIALOG BEGIN BOTTOMMARGIN, 75 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN IDS_APP_TITLE "vcsam2p" IDS_HELLO "Hello World!" IDC_VCSAM2P "VCSAM2P" END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED sam2p-0.49.2/resource.h0000644000175100017510000000322612211371426013032 0ustar ptspts//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by vcsam2p.rc // #define IDC_MYICON 2 #define IDOK2 3 #define IDD_VCSAM2P_DIALOG 102 #define IDD_ABOUTBOX 103 #define IDS_APP_TITLE 103 #define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDS_HELLO 106 #define IDI_VCSAM2P 107 #define IDI_SMALL 108 #define IDC_VCSAM2P 109 #define IDR_MAINFRAME 128 #define IDI_SAM2P16 131 #define IDI_SAM2P32 132 #define IDD_RUN 133 #define IDC_PRODUCT 1000 #define IDC_EDIT1 1001 #define IDC_ELOG 1001 #define IDC_INFO 1001 #define IDC_EDIT2 1002 #define IDM_OPEN 32771 #define IDM_SAVE 32772 #define IDM_WEBSITE 32773 #define IDM_SAVE_AS 32774 #define IDM_NEW 32775 #define IDM_PARAMETERS 32776 #define IDC_STATIC -1 #define IDC_COPYRIGHT -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 134 #define _APS_NEXT_COMMAND_VALUE 32777 #define _APS_NEXT_CONTROL_VALUE 1003 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif sam2p-0.49.2/StdAfx.cpp0000644000175100017510000000043612211371426012727 0ustar ptspts// stdafx.cpp : source file that includes just the standard includes // vcsam2p.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file sam2p-0.49.2/StdAfx.h0000644000175100017510000000204312211371426012370 0ustar ptspts// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) #define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include #include /* _getpid() */ #include /* ShellExecute() */ // C RunTime Header Files #include #include #include #include #include /* sprintf() */ #include /* OPENFILENAME */ // Local Header Files // TODO: reference additional headers your program requires here //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) sam2p-0.49.2/hq.pl0000755000175100017510000000237412211371426012005 0ustar ptspts#! /bin/sh -- eval '(exit $?0)' && eval 'PERL_BADLANG=x;export PERL_BADLANG;: \ ;exec perl -x -S -- "$0" ${1+"$@"};#'if 0; eval 'setenv PERL_BADLANG x;exec perl -x -S -- "$0" $argv:q;#'.q #!perl -w +($0=~/(.*)/s);do$1;die$@if$@;__END__+if 0; # Don't touch/remove lines 1--7: http://www.inf.bme.hu/~pts/Magic.Perl.Header # # hq.pl -- convert binary STDIN to C language "quoted\\-string" # by pts@fazekas.hu at Tue Dec 3 17:46:52 CET 2002 # # VC6.0 imposes the following restrictions: # -- the number of (destination) characters inside a single "..." block may # not exceed 2048 # -- the number of "..." blocks may not exceed 999 if the /Zm999 compiler # option is specified; this number should be minimized # -- "\12319" causes a stupid warning, should be emitted as: "\123\51\61" # -- output lines should not be too long (I limit them to 79 chars) # my @numenc=('\60','\61','\62','\63','\64','\65','\66','\67','\70','\71'); my @enc; for (my $I=0;$I<256;$I++) { $enc[$I]=sprintf"\\%03o",$I } binmode STDIN if @ARGV; binmode STDOUT; # UNIX NL in output while (0 #include /* for write(), also available on Windows */ /* Sat Jul 6 16:39:19 CEST 2002 * empirical checkerg++ helper routines for gcc version 2.95.2 20000220 (Debian GNU/Linux) */ #ifdef __CHECKER__ void* __builtin_vec_new XMALLOC_CODE() void __builtin_vec_delete XFREE_CODE() void* __builtin_new XMALLOC_CODE() void __builtin_delete XFREE_CODE() void __rtti_user() { abort(); } void __rtti_si() { abort(); } void terminate() { abort(); } /* void* __pure_virtual=0; -- doesn't work */ extern "C" void __pure_virtual(); void __pure_virtual() { abort(); } #else /* at Tue Sep 3 18:24:26 CEST 2002: * empirical g++-3.2 helper routines for gcc version 3.2.1 20020830 (Debian prerelease) * at Sun Dec 19 19:25:31 CET 2010: * works for g++-4.2.1 and g++-4.4.1 as well * removed dependency on stdio, so we get more reliable OOM reporting */ extern "C" void* emulate_cc_new(unsigned len) { \ void *p = malloc(len); if (p == 0) { /* Don't use stdio (e.g. fputs), because that may want to allocate more * memory. */ (void)!write(2, "out of memory\n", 14); abort(); } return p; } extern "C" void emulate_cc_delete(void* p) { if (p!=0) free(p); } void* operator new (unsigned len) __attribute__((alias("emulate_cc_new"))); void* operator new[](unsigned len) __attribute__((alias("emulate_cc_new"))); void operator delete (void* p) __attribute__((alias("emulate_cc_delete"))); void operator delete[](void* p) __attribute__((alias("emulate_cc_delete"))); void* __cxa_pure_virtual = 0; #endif sam2p-0.49.2/c_lgcc3.cpp0000644000175100017510000000164512211371426013036 0ustar ptspts/* c_lgcc3.cpp -- make g++-3.2 programs linkable with gcc-2.95 * by pts@fazekas.hu at Wed Dec 11 16:33:03 CET 2002 * * This file is not sam2p-specific. See also AC_PTS_GCC_LINKS_CXX in file * aclocal.m4. */ #include #include /* vvv make these a macro to make them fast */ #define XMALLOC_CODE() (unsigned len) { \ void *p=malloc(len); \ if (p==0) { fputs("out of memory\n",stderr); abort(); } \ return p; \ } #define XFREE_CODE() (void* p) { if (p!=0) free(p); } /* at Wed Dec 11 16:31:42 CET 2002 * This helper is here for gcc-2.95: c_lgcc3.cpp should be compiled by * gcc-2.95, remaining files are compiled by g++-3.2 */ void* __cxa_pure_virtual=0; extern "C" void _ZdlPv (void*); extern "C" void* _Znwj (unsigned); extern "C" void _ZdaPv (void*); extern "C" void* _Znaj (unsigned); void _ZdlPv XFREE_CODE() void* _Znwj XMALLOC_CODE() void _ZdaPv XFREE_CODE() void* _Znaj XMALLOC_CODE() sam2p-0.49.2/in_jai.hpp0000644000175100017510000000236712211371426013001 0ustar ptspts/* in_jai.hpp -- Tue Jun 11 19:05:04 CEST 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef IN_JAI_HPP #define IN_JAI_HPP 1 #include "config2.h" #if USE_IN_JAI #include "gensio.hpp" struct jai_gfxinfo { /** 0 for baseline JPEG, 1..15 for other JPEG compression */ unsigned char SOF_type; unsigned char colorspace; unsigned char bad, bpc, cpp, had_jfif, colortransform, id_rgb; /** (Horiz<<4+Vert) sampling factor for the first color component. Usually * 0x11, but TIFF defaults to 0x22. */ unsigned char hvs; /*Image::Sampled::dimen_t*/slen_t height, width; /** Offset of byte just _after_ the first SOF marker (FF C0 or alike) * from the beginning of the file. */ slen_t SOF_offs; }; extern char const*jai_errors[]; #if 0 extern void jai_parse_jpeg(struct gfxinfo *result, Filter::FlatR *f); extern void jai_parse_jpeg(struct gfxinfo *result, FILE *f); #else extern void jai_parse_jpeg(struct jai_gfxinfo *result, DecoderTeller *fp, bool must_be_baseline=true); /** Doesn't treat `-' as a special filename. @return 0, 1, or -1 on I/O error */ extern int jai_is_baseline_jpeg(char const* filename); extern int jai_is_baseline_jpeg(/*DecoderTeller*/ Filter::UngetFILED *fp); #endif #endif #endif /* in_jai.hpp */ sam2p-0.49.2/jpegdump_main.cpp0000644000175100017510000002262412211371426014360 0ustar ptspts\/* * jpegdump_main.cpp -- dump a JPEG stream * by pts@math.bme.hu at Tue Jun 4 13:19:00 CEST 2002 */ /* Structure of a typical JPEG file: (D8:SOI) (E0:APP0) (FE:COM)? (DB:DQT)*2 (C0:SOF0) (C4:DHT)*4 (DA:SOS) ... (D9:EOI) */ #ifdef __GNUC__ #pragma implementation #endif #include "config2.h" #include #if OBJDEP #warning PROVIDES: jpegdump_main #endif typedef slen_t dimen_t; static const unsigned char CS_UNKNOWN=0, /* error/unspecified */ CS_GRAYSCALE=1, /* monochrome */ CS_RGB=2, /* red/green/blue */ CS_YCbCr=3, /* Y/Cb/Cr (also known as YUV) */ CS_CMYK=4, /* C/M/Y/K */ CS_YCCK=5, /* Y/Cb/Cr/K */ CS_Indexed_RGB=12; /* --- The following code is based on standard/image.c from PHP4 */ /* some defines for the different JPEG block types */ #define M_SOF0 0xC0 /* Start Of Frame N */ #define M_SOF1 0xC1 /* N indicates which compression process */ #define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ #define M_SOF3 0xC3 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ #define M_SOF6 0xC6 #define M_SOF7 0xC7 #define M_SOF9 0xC9 #define M_SOF10 0xCA #define M_SOF11 0xCB #define M_SOF13 0xCD #define M_SOF14 0xCE #define M_SOF15 0xCF #define M_SOI 0xD8 #define M_EOI 0xD9 /* End Of Image (end of datastream) */ #define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ #define M_COM 0xFE /* comment */ #define M_DQT 0xDB /* QuantTables */ #define M_DHT 0xC4 /* HuffTables */ #define M_APP0 0xe0 #define M_APP1 0xe1 #define M_APP2 0xe2 #define M_APP3 0xe3 #define M_APP4 0xe4 #define M_APP5 0xe5 #define M_APP6 0xe6 #define M_APP7 0xe7 #define M_APP8 0xe8 #define M_APP9 0xe9 #define M_APP10 0xea #define M_APP11 0xeb #define M_APP12 0xec #define M_APP13 0xed #define M_APP14 0xee #define M_APP15 0xef static unsigned short jai_read2(FILE *fp) { unsigned char a[ 2 ]; /* just return 0 if we hit the end-of-file */ if (fread(a,sizeof(a),1,fp) != 1) return 0; return (((unsigned short) a[ 0 ]) << 8) + ((unsigned short) a[ 1 ]); } static unsigned int jai_next_marker(FILE *fp) /* get next marker byte from file */ { int c; /* skip unimportant stuff */ c = MACRO_GETC(fp); while (c != 0xff) { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } /* get marker byte, swallowing possible padding */ do { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } while (c == 0xff); // printf("marker=%02X\n", c); return (unsigned int) c; } static void jai_skip_variable(FILE *fp) /* skip over a variable-length block; assumes proper length marker */ { unsigned short length; printf("%lu: skip variable\n", ftell(fp)); length = jai_read2(fp); length -= 2; /* length includes itself */ if (length>0) { printf("... variable length=%u\n", length); #if 0 fseek(fp, (long) length, SEEK_CUR); /* skip the header */ #endif while (length--!=0) MACRO_GETC(fp); /* make feof(fp) correct */ printf("%lu: skipped variable; feof=%u\n", ftell(fp), feof(fp)); } } struct gfxinfo { unsigned char bad, bpc, cpp, had_jfif, colortransform, id_rgb; dimen_t height, width; /** Offset of byte just _after_ the first SOF marker (FF C0 or alike) * from the beginning of the file. */ slen_t SOF_offs; }; /** main loop to parse JPEG structure */ static void jai_handle_jpeg(struct gfxinfo *result, FILE *fp) { unsigned int length, marker; unsigned char had_adobe, id, hvs, qtn; result->bad=1; /* signal invalid return value */ result->id_rgb=0; result->had_jfif=0; result->colortransform=127; /* no Adobe marker yet */ // fseek(fp, 0L, SEEK_SET); /* position file pointer on SOF */ if (MACRO_GETC(fp) != 0xFF || MACRO_GETC(fp)!=M_SOI) return; /* JPEG header... */ printf("2: marker D8 (SOI)\n"); for (;;) { assert(!feof(fp)); printf("... %lu\n", ftell(fp)); marker=jai_next_marker(fp); printf("%lu: marker %02X\n", ftell(fp), marker); switch (marker) { case M_SOF0: if (result->bad!=1) { result->bad=4; return; } /* only one M_SOF allowed */ result->SOF_offs=ftell(fp); /* handle SOFn block */ length=jai_read2(fp); result->bpc = MACRO_GETC(fp); result->height = jai_read2(fp); result->width = jai_read2(fp); result->cpp = MACRO_GETC(fp); if ((length-=8)!=3U*result->cpp) return; if (result->cpp==3) { result->id_rgb =(id=MACRO_GETC(fp)=='R'); hvs=MACRO_GETC(fp); qtn=MACRO_GETC(fp); printf("Comp#1 id=0x%02X h_samp_fact=%u v_samp_fact=%u quant_tbl_no=%u\n", id, hvs>>4, hvs&15, qtn); result->id_rgb&=(id=MACRO_GETC(fp)=='G'); hvs=MACRO_GETC(fp); qtn=MACRO_GETC(fp); printf("Comp#2 id=0x%02X h_samp_fact=%u v_samp_fact=%u quant_tbl_no=%u\n", id, hvs>>4, hvs&15, qtn); result->id_rgb&=(id=MACRO_GETC(fp)=='B'); hvs=MACRO_GETC(fp); qtn=MACRO_GETC(fp); printf("Comp#3 id=0x%02X h_samp_fact=%u v_samp_fact=%u quant_tbl_no=%u\n", id, hvs>>4, hvs&15, qtn); } else while (length--!=0) MACRO_GETC(fp); if (result->cpp!=1 && result->cpp!=3 && result->cpp!=4) { result->bad=5; return; } if (feof(fp)) { result->bad=8; return; } result->bad=2; break; case M_SOF1: case M_SOF2: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: // fprintf(stderr, "SOF%u\n", marker-M_SOF0); assert(0); result->bad=3; return; case M_SOS: /* we are about to hit image data. We're done. */ jai_skip_variable(fp); /* anything else isn't interesting */ if (feof(fp)) { result->bad=8; return; } if (result->bad==2 && !feof(fp)) result->bad=0; /* Dat: we should really return() here, because the SOS marker is * followed by binary data, not surrounded by markers. */ break; case M_EOI: /* end of image or EOF */ if (feof(fp)) result->bad=6; else if (MACRO_GETC(fp)!=EOF) result->bad=7; return; case M_APP0: /* JFIF application-specific marker */ length=jai_read2(fp); if (length==2+4+1+2+1+2+2+1+1) { result->had_jfif=MACRO_GETC(fp)=='J' && MACRO_GETC(fp)=='F' && MACRO_GETC(fp)=='I' && MACRO_GETC(fp)=='F' && MACRO_GETC(fp)==0; length-=7; } else length-=2; while (length--!=0) MACRO_GETC(fp); if (feof(fp)) { result->bad=8; return; } break; case M_APP14: /* Adobe application-specific marker */ length=jai_read2(fp); if ((length-=2)==5+2+2+2+1) { had_adobe=MACRO_GETC(fp)=='A' && MACRO_GETC(fp)=='d' && MACRO_GETC(fp)=='o' && MACRO_GETC(fp)=='b' && MACRO_GETC(fp)=='e' && ((unsigned char)MACRO_GETC(fp))>=1; MACRO_GETC(fp); MACRO_GETC(fp); MACRO_GETC(fp); MACRO_GETC(fp); MACRO_GETC(fp); if (had_adobe) result->colortransform=MACRO_GETC(fp); else MACRO_GETC(fp); } else while (length--!=0) MACRO_GETC(fp); if (feof(fp)) { result->bad=8; return; } break; case M_APP1: case M_APP2: case M_APP3: case M_APP4: case M_APP5: case M_APP6: case M_APP7: case M_APP8: case M_APP9: case M_APP10: case M_APP11: case M_APP12: case M_APP13: case M_APP15: /* fall through */ default: jai_skip_variable(fp); /* anything else isn't interesting */ if (feof(fp)) { result->bad=8; return; } break; } } } static char *jai_errors[]={ (char*)NULLP, /*1*/ "missing SOF0 marker", /*2*/ "EOF|EOI before SOS", /* "premature EOF", */ /*3*/ "not a Baseline JPEG (SOF must be SOF0)", /*4*/ "more SOF0 markers", /*5*/ "bad # components", /*6*/ "EOF before EOI", /*7*/ "extra bytes after EOI", /*8*/ "EOF before end of parametric marker", }; int main(int argc, char **argv) { struct gfxinfo gi; FILE *f=argc>=2 ? fopen(argv[1], "rb"): stdin; jai_handle_jpeg(&gi, f); if (gi.bad==1) { printf("JAI: Warning: %s.\n", jai_errors[gi.bad]); gi.cpp=1; gi.width=0; gi.height=0; gi.SOF_offs=0; gi.bpc=0; } else if (gi.bad!=0) { printf("JAI: %s.\n", jai_errors[gi.bad]); if (gi.bad!=1) return 1; } unsigned char colorspace; if (gi.cpp==1) { colorspace=CS_GRAYSCALE; } else if (gi.cpp==3) { colorspace=CS_YCbCr; if (gi.had_jfif!=0) ; else if (gi.colortransform==0) colorspace=CS_RGB; else if (gi.colortransform==1) ; else if (gi.colortransform!=127) { printf("JAI: unknown ColorTransform: %u\n", (unsigned)gi.colortransform); return 2; } else if (gi.id_rgb!=0) colorspace=CS_RGB; /* Imp: check for id_ycbcr */ else printf("JAI: assuming YCbCr color space\n"); } else if (gi.cpp==4) { colorspace=CS_CMYK; if (gi.colortransform==0) ; else if (gi.colortransform==2) colorspace=CS_YCCK; else if (gi.colortransform!=127) { printf("JAI: unknown ColorTransform: %u\n", (unsigned)gi.colortransform); return 2; } } else assert(0); fseek(f, 0L, 2); /* EOF */ long flen=ftell(f); /* skip extra bytes after EOI */ fclose(f); printf("%lu: flen\n", flen); printf("bpc=%u cpp=%u had_jfif=%u colortransform=%u id_rgb=%u colorspace=%u\n", gi.bpc, gi.cpp, gi.had_jfif, gi.colortransform, gi.id_rgb, colorspace); printf("wd=%u ht=%u SOF_offs=%u\n", gi.width, gi.height, gi.SOF_offs); return 0; } /* __EOF__ */ sam2p-0.49.2/sam2p_main.cpp0000644000175100017510000014626612212351433013575 0ustar ptspts/* sam2p_main.cpp * by pts@fazekas.hu at Fri Mar 15 16:11:03 CET 2002 */ #include "gensi.hpp" #include "gensio.hpp" #include "image.hpp" #include "error.hpp" #include "encoder.hpp" #include "minips.hpp" #include "rule.hpp" #include "main.hpp" #include "in_jai.hpp" #ifndef SAM2P_VERSION #include "sam2p_version.h" #endif /* Sat Jul 6 16:39:19 CEST 2002 * empirical checkerg++ helper routines for gcc version 2.95.2 20000220 (Debian GNU/Linux) * see c_lgcc.cpp for more */ #if !defined(OBJDEP) && defined(__CHECKER__) && !HAVE_PTS_C_LGCC_CPP_REQUIRED # include "c_lgcc.cpp" #endif #if 0 /*#ifdef __CHECKER__*/ #include void* __builtin_vec_new(unsigned len){ return malloc(len); } void __builtin_vec_delete(void *p) { free(p); } void* __builtin_new(unsigned len){ return malloc(len); } void __builtin_delete(void *p) { free(p); } void __rtti_user() { abort(); } void __rtti_si() { abort(); } void terminate() { abort(); } extern "C" void __pure_virtual(); void __pure_virtual() { abort(); } #endif #if OBJDEP # warning PROVIDES: sam2p_main # warning REQUIRES: gensi.o # warning REQUIRES: gensio.o # warning REQUIRES: image.o # warning REQUIRES: error.o # warning REQUIRES: encoder.o # warning REQUIRES: minips.o # warning REQUIRES: rule.o #endif #include #include /* memset() */ #if OBJDEP # warning REQUIRES: in_tiff.o # warning REQUIRES: in_jpeg.o # warning REQUIRES: in_png.o # warning REQUIRES: in_jai.o # warning REQUIRES: in_pcx.o # warning REQUIRES: in_xpm.o # warning REQUIRES: in_lbm.o # warning REQUIRES: in_gif.o # warning REQUIRES: in_bmp.o # warning REQUIRES: in_pnm.o # warning REQUIRES: in_tga.o /*# warning REQUIRES: in_pdf.o Dat: no more, integrated to in_ps.o */ # warning REQUIRES: in_ps.o #endif extern Image::Loader in_tiff_loader; extern Image::Loader in_jpeg_loader; extern Image::Loader in_png_loader; extern Image::Loader in_jai_loader; extern Image::Loader in_pcx_loader; extern Image::Loader in_xpm_loader; extern Image::Loader in_lbm_loader; extern Image::Loader in_gif_loader; extern Image::Loader in_bmp_loader; extern Image::Loader in_pnm_loader; extern Image::Loader in_tga_loader; extern Image::Loader in_pdf_loader; extern Image::Loader in_ps_loader; void init_loader() { static bool had_init_loader=false; if (had_init_loader) return; Image::register0(&in_tga_loader); /* checker not sure; install early */ Image::register0(&in_pcx_loader); Image::register0(&in_xpm_loader); Image::register0(&in_lbm_loader); Image::register0(&in_gif_loader); Image::register0(&in_bmp_loader); Image::register0(&in_pnm_loader); Image::register0(&in_tiff_loader); Image::register0(&in_jpeg_loader); Image::register0(&in_png_loader); Image::register0(&in_jai_loader); Image::register0(&in_pdf_loader); Image::register0(&in_ps_loader); had_init_loader=true; } #if OBJDEP # warning REQUIRES: appliers.o #endif extern Rule::Applier out_pnm_applier; extern Rule::Applier out_jpeg_applier; extern Rule::Applier out_jpegjai_applier; extern Rule::Applier out_tiffjai_applier; extern Rule::Applier out_tiff_applier; extern Rule::Applier out_png_applier; extern Rule::Applier out_bmp_applier; extern Rule::Applier out_gif89a_applier; extern Rule::Applier out_xpm_applier; extern Rule::Applier out_l1c_applier; // extern Rule::Applier out_l1op_applier; extern Rule::Applier out_l1tr_applier; extern Rule::Applier out_l23_applier; // extern Rule::Applier out_l1fa85g_applier; extern Rule::Applier out_l2jbin_applier; // extern Rule::Applier out_p0jbin_applier; extern Rule::Applier out_empty_applier; extern Rule::Applier out_meta_applier; extern Rule::Applier out_xwd_applier; extern Rule::Applier out_x11_applier; void init_applier() { static bool had_init_applier=false; if (had_init_applier) return; // Rule::register0(&out_l1op_applier); Rule::register0(&out_l1tr_applier); // Rule::register0(&out_l1fa85g_applier); Rule::register0(&out_l2jbin_applier); // Rule::register0(&out_p0jbin_applier); Rule::register0(&out_l23_applier); Rule::register0(&out_l1c_applier); Rule::register0(&out_xpm_applier); Rule::register0(&out_gif89a_applier); Rule::register0(&out_pnm_applier); Rule::register0(&out_jpeg_applier); Rule::register0(&out_jpegjai_applier); Rule::register0(&out_tiffjai_applier); Rule::register0(&out_tiff_applier); Rule::register0(&out_png_applier); Rule::register0(&out_bmp_applier); Rule::register0(&out_empty_applier); Rule::register0(&out_meta_applier); Rule::register0(&out_xwd_applier); Rule::register0(&out_x11_applier); had_init_applier=true; } static char bts_ttt[] = #include "bts2.tth" ; /* --- One-liner mode */ /** Dat: mod 16 does matter: expected # args etc. */ static const unsigned OPT_unknown=0, OPT_SampleFormat=0x02, OPT_LoadHints=0x12, OPT_Compression=0x22, OPT_TransferEncoding=0x32, OPT_TransferEncodingF=0x42, OPT_Asis=0x50, OPT_PSL1=0x60, OPT_PSLC=0x70, OPT_PSL2=0x80, OPT_PSL3=0x90, OPT_PS=0xA1, OPT_PDF=0xB1, OPT_DisplayJobFile=0xC1, OPT_Hints=0xD2, OPT_InputFile=0xE2, OPT_OutputFile=0xF2, OPT_Scale=0x101, OPT_Margins=0x112, OPT_Transparent=0x122, OPT_TmpRemove=0x132; /** @param s an option (lower/upper case intact), without leading `-'s * @param slen length of option * @return 0 if invalid/unsupported/unknown option * | 16*(k+1)+0 if the option never accepts parameters * | 16*(k+2)+1 if the option may or may not have a parameter * | 16*(k+3)+2 if the option must have a parameter */ static unsigned sam2p_optval(char const* s, slen_t slen) { if (slen==1) { switch (s[0]) { case 's': return OPT_SampleFormat; case 'l': return OPT_LoadHints; case 'h': return OPT_Hints; case 't': return OPT_TransferEncoding; case 'f': return OPT_TransferEncodingF; case 'c': return OPT_Compression; // case 'a': return OPT_Asis; /* disabled, automatic! */ case '1': return OPT_PSL1; case '2': return OPT_PSL2; case '3': return OPT_PSL3; case 'j': return OPT_DisplayJobFile; case 'o': case 'O': return OPT_OutputFile; case 'e': return OPT_Scale; case 'm': return OPT_Margins; } } else { slen_t len=slen; /* strlen(s); */ if (len>=32) return OPT_unknown; char buf[32]; GenBuffer::tolower_memcpy(buf, s, len); buf[len]='\0'; /* printf("buf=(%s)\n", buf); */ if (0==strcmp(buf, "sampleformat")) return OPT_SampleFormat; if (0==strcmp(buf, "loadhints")) return OPT_LoadHints; if (0==strcmp(buf, "tmpremove")) return OPT_TmpRemove; if (0==strcmp(buf, "transparent")) return OPT_Transparent; if (0==strcmp(buf, "hints")) return OPT_Hints; if (0==strcmp(buf, "ps") || 0==strcmp(buf, "eps")) return OPT_PS; if (0==strcmp(buf, "pdf")) return OPT_PDF; if (0==strcmp(buf, "1c")) return OPT_PSLC; if (0==strcmp(buf, "scale")) return OPT_Scale; if (0==strcmp(buf, "hints")) return OPT_Margins; } return OPT_unknown; } static void displayJob(GenBuffer::Writable &sout, SimBuffer::Flat const& jobss) { fflush(stdout); fflush(stderr); #if 0 puts("\n\n% begin sam2p job dump"); fwrite(stdout, 1, jobss.getLength(), jobss); puts("% end sam2p job dump\n"); #else /* vvv Dat: sout conflicts /OutputFile(-), but it is OK here */ sout << "\n% begin sam2p job dump\n" << jobss << "%)%)%)% end sam2p job dump\n\n"; #endif fflush(stdout); fflush(stderr); } static inline char const *protect_null(char const *s) { return s==(char const*)NULLP ? "//" : s; } /** @return the value for the parameter if matches key or the first letter of * key; or NULLP if no match. * @param key lower case */ static char const*one_pabbr(char const*param, char const *key) { return GenBuffer::nocase_strbegins(param, key) ? param+strlen(key) : (param[0]==key[0] || param[0]==key[0]+'A'-'a') && param[1]==':' ? param+2 : (char const*)NULLP; } #if 0 /* cannot set badp... */ static inline void one_setdimen2(char const*&Dimen1, char const*&Dimen2, char const*p2) { if (MiniPS::Real::isDimen(p2)) Dimen1=Dimen2=p2; else Error::sev(Error::ERROR_CONT) << "one_liner: dimen expected" /*<< (SimBuffer::B().appendDumpC(p2, true))*/ << (Error*)0; } #endif #if 0 #define one_setdimen2(Dimen1,Dimen2,p2) do { \ if (MiniPS::Real::isDimen(p2)) Dimen1=Dimen2=p2; \ else { badmsg="one_liner: dimen expected: "; goto bad_label; } \ } while(0) #endif static Filter::UngetFILED *ufd; static bool do_DisplayJobFile; static bool buildProfile_quiet=false; /** Creates an in-memory job file according to the command-line options. * @param a argv+1 * @param job initially an empty string. On error, this function leaves it * as-is, but on success, a valid job file is appened. * @return true on syntax error */ static bool one_liner(SimBuffer::B &jobss, char const *const* a) { /* Tue Jul 2 21:27:15 CEST 2002 */ char const *p, *pend; bool no_option_term=true; bool badp=false; bool no_selector=true; char const *badmsg; // SimBuffer::B Profile /* MiniPS code */ SimBuffer::B Hints; /* MiniPS code */ /* ^^^ Imp: separate hint for each -c arg?? */ SimBuffer::B LoadHints; bool TmpRemove_p=true; Rule::Cache::pr_t Predictor=Rule::Cache::PR_None; /* Imp: separate for each Compression */ Rule::Cache::ff_t FileFormat=Rule::Cache::FF_default; Rule::Cache::te_t TransferEncoding=Rule::Cache::TE_default; do_DisplayJobFile=false; bool do_stop_SampleFormat=false; char const *Transparent=(char const*)NULLP; /* change 1 color to transparent unless NULL */ char const *OutputFile=(char const*)NULLP, *InputFile=(char const*)NULLP; // SimBuffer::B tmp; char const *TopMargin=(char const*)NULLP, *BottomMargin=(char const*)NULLP, *LeftMargin=(char const*)NULLP, *RightMargin=(char const*)NULLP, *LowerMargin=(char const*)NULLP, *ImageDPI=(char const*)NULLP; bool negLowerMargin=false; Rule::CacheHints::sc_t Scale=Rule::CacheHints::SC_default; #define APPEND_sf(val) do { if (sfx[val]==0) { sfx[val]=1; sft[sflen++]=val; } } while (0) Image::sf_t sft[Image::SF_max+1]; char sfx[Image::SF_max+1]; memset(sfx, 0, sizeof(sfx)); unsigned sflen=0; #define APPEND_co(val) do { if (cox[val]==0) { cox[val]=1; cot[colen++]=val; } } while (0) Rule::Cache::co_t cot[Rule::Cache::CO_max+1]; char cox[Image::SF_max+1]; memset(cox, 0, sizeof(cox)); unsigned colen=0; /* ^^^ BUGFIX at 2002.12.02 */ /** OPT_* value of current option */ unsigned opt; /** Parameter for current option. May be NULL. */ char const *param=""; /* pacify VC6.0 */ char const *p2; slen_t paramlen; SimBuffer::B tmpnam; /* any dir -- keep on stack frame */ buildProfile_quiet=true; for (; (p=*a)!=(char const*)NULLP; a++) { if (p[0]=='-' && p[1]=='\0') { /* `-': Filename: STDIN or STDOUT */ #if 1 goto normal_label; #else Error::sev(Error::ERROR_CONT) << "one_liner: `-' (stdin|stdout) not allowed as filename" << (Error*)0; badp=true; continue; #endif } else if (p[0]=='-' && p[1]=='-' && p[2]=='\0') { /* `--': No more options */ if (a[1]==(char const*)NULLP && InputFile!=(char const*)NULLP) { /* `--' is last argument */ p=InputFile; /* OutputFile:=InputFile */ goto normal_label; } no_option_term=false; } else if (p[0]=='-' && no_option_term) { /* an option */ while (*p=='-') p++; /* short options (-p) and long options (--pdf) are equivalent */ pend=p; while (*pend!='\0' && *pend!=':' && *pend!='=') pend++; SimBuffer::Static optss(p, pend-p); if (0==(opt=sam2p_optval(p, pend-p))) { badmsg="one_liner: unknown option: "; bad_label: Error::sev(Error::ERROR_CONT) << badmsg << (SimBuffer::B().appendDumpC(optss, true)) << (Error*)0; badp=true; continue; } if ((opt&15)==0) { /* no parameters */ if (*pend!='\0') { badmsg="one_liner: don't give param to option: "; goto bad_label; } param=(char const*)NULLP; } else if ((opt&15)==1) { /* an optional parameter */ if (*pend!='\0') { param=pend+1; while (*pend==*param) param++; } else param=(char const*)NULLP; } else if ((opt&15)==2) { /* a mandatory parameter */ if (*pend!='\0') { param=pend+1; while (*pend==*param) param++; } else if ((param=*++a)==(char const*)NULLP) { badmsg="one_liner: missing param for option: "; goto bad_label; } } else assert(0); paramlen=param==(char const*)NULLP ? 0 : strlen(param); /* Dat: now opt, paramlen and param are correct */ switch (opt) { case OPT_LoadHints: LoadHints << ',' << param; break; case OPT_TmpRemove: TmpRemove_p=GenBuffer::parseBool(param, paramlen); break; case OPT_Transparent: Transparent=param; break; /* Imp: is this good memory management */ case OPT_Hints: Hints << '\n' << param; break; case OPT_PSL1: FileFormat=Rule::Cache::FF_PSL1; break; case OPT_PSLC: FileFormat=Rule::Cache::FF_PSLC; break; case OPT_PSL2: FileFormat=Rule::Cache::FF_PSL2; break; case OPT_PSL3: FileFormat=Rule::Cache::FF_PSL3; break; case OPT_DisplayJobFile: // fprintf(stderr, "param=(%s)\n", param); if (paramlen==0 || 0==GenBuffer::nocase_strcmp(param, "job")) do_DisplayJobFile=true; else if (0==GenBuffer::nocase_strcmp(param, "warn")) buildProfile_quiet=false; else if (GenBuffer::nocase_strbegins(param, "warn:")) buildProfile_quiet=!GenBuffer::parseBool(param+5, paramlen-5); else if (0==GenBuffer::nocase_strcmp(param, "quiet")) { buildProfile_quiet=true; Error::setTopPrinted(Error::ERROR_CONT); } /* Dat: hide warnings, info etc. */ /* at Fri Aug 26 07:54:00 CEST 2005 */ else if (GenBuffer::nocase_strbegins(param, "job:")) do_DisplayJobFile=GenBuffer::parseBool(param+4, paramlen-4); else do_DisplayJobFile=GenBuffer::parseBool(param, paramlen); /* Imp: better error report */ break; case OPT_Margins: /* Dat:abbreviation letters are distinct: [ahxvylrtubd] */ if (0!=(p2=one_pabbr(param,"all:"))) { all5: if (MiniPS::Real::isDimen(p2)) LeftMargin=RightMargin=TopMargin=BottomMargin=LowerMargin=p2; else { err_dimexp: badmsg="one_liner: dimen expected: "; goto bad_label; } } else if (0!=(p2=one_pabbr(param,"horiz:")) || 0!=(p2=one_pabbr(param,"x:"))) { if (MiniPS::Real::isDimen(p2)) LeftMargin=RightMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"vert:")) || 0!=(p2=one_pabbr(param,"y:"))) { if (MiniPS::Real::isDimen(p2)) TopMargin=BottomMargin=LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"left:"))) { if (MiniPS::Real::isDimen(p2)) LeftMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"right:"))) { if (MiniPS::Real::isDimen(p2)) RightMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"dpi:"))) { if (MiniPS::Real::isDimen(p2)) ImageDPI=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"top:")) || 0!=(p2=one_pabbr(param,"up:"))) { if (MiniPS::Real::isDimen(p2)) TopMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"bottom:")) || 0!=(p2=one_pabbr(param,"down:"))) { if (MiniPS::Real::isDimen(p2)) BottomMargin=LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"raise:"))) { if (MiniPS::Real::isDimen(p2)) LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"lower:"))) { negLowerMargin=true; if (MiniPS::Real::isDimen(p2)) LowerMargin=p2; else goto err_dimexp; } else { p2=param; goto all5; } break; case OPT_Scale: if (paramlen==0 || 0==GenBuffer::nocase_strcmp(param, "scale")) Scale=Rule::CacheHints::SC_OK; else if (0==GenBuffer::nocase_strcmp(param, "none")) Scale=Rule::CacheHints::SC_None; else if (0==GenBuffer::nocase_strcmp(param, "rot")) Scale=Rule::CacheHints::SC_RotateOK; else if (0==GenBuffer::nocase_strcmp(param, "rotate")) Scale=Rule::CacheHints::SC_RotateOK; else Scale=(Rule::CacheHints::sc_t)(GenBuffer::parseBool(param, paramlen) ? 0+Rule::CacheHints::SC_OK : 0+Rule::CacheHints::SC_None); /* ^^^ Imp: better error report */ /* ^^^ +0: pacify g++-3.1 */ break; case OPT_TransferEncoding: if (0==GenBuffer::nocase_strcmp(param, "bin")) TransferEncoding=Rule::Cache::TE_Binary; else if (0==GenBuffer::nocase_strcmp(param, "hex")) TransferEncoding=Rule::Cache::TE_Hex; else if (0==GenBuffer::nocase_strcmp(param, "a85")) TransferEncoding=Rule::Cache::TE_A85; else if (0==GenBuffer::nocase_strcmp(param, "ascii"))TransferEncoding=Rule::Cache::TE_ASCII; else if (0==GenBuffer::nocase_strcmp(param, "lsb1")) TransferEncoding=Rule::Cache::TE_LSBfirst; else if (0==GenBuffer::nocase_strcmp(param, "msb1")) TransferEncoding=Rule::Cache::TE_MSBfirst; else { inv_par: badmsg="one_liner: invalid param for option: "; goto bad_label; } break; case OPT_TransferEncodingF: if (0==GenBuffer::nocase_strcmp(param, "lsb2msb")) TransferEncoding=Rule::Cache::TE_LSBfirst; else if (0==GenBuffer::nocase_strcmp(param, "msb2lsb")) TransferEncoding=Rule::Cache::TE_MSBfirst; else goto inv_par; break; case OPT_PS: if (param==(char const*)NULLP || param[0]=='\0') FileFormat=Rule::Cache::FF_eps; else if (0==GenBuffer::nocase_strcmp(param, "1")) FileFormat=Rule::Cache::FF_PSL1; else if (0==GenBuffer::nocase_strcmp(param, "1c") || 0==GenBuffer::nocase_strcmp(param, "c")) FileFormat=Rule::Cache::FF_PSLC; else if (0==GenBuffer::nocase_strcmp(param, "2")) FileFormat=Rule::Cache::FF_PSL2; else if (0==GenBuffer::nocase_strcmp(param, "3")) FileFormat=Rule::Cache::FF_PSL3; else goto inv_par; break; case OPT_PDF: if (param==(char const*)NULLP || param[0]=='\0') FileFormat=Rule::Cache::FF_pdfb; else if (0==GenBuffer::nocase_strcmp(param, "b")) FileFormat=Rule::Cache::FF_pdfb; /* BI */ else if (0==GenBuffer::nocase_strcmp(param, "x")) FileFormat=Rule::Cache::FF_pdf; /* XObject */ else if (0==GenBuffer::nocase_strcmp(param, "b0")) FileFormat=Rule::Cache::FF_PDFB10; else if (0==GenBuffer::nocase_strcmp(param, "b2")) FileFormat=Rule::Cache::FF_PDFB12; else if (0==GenBuffer::nocase_strcmp(param, "0")) FileFormat=Rule::Cache::FF_PDF10; else if (0==GenBuffer::nocase_strcmp(param, "2")) FileFormat=Rule::Cache::FF_PDF12; else goto inv_par; break; case OPT_SampleFormat: pend=param; while (*pend!='\0') { while (*pend==':') pend++; if (do_stop_SampleFormat) goto inv_par; /* already stopped */ p=pend; while (*pend!='\0' && *pend!=':') pend++; paramlen=pend-p; if (4==paramlen && 0==memcmp(p,"stop",4)) { do_stop_SampleFormat=true; buildProfile_quiet=false; break; } if (5==paramlen && 0==memcmp(p,"stopq",5)) { do_stop_SampleFormat=true; break; } if (2==paramlen && 0==memcmp(p,"tr",2)) { APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Mask); APPEND_sf(Image::SF_Transparent2); APPEND_sf(Image::SF_Transparent4); APPEND_sf(Image::SF_Transparent8); } else { Image::sf_t sf=Rule::Cache::parseSampleFormat(p, paramlen); if (sf==Image::SF_max) goto inv_par; APPEND_sf(sf); } } break; case OPT_Compression: assert(param!=(char const*)NULLP); if (0==GenBuffer::nocase_strcmp(param, "none")) APPEND_co(Rule::Cache::CO_None); else if (0==GenBuffer::nocase_strcmp(param, "lzw")) APPEND_co(Rule::Cache::CO_LZW); else if (0==GenBuffer::nocase_strcmp(param, "zip")) APPEND_co(Rule::Cache::CO_ZIP); else if (0==GenBuffer::nocase_strcmp(param, "rle") || 0==GenBuffer::nocase_strcmp(param, "packbits")) APPEND_co(Rule::Cache::CO_RLE); else if (0==GenBuffer::nocase_strcmp(param, "dct")) { APPEND_co(Rule::Cache::CO_DCT); Hints << "\n/DCT<<>>"; } else if (0==GenBuffer::nocase_strcmp(param, "jpg") || 0==GenBuffer::nocase_strcmp(param, "jpeg")) { APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); } else if (0==GenBuffer::nocase_strcmp(param, "ijg")) APPEND_co(Rule::Cache::CO_IJG); else if (0==GenBuffer::nocase_strcmp(param, "g4")) { APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K -1"; } else if (0==GenBuffer::nocase_strcmp(param, "g3") || 0==GenBuffer::nocase_strcmp(param, "fax") || 0==GenBuffer::nocase_strcmp(param, "g3:1d"))APPEND_co(Rule::Cache::CO_Fax); else if (0==GenBuffer::nocase_strcmp(param, "g3:2d")){ APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K -2"; } else if (0==GenBuffer::nocase_strcmp(param, "jai")) APPEND_co(Rule::Cache::CO_JAI); else if (GenBuffer::nocase_strbegins(param, "lzw:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_LZW); Predictor=(Rule::Cache::pr_t)i; } else if (GenBuffer::nocase_strbegins(param, "rle:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_RLE); Hints << "\n/RecordSize " << i; } else if (GenBuffer::nocase_strbegins(param, "packbits:")) { SimBuffer::Static s(param+9); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_RLE); Hints << "\n/RecordSize " << i; } else if (GenBuffer::nocase_strbegins(param, "fax:")) { SimBuffer::Static s(param+4); long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K " << i; } else if (GenBuffer::nocase_strbegins(param, "dct:")) { APPEND_co(Rule::Cache::CO_DCT); Hints << "\n/DCT<< " << (param+4) << " >>"; } else if (GenBuffer::nocase_strbegins(param, "ijg:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_IJG); Hints << "\n/Quality " << i; } else if (GenBuffer::nocase_strbegins(param, "jpeg:")) { SimBuffer::Static s(param+5); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); Hints << "\n/Quality " << i; } else if (GenBuffer::nocase_strbegins(param, "zip:")) { pend=param+4; while (*pend!='\0' && *pend!=':') pend++; SimBuffer::Static s(param+4, pend-param-4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_ZIP); Predictor=(Rule::Cache::pr_t)i; if (*pend==':') { pend++; while (*pend==':') pend++; SimBuffer::Static s(pend); if (s.toInteger(i)) goto inv_par; // Error::sev(Error::FATAL) << "SUXX)" << s << ',' << i << '.' << (Error*)0; APPEND_co(Rule::Cache::CO_ZIP); Hints << "\n/Effort " << i; // Error::sev(Error::FATAL) << "SUXX(" << s << ',' << Hints << '.' << (Error*)0; } } else goto inv_par; break; default: assert(0); } } else { /* a selector or a normal argument */ if (!(no_selector && no_option_term)) goto normal_label; pend=p; while (*pend!='\0' && *pend!=':') pend++; if (pend-p>=2 && *pend==':') { /* an ImageMagick-style FileFormat selector */ if (GenBuffer::nocase_strbegins(p, "PSL2:") || GenBuffer::nocase_strbegins(p, "EPS2:")) FileFormat=Rule::Cache::FF_PSL2; else if (GenBuffer::nocase_strbegins(p, "EPS:")) FileFormat=Rule::Cache::FF_eps; else if (GenBuffer::nocase_strbegins(p, "PS2:")) { FileFormat=Rule::Cache::FF_PSL2; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (GenBuffer::nocase_strbegins(p, "PS:")) { FileFormat=Rule::Cache::FF_eps; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (GenBuffer::nocase_strbegins(p, "PSL1:")) FileFormat=Rule::Cache::FF_PSL1; else if (GenBuffer::nocase_strbegins(p, "PSLC:")) FileFormat=Rule::Cache::FF_PSLC; else if (GenBuffer::nocase_strbegins(p, "PSL3:")) FileFormat=Rule::Cache::FF_PSL3; else if (GenBuffer::nocase_strbegins(p, "PDF:") || GenBuffer::nocase_strbegins(p, "PDF:")) FileFormat=Rule::Cache::FF_pdfb; else if (GenBuffer::nocase_strbegins(p, "PDFX:")) FileFormat=Rule::Cache::FF_pdf; else if (GenBuffer::nocase_strbegins(p, "PDFB1.0:")) FileFormat=Rule::Cache::FF_PDFB10; else if (GenBuffer::nocase_strbegins(p, "PDFB1.2:")) FileFormat=Rule::Cache::FF_PDFB12; else if (GenBuffer::nocase_strbegins(p, "PDF1.0:")) FileFormat=Rule::Cache::FF_PDF10; else if (GenBuffer::nocase_strbegins(p, "PDF1.2:")) FileFormat=Rule::Cache::FF_PDF12; else if (GenBuffer::nocase_strbegins(p, "GIF89a:") || GenBuffer::nocase_strbegins(p, "GIF:")) FileFormat=Rule::Cache::FF_GIF89a; /* vvv do_stop_SampleFormat BUGFIX at Thu Nov 21 23:44:20 CET 2002 */ else if (GenBuffer::nocase_strbegins(p, "PNM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PBM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PGM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PPM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Rgb8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PAM:")) FileFormat=Rule::Cache::FF_PAM; else if (GenBuffer::nocase_strbegins(p, "PIP:")) FileFormat=Rule::Cache::FF_PIP; else if (GenBuffer::nocase_strbegins(p, "Empty:"))FileFormat=Rule::Cache::FF_Empty; else if (GenBuffer::nocase_strbegins(p, "Meta:")) FileFormat=Rule::Cache::FF_Meta; else if (GenBuffer::nocase_strbegins(p, "JPEG:") || GenBuffer::nocase_strbegins(p, "JPG:")) FileFormat=Rule::Cache::FF_JPEG; else if (GenBuffer::nocase_strbegins(p, "TIFF:") || GenBuffer::nocase_strbegins(p, "TIF:")) FileFormat=Rule::Cache::FF_TIFF; else if (GenBuffer::nocase_strbegins(p, "PNG:")) FileFormat=Rule::Cache::FF_PNG; else if (GenBuffer::nocase_strbegins(p, "XPM:")) FileFormat=Rule::Cache::FF_XPM; else if (GenBuffer::nocase_strbegins(p, "BMP:") || GenBuffer::nocase_strbegins(p, "RLE:")) { FileFormat=Rule::Cache::FF_BMP; /*APPEND_co(Rule::Cache::CO_RLE);*/ } else if (GenBuffer::nocase_strbegins(p, "XWD:")) FileFormat=Rule::Cache::FF_XWD; else if (GenBuffer::nocase_strbegins(p, "X11:")) FileFormat=Rule::Cache::FF_X11; else { Error::sev(Error::ERROR_CONT) << "one_liner: invalid FileFormat selector: " << (SimBuffer::B().appendDumpC(SimBuffer::Static(p, pend-p), true)) << (Error*)0; badp=true; continue; } no_selector=false; while (*pend==':') pend++; if (*pend=='\0') continue; /* this arg is just a selector */ /* normal argument is coming */ p=pend; } normal_label: if (InputFile==(char const*)NULLP) { InputFile=p; /* set it even on error */ /* vvv since Sat Apr 19 13:37:57 CEST 2003: * Possibly unseekable STDIN is handled by Filter::UngetFILED */ #if 0 if (p[0]=='-' && p[1]=='\0') { /* Filename: STDIN */ Files::set_binary_mode(0, true); if (0!=fseek(stdin, 0L, 0)) { unseekable: #if 0 Error::sev(Error::ERROR_CONT) << "one_liner: `-' (stdin) not allowed as InputFile (stdin unseekable)" << (Error*)0; badp=true; continue; #endif FILE *f=Files::open_tmpnam(tmpnam); if (!f) { Error::sev(Error::ERROR_CONT) << "one_liner: cannot open" << " temporary file for `-' (stdin)" << (Error*)0; badp=true; continue; } tmpnam.term0(); Files::tmpRemoveCleanup(InputFile=tmpnam()); char *buf=new char[4096]; unsigned got; while ( (0<(got=fread(buf, 1, sizeof(buf), stdin))) && got==fwrite(buf, 1, sizeof(buf), f)) {} delete [] buf; if (ferror(f) || 0!=fclose(f) || ferror(stdin)) { Error::sev(Error::ERROR_CONT) << "one_liner: cannot write" << " temporary file for `-' (stdin)" << (Error*)0; badp=true; continue; } // fprintf(stderr, "if=(%s)\n", InputFile); continue; /* Imp: report `-' as filename on errors etc. */ } int c=MACRO_GETC(stdin); if (0!=fseek(stdin, 0L, 0)) { if (c>=0) ungetc(c, stdin); goto unseekable; } /* active test */ /* ungetc() is not necessary because of fseek() */ } #endif } else if (OutputFile==(char const*)NULLP) { /* Filename: STDOUT */ Files::set_binary_mode(1, true); OutputFile=p; if (FileFormat==Rule::Cache::FF_default) { /* OutputFile; determine FileFormat from extension */ pend=p+strlen(p); while (pend!=p && *pend!='.') pend--; /* ^^^ Dat: extra care later for /a/b.c/d */ if (pend!=p) { /* have extension */ assert(*pend=='.'); pend++; if (0==GenBuffer::nocase_strcmp(pend, "eps") || 0==GenBuffer::nocase_strcmp(pend, "epsi") || 0==GenBuffer::nocase_strcmp(pend, "epsf")) FileFormat=Rule::Cache::FF_eps; else if (0==GenBuffer::nocase_strcmp(pend, "ps")) { FileFormat=Rule::Cache::FF_eps; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (0==GenBuffer::nocase_strcmp(pend, "pdf")) FileFormat=Rule::Cache::FF_pdfb; else if (0==GenBuffer::nocase_strcmp(pend, "gif")) FileFormat=Rule::Cache::FF_GIF89a; else if (0==GenBuffer::nocase_strcmp(pend, "pnm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pbm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pgm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "ppm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Rgb8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pam")) FileFormat=Rule::Cache::FF_PAM; else if (0==GenBuffer::nocase_strcmp(pend, "pip")) FileFormat=Rule::Cache::FF_PIP; else if (0==GenBuffer::nocase_strcmp(pend, "empty"))FileFormat=Rule::Cache::FF_Empty; else if (0==GenBuffer::nocase_strcmp(pend, "meta")) FileFormat=Rule::Cache::FF_Meta; else if (0==GenBuffer::nocase_strcmp(pend, "jpeg") || 0==GenBuffer::nocase_strcmp(pend, "jpg")) FileFormat=Rule::Cache::FF_JPEG; else if (0==GenBuffer::nocase_strcmp(pend, "tiff") || 0==GenBuffer::nocase_strcmp(pend, "tif")) FileFormat=Rule::Cache::FF_TIFF; else if (0==GenBuffer::nocase_strcmp(pend, "png")) FileFormat=Rule::Cache::FF_PNG; else if (0==GenBuffer::nocase_strcmp(pend, "xpm")) FileFormat=Rule::Cache::FF_XPM; else if (0==GenBuffer::nocase_strcmp(pend, "bmp") || 0==GenBuffer::nocase_strcmp(pend, "rle")) { FileFormat=Rule::Cache::FF_BMP; /*APPEND_co(Rule::Cache::CO_RLE);*/ } else if (0==GenBuffer::nocase_strcmp(pend, "xwd")) FileFormat=Rule::Cache::FF_XWD; // else if (0==GenBuffer::nocase_strcmp(pend, "x11")) FileFormat=Rule::Cache::FF_X11; /* ^^^ .x11 extension is useless */ } } } else { Error::sev(Error::ERROR_CONT) << "one_liner: got too many (>2) filenames" << (Error*)0; badp=true; continue; } } /* IF */ } /* NEXT */ if (InputFile==(char const*)NULLP) { Error::sev(Error::ERROR_CONT) << "one_liner: InputFile unspecified" << (Error*)0; badp=true; } if (OutputFile==(char const*)NULLP) { Error::sev(Error::ERROR_CONT) << "one_liner: OutputFile unspecified" << (Error*)0; badp=true; } if (FileFormat==Rule::Cache::FF_default) { Error::sev(Error::ERROR_CONT) << "one_liner: FileFormat unspecified" << (Error*)0; badp=true; } if (badp) return true; int prcc = (colen==0) ? 2 : 1; if (colen==0) { /* apply default if Compression is unspecified */ // Error::sev(Error::FATAL) << "FileFormat=" << (unsigned)FileFormat << (Error*)0; switch (FileFormat) { case Rule::Cache::FF_TIFF: case Rule::Cache::FF_eps: case Rule::Cache::FF_PSL2: case Rule::Cache::FF_PDFB10: case Rule::Cache::FF_PDF10: APPEND_co(Rule::Cache::CO_JAI); #if HAVE_LZW APPEND_co(Rule::Cache::CO_LZW); #endif APPEND_co(Rule::Cache::CO_RLE); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_BMP: case Rule::Cache::FF_PSL1: case Rule::Cache::FF_PSLC: /* assert(0); */ APPEND_co(Rule::Cache::CO_RLE); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_PSL3: case Rule::Cache::FF_pdfb: /* BUGFIX at Sun Sep 22 14:57:03 CEST 2002 */ case Rule::Cache::FF_pdf: case Rule::Cache::FF_PDFB12: case Rule::Cache::FF_PDF12: APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_ZIP); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_GIF89a: APPEND_co(Rule::Cache::CO_LZW); /* _not_ /LZWEncode filter */ APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_JPEG: APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); break; case Rule::Cache::FF_PNG: APPEND_co(Rule::Cache::CO_ZIP); break; default: APPEND_co(Rule::Cache::CO_None); break; /* for others FileFormats: CO_None, but that is _not_ appended anyway */ } } else { if ((int)Predictor == 55 || (int)Predictor == 45) { Error::sev(Error::WARNING) << "predictor: /Predictor " << (int)Predictor << " is inefficient; use /Predictor 15 instead" << (Error*)0; } } /* Dat: don't append /Compression/None if the user has specified `-c'. The * user can append `-c none' manually. */ if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_None; if (TransferEncoding==Rule::Cache::TE_default) { /* apply default if TransferEncoding is unspecified */ switch (FileFormat) { case Rule::Cache::FF_PSL1: case Rule::Cache::FF_PSLC: TransferEncoding=(Rule::Cache::te_t)(cox[Rule::Cache::CO_ZIP]!=0 || cox[Rule::Cache::CO_LZW]!=0 ? 0+Rule::Cache::TE_A85 : 0+Rule::Cache::TE_Hex); break; /* ^^^ Dat: /Hex is default for /RLE */ case Rule::Cache::FF_eps: case Rule::Cache::FF_PSL2: case Rule::Cache::FF_PSL3: TransferEncoding=Rule::Cache::TE_A85; break; #if 0 /* useless bugfix */ case Rule::Cache::FF_XPM: /* BUGFIX at Thu Jul 11 21:53:56 CEST 2002 */ // assert(0); TransferEncoding=Rule::Cache::TE_ASCII; break; #endif default: TransferEncoding=Rule::Cache::TE_Binary; break; } } unsigned coc=colen; /* Smart verify whether /Compression/JAI is requested. If so, and the input * file is JPEG, then load it as-is. Our heuristic is that if the user * allowed /Compression/JAI among others, and the input file is a baseline * JPEG, then /Compression/JAI will be the best (and only) compression * method. */ bool jaip=cox[Rule::Cache::CO_JAI]!=0; if (jaip) { if (ufd==NULLP) ufd=new Filter::UngetFILED(InputFile, stdin, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); /* vvv Imp: no error handling */ if (1!=jai_is_baseline_jpeg(ufd)) { jaip=false; coc--; cox[Rule::Cache::CO_JAI]=0; } ufd->seek(0); #if 0 assert(ufd->vi_getcc()==255); assert(ufd->vi_getcc()==0xd8); assert(ufd->vi_getcc()==255+0); assert(0); #endif } if (jaip) { /* Dat: might have changed to false */ APPEND_sf(Image::SF_Asis); LoadHints << ",jpeg-asis,"; cot[0]=Rule::Cache::CO_JAI; colen=1; /* disable all other compression */ } else if (coc==1 && cox[Rule::Cache::CO_Fax]!=0) { APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Indexed1); APPEND_sf(Image::SF_Mask); } else if (coc==1 && (cox[Rule::Cache::CO_DCT]!=0 || cox[Rule::Cache::CO_IJG]!=0)) { APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); } else if (!do_stop_SampleFormat) { /* JAI compression is automatically disabled since jaip==false */ /* Guess SampleFormat automatically. The order is significant, so most * warnings emitted by Image::SampledInfo::setSampleFormat() are avoided. */ APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Indexed1); APPEND_sf(Image::SF_Mask); APPEND_sf(Image::SF_Gray2); APPEND_sf(Image::SF_Indexed2); APPEND_sf(Image::SF_Rgb1); APPEND_sf(Image::SF_Gray4); APPEND_sf(Image::SF_Indexed4); APPEND_sf(Image::SF_Rgb2); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Indexed8); APPEND_sf(Image::SF_Rgb4); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent2); /* transparents are put last because of expensive color separation */ APPEND_sf(Image::SF_Transparent4); APPEND_sf(Image::SF_Transparent8); } /* Append more Hints */ if (Scale!=Rule::CacheHints::SC_None) Hints << "\n/Scale /" << protect_null(Rule::CacheHints::dumpScale(Scale)); if ((char const*)NULLP!=ImageDPI) Hints << "\n/ImageDPI " << ImageDPI; if ((char const*)NULLP!=LeftMargin) Hints << "\n/LeftMargin " << LeftMargin; if ((char const*)NULLP!=RightMargin) Hints << "\n/RightMargin " << RightMargin; if ((char const*)NULLP!=TopMargin) Hints << "\n/TopMargin " << TopMargin; if ((char const*)NULLP!=BottomMargin) Hints << "\n/BottomMargin " << BottomMargin; if ((char const*)NULLP!=LowerMargin) { Hints << "\n/LowerMargin "; if (negLowerMargin) { if (LowerMargin[0]=='-') Hints << (LowerMargin+1); else Hints << '-' << LowerMargin; } else Hints << LowerMargin; } /* Emit job file */ jobss << "<<%sam2p in-memory job file, autogenerated by " << Error::banner0 << "\n/InputFile "; jobss.appendDumpPS(SimBuffer::Static(InputFile), true); jobss << "\n/OutputFile "; jobss.appendDumpPS(SimBuffer::Static(OutputFile), true); jobss << "\n/LoadHints "; jobss.appendDumpPS(LoadHints, true); jobss << "\n/TmpRemove " << (TmpRemove_p ? "true" : "false"); jobss << "\n/Profile[\n"; unsigned coi, sfi; slen_t orc=0; int prc; bool is_predictor_recommended; for (sfi=0;sfi0; --prc) { /* Add an extra predictor only for LZW or ZIP, appropriate SampleFormat * and if the `-c' command line option was not specified. * So if the user specifies `-c zip', he won't get a predictor by * default; but if he specifies no `-c', he might get a `-c:zip:15'. * To get the smallest file size, he should specify `-c zip:15:9'. * * The value we assign to is_predictor_recommended comes from the * do_filter = ... assignment in png_write_IHDR() in pngwutil.c of * libpng-1.2.15 . */ is_predictor_recommended = ( sf==Image::SF_Gray8 || sf==Image::SF_Rgb8); if (prc>1 && ((co!=Rule::Cache::CO_LZW && co!=Rule::Cache::CO_ZIP) || !is_predictor_recommended)) continue; jobss << "<<% OutputRule #" << orc++ << "\n /FileFormat /" << protect_null(Rule::Cache::dumpFileFormat(FileFormat, co)) << "\n /TransferEncoding /" << protect_null(Rule::Cache::dumpTransferEncoding(TransferEncoding)) << "\n /SampleFormat /" << protect_null(Rule::Cache::dumpSampleFormat(sf)) << "\n /Compression /" << protect_null(Rule::Cache::dumpCompression (co)) << "\n /Predictor " << (int)(co==Rule::Cache::CO_LZW || co==Rule::Cache::CO_ZIP ? /* If no compression (or predictor) specified, try predictor 15, then 1; otherwise try the specified predictor */ /* +0 down there to avoid linking problems with g++ on Mac OS X 10.5.6 */ (prc>1 ? Rule::Cache::PR_PNGAuto+0 : Predictor != Rule::Cache::PR_PNGAutoMaybe ? Predictor : is_predictor_recommended ? Rule::Cache::PR_PNGAuto+0 : Rule::Cache::PR_None+0) : Rule::Cache::PR_None+0) << "\n /Hints << " << Hints << " >>"; // jobss << " /Transparent (\377\377\377)\n"; if (Transparent!=NULL) { jobss << "\n /Transparent "; jobss.appendDumpPS(SimBuffer::Static(Transparent), true); } jobss << "\n>>\n"; } } } jobss << "]>>% __EOF__\n"; /* Common keys not emited here: * /TmpRemove true /Templates pop * /ColorTransform pop * /EncoderColumns 0 /EncoderBPL 0 /EncoderRows 0 /EncoderColors 0 * /PredictorColumns 0 /PredictorBPC 0 /PredictorColors 0 * /Transparent null * /WarningOK true * /Comment pop * /Title pop * /Subject pop * /Author pop * /Creator pop * /Producer pop * /Created pop * /Produced pop */ return false; #undef APPEND_sf #undef APPEND_co } /* one_liner() */ static bool option_eq(char const *arg, char const*option) { if (option[0]=='-') { option++; while (arg[0]=='-') arg++; } return 0==GenBuffer::nocase_strcmp(arg, option); } void init_sam2p_engine(char const*argv0) { Error::long_argv0=argv0==(char const*)NULLP ? "sam2p" : argv0; Error::argv0=Files::only_fext(Error::long_argv0); Error::tmpargv0="_sam2p_"; Error::banner0="sam2p " SAM2P_VERSION; } /* --- */ /* Never returns. */ int run_sam2p_engine(Files::FILEW &sout, Files::FILEW &serr, char const*const*argv1, bool helpp) { class SerrResetter { public: SerrResetter(GenBuffer::Writable *old_serr_): old_serr(old_serr_) {} ~SerrResetter() { Error::serr = old_serr; } private: GenBuffer::Writable *old_serr; } serr_resetter(Error::serr); Error::serr=&serr; /* --- Parse arguments, generate/read .job file */ MiniPS::VALUE job=MiniPS::Qundef; Filter::FlatD bts(bts_ttt); ufd=(Filter::UngetFILED*)NULLP; if (!helpp && argv1[0]!=(char const*)NULLP && argv1[1]==(char const*)NULLP) { /* A single argument: must be the name of the .job file */ MiniPS::Parser p(argv1[0]); p.addSpecRun("%bts", &bts); /* bts: Built-in TemplateS, the bts.ttt file in the sources */ job=p.parse1(); if (p.parse1(p.EOF_ALLOWED)!=MiniPS::Qundef) Error::sev(Error::EERROR) << "job: the .job file should contain a single job" << (Error*)0; /* ^^^ Dat: the result of the second p.parse1() doesn't get delete0(...)d */ } else if (helpp || argv1[0]==(char const*)NULLP) { help: /* help message */ sout << "Usage: " << Error::long_argv0 << " \n" << " " << Error::long_argv0 << " [options] [OutputFormat:] \n" << "Example: " << Error::long_argv0 << " test.gif EPS: test.eps\n"; if (helpp) Error::cexit(Error::runCleanups(0)); Error::sev(Error::EERROR) << "Incorrect command line" << (Error*)0; } else { /* one_liner */ SimBuffer::B jobss; if (one_liner(jobss, argv1)) goto help; if (do_DisplayJobFile) displayJob(sout, jobss); Filter::FlatD jobr(jobss(), jobss.getLength()); MiniPS::Parser p(&jobr); p.addSpecRun("%bts", &bts); /* bts: Built-in TemplateS, the bts.ttt file in the sources */ if (MiniPS::Qerror==(job=p.parse1(p.EOF_ILLEGAL, Error::ERROR_CONT)) || p.parse1(p.EOF_ALLOWED)!=MiniPS::Qundef ) { displayJob(sout, jobss); Error::sev(Error::EERROR) << "job: in-memory .job file corrupt (bug?" "?)" << (Error*)0; /* ^^^ Dat: the result of the second p.parse1() doesn't get delete0(...)d */ } } Files::doSignalCleanup(); /* --- Pre-parse .job file */ /* Dat: memory storage for the MiniPS objects in the .job file are * allocated by p.parse1() and freed by MiniPS::delete0(job). Other * structures throughout this program hold pointers to inside `job', * but storage is not copied. */ MiniPS::String *InputFile, *OutputFile, *LoadHints; MiniPS::Array *Profile; MiniPS::VALUE TmpRemove; MiniPS::scanf_dict(job, /*show_warnings:*/true, "InputFile", MiniPS::T_STRING, MiniPS::Qundef, &InputFile, "OutputFile", MiniPS::T_STRING, MiniPS::Qundef, &OutputFile, "LoadHints", MiniPS::T_STRING, MiniPS::Qnull, &LoadHints, "Templates", MiniPS::T_DICT, MiniPS::Qnull, &Rule::Templates, "Profile", MiniPS::T_ARRAY, MiniPS::Qundef, &Profile, "TmpRemove", MiniPS::T_BOOLEAN,MiniPS::Qtrue, &TmpRemove, /* remove temporary files upon exit? */ NULLP ); // MiniPS::dump(sout, job, 1); Files::tmpRemove=TmpRemove==MiniPS::Qtrue; if (MiniPS::Qnull==(MiniPS::VALUE)Rule::Templates) { Filter::FlatD flatd("<< (%bts) run >>"); MiniPS::Parser p(&flatd); p.addSpecRun("%bts", &bts); Rule::Templates=(MiniPS::Dict*)p.parse1(); MiniPS::RDICT(job)->put("/Templates", (MiniPS::VALUE)Rule::Templates); /* avoid memory leak (job gets freed recursively) */ } /* --- Preprocess Appliers */ Rule::OutputRule *rule_list=Rule::buildProfile((MiniPS::VALUE)Profile, buildProfile_quiet); /* --- Read/open other files */ if ((MiniPS::VALUE)LoadHints==MiniPS::Qnull) { /* smart default */ if (!rule_list[0].isEOL() && rule_list[0].cache.Compression==Rule::Cache::CO_JAI) { LoadHints=new MiniPS::String("jpeg-asis",4); /* used by in_jai.cpp and in_jpeg.cpp; even TIFF/JPEG */ } else { LoadHints=new MiniPS::String("",0); } MiniPS::RDICT(job)->put("/LoadHints", (MiniPS::VALUE)LoadHints); /* avoid memory leak (job gets freed recursively) */ } /* Imp: eliminate memory leak from default LoadHints */ /* vvv may raise tons of error messages */ // InputFile->term0(); /* always term0() for MiniPS::String */ if (ufd==NULLP) ufd=new Filter::UngetFILED(InputFile->begin_(), stdin, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); // fprintf(stderr, "ufd=%p\n", ufd); Image::SampledInfo info(Image::load( #if 0 InputFile->begin_(), /* knows about stdin `-' */ SimBuffer::B(",",1, LoadHints->begin_(),LoadHints->getLength(), ",",1 ).term0() /* three-way concatentation */ #else (Image::Loader::UFD*)ufd, SimBuffer::B(",",1, LoadHints->begin_(),LoadHints->getLength(), ",",1 ).term0(), /* three-way concatentation */ /*format:*/(char const*)NULLP #endif )); Error::sev(Error::NOTICE) << "job: read InputFile: " << FNQ2STDOK(InputFile->begin_(),InputFile->getLength()) << (Error*)0; delete ufd; // assert(0); bool overwrite=false; if (0==strcmp(InputFile->begin_(), OutputFile->begin_()) && 0!=strcmp("-", InputFile->begin_())) { // Error::sev(Error::WARNING) << "job: InputFile == OutputFile" << (Error*)0; OutputFile->replace(OutputFile->begin_(), OutputFile->getLength(), ".s2new", 6); overwrite=true; } FILE *of=stdout; if (OutputFile->getLength()!=1 || OutputFile->begin_()[0]!='-') { if ((of=fopen(OutputFile->begin_(), "wb"))==(FILE*)NULLP) { Error::sev(Error::EERROR) << "job: cannot rewrite OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; } /*if (!overwrite)*/ Files::tmpRemoveCleanup(OutputFile->begin_(), &of); } else Files::set_binary_mode(1, true); /* --- Find and apply best applier */ Files::FILEW wf(of); Rule::applyProfile(wf, rule_list, &info); /* --- Done, flush files and clean up. */ fflush(of); if (ferror(of)) { /* FILE *backup=of; of=(FILE*)NULLP; fclose(backup); */ Error::sev(Error::EERROR) << "job: error writing OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; } if (of!=stdout) { /* Don't interfere with tmpRemoveCleanup() */ FILE *backup=of; of=(FILE*)NULLP; fclose(backup); } if (overwrite) { if (0!=rename(OutputFile->begin_(), InputFile->begin_())) { // remove(OutputFile->begin_()); /* tmpRemoveCleanup() does it */ Error::sev(Error::EERROR) << "job: error renaming, InputFile left intact" << (Error*)0; } } Error::sev(Error::NOTICE) << "job: written OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; /* Freeing memory may cause segfaults because of possibly * bad code design :-(. Luckily we have already saved the output file. */ Rule::deleteProfile(rule_list); MiniPS::delete0(job); /* frees OutputFile etc. */ bool successp = Error::getTopPrinted()+0<=Error::NOTICE+0; int exitCode = Error::runCleanups(0); fflush(stdout); fflush(stderr); if (successp && exitCode == 0) fputs("Success.\n", stderr); /* Don't do Error::cexit(exitCode);, it won't run destructors of * stack-allocated objects, and valgrind will complain about memory leaks. */ return exitCode; } /** main: process entry point for the sam2p utility. */ int main(int, char const*const* argv) { Files::FILEW sout(stdout); Files::FILEW serr(stderr); /* --- Initialize */ bool helpp=argv[0]==(char const*)NULLP || (argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && argv[2]==(char const*)NULLP && ( option_eq(argv[1], "-help") || option_eq(argv[1], "-h") || option_eq(argv[1], "-?") || option_eq(argv[1], "/h") || option_eq(argv[1], "/?"))); bool versionp=argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && argv[2]==(char const*)NULLP && ( option_eq(argv[1], "-version") || option_eq(argv[1], "-v")); bool quietp=argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && option_eq(argv[1], "-j:quiet"); init_sam2p_engine(argv[0]); if (versionp) { sout << "This is " << Error::banner0 << ".\n"; return 0; } /* Don't print diagnostics to stdout, becuse it might be the OutputFile */ if (!quietp) { serr << "This is " << Error::banner0 << ".\n"; } init_loader(); if (!quietp) { serr << "Available Loaders:"; Image::printLoaders(serr); serr << ".\n"; } init_applier(); if (!quietp) { serr << "Available Appliers:"; Rule::printAppliers(serr); serr << ".\n"; } return run_sam2p_engine( sout, serr, argv+(argv[0]!=(char const*)NULLP), helpp); } sam2p-0.49.2/test_main.cpp0000644000175100017510000002764512211371426013534 0ustar ptspts/* test_main.cpp * by pts@fazekas.hu at Sun Feb 24 16:24:38 CET 2002 */ #include "gensi.hpp" #include "gensio.hpp" #include "image.hpp" #include "error.hpp" #include "encoder.hpp" #include "minips.hpp" #include "mapping.hpp" #if OBJDEP # warning PROVIDES: test_main # warning REQUIRES: gensi.o # warning REQUIRES: gensio.o # warning REQUIRES: image.o # warning REQUIRES: error.o # warning REQUIRES: encoder.o # warning REQUIRES: minips.o # warning REQUIRES: mapping.o #endif #include #include #include Files::FILEW sout(stdout); #if OBJDEP # warning REQUIRES: in_xpm.o # warning REQUIRES: in_lbm.o # warning REQUIRES: in_gif.o # warning REQUIRES: in_bmp.o # warning REQUIRES: in_pnm.o # warning REQUIRES: in_tga.o #endif extern Image::Loader in_xpm_loader; extern Image::Loader in_lbm_loader; extern Image::Loader in_gif_loader; extern Image::Loader in_bmp_loader; extern Image::Loader in_pnm_loader; extern Image::Loader in_tga_loader; static void init_loader() { Image::register0(&in_tga_loader); /* checker not sure; install early */ Image::register0(&in_xpm_loader); Image::register0(&in_lbm_loader); Image::register0(&in_gif_loader); Image::register0(&in_bmp_loader); Image::register0(&in_pnm_loader); sout << "Available Loaders:"; Image::printLoaders(sout); sout << ".\n"; } static void test_data() { int i; SimBuffer::Static world("World!"); SimBuffer::Static("-1984").toInteger(i); sout << "Hello," << ' ' << world << '\n' << i << " luftballons.\n" << -99U << " negatives.\n"; sout << (world >= "FooBar") << '\n'; /// true { bool b=true; SimBuffer::Linked sli; sli << (world>"Zorba"); sli.toBool(b); sout << b << '\n'; /// false } SimBuffer::Linked li, lj("LJ"); li << "answer is: " << 42L << '\n'; li.prepend("The X", 4); lj << "uff."; lj=li; lj.prepend("D.A said: ",10); sout << li; /// The answer is 42 sout << lj; /// D.A said: The answer is 42 { Buffer b="Hello!\n"; /* <= 8 chars */ sout << b; } { Buffer b="Hello, World!\n"; /* > 8 chars */ sout << b; } { sout << "Hello,"+Buffer(" World2!\n"); } { Buffer b; b.format("Hello,%cWorld %d%s", ' ', -42, "!\n"); sout << b; } { Buffer b; b.format("123456789012\n"); sout << b; } { Buffer b; b.format("1234567890123\n"); sout << b; } { Buffer b; b.format("12345678901234\n"); sout << b; } { Buffer b; b.format("123456789012345\n"); sout << b; } { Buffer b; b.format("1234567890123456\n"); sout << b; } { Buffer b; b.format("1234567890%u\n",123456789L); sout << b; } { Buffer b("Hello, World!\n"); memcpy(b.substr_grow(7,5,3), "Bar", 3); sout << b; } { Buffer b("Hello, World!\n"); memcpy(b.substr_grow(7,5,6), "FooBar", 6); sout << b; } { Buffer b("Hello, World!\n"); memcpy(b.substr_grow(7,15,8), "FooBar!\n", 8); sout << b; } { Buffer b("Hello, World!"); memcpy(b.substr_grow(17,15,8), "HowDYD?\n", 8); sout << b; } { Buffer b="bena"; Buffer c; c=(SimBuffer::Flat)b; } sout << "Done.\n"; } #if OBJDEP # warning REQUIRES: image.o #endif static void test_image() { // Image::Sampled *img=Image::load("at-logo.xpm"); // Image::Sampled *img=Image::load("pts.xpm"); // Image::Sampled *img=Image::load("tex5.xpm"); // Image::Sampled *img=Image::load("at-logo.lbm"); // Image::Sampled *img=Image::load("ptest.lbm"); // Image::Sampled *img=Image::load("chessbrd.lbm"); // Image::Sampled *img=Image::load("at-logo.gif"); // Image::Sampled *img=Image::load("ptsbanner.gif"); // Image::Sampled *img=Image::load("ptsbanner.bmp"); // Image::Sampled *img=Image::load("pts.bmp"); // Image::Sampled *img=Image::load("t.cpp"); // Image::Sampled *img=Image::load("ptsbanner.tga"); // Image::Sampled *img=Image::load("mixing.xpm"); Image::Sampled *img=Image::load("mixing0.xpm", SimBuffer::B()); Files::FILEW f(fopen("t.ppm","wb")); /* Imp: autoclose... */ Image::Sampled *bak=img; img=img->toIndexed(); if (bak!=img) delete bak; assert(img->getTy()==img->TY_INDEXED); sout << "ncol0=" << PTS_dynamic_cast(Image::Indexed*,img)->getNcols() << '\n'; PTS_dynamic_cast(Image::Indexed*,img)->packPal(); sout << "ncols=" << PTS_dynamic_cast(Image::Indexed*,img)->getNcols() << '\n'; PTS_dynamic_cast(Image::Indexed*,img)->setBpc(0); sout << "bpc=" << (int)img->getBpc() << '\n'; // Files::tmpRemoveCleanup("t.dump"); // Files::tmpRemoveCleanup("t.dump"); /* twice: OK */ /* Files::tmpRemoveCleanup("/bin"); */ Files::FILEW f2(fopen("t.dump","wb")); PTS_dynamic_cast(Image::Indexed*,img)->dumpDebug(f2); f2.close(); f << *img; f.close(); // delete img; } static void test_encoder() { // Files::tmpRemove=false; /* Imp: make this a command-line option */ { Filter::FILEE a("t.a85"); PSEncoder *bp=PSEncoder::newASCII85Encode(a,78); // FlateEncode c(b,5); // LZWEncode c(b); // PipeEncode c(b,"gs -dNODISPLAY -q -c '/i(%stdin)(r)file def/o(%stdout)(w)file/LZWEncode filter def/s 4096 string def{i s readstring exch o exch writestring not{exit}if}loop o closefile quit'"); // GSEncode c(b,"xFlateEncode"); // PSEncoder *cp=PSEncoder::newLZWEncode(*bp); #if 1 PSEncoder *cp=PSEncoder::newRunLengthEncode(*bp); // delete [] cp; exit(0); /* Cannot free a GSEncode with multiple inheritance :-(( -> SegFault. virtual inheritance SUXX */ // PSEncoder *cp=PSEncoder::newRunLengthEncode(a); // FILE *fin=fopen("t55","rb"); FILE *fin=fopen("t.dump","rb"); // FILE *fin=fopen("t.xin","rb"); static char mybuf[2033]; unsigned long sum=0; while (1) { unsigned size=fread(mybuf, 1, sizeof(mybuf), fin); if (size<1) { fprintf(stderr,"nosiz=%u\n",size); cp->vi_write(0,0); break; } fprintf(stderr, "sending size=%u ofs=%lu\n", size, sum); sum+=size; cp->vi_write(mybuf, size); } assert(feof(fin)); assert(!ferror(fin)); fprintf(stderr, "ftell=%lu\n", ftell(fin)); fclose(fin); #else img->to8(); //img->setBpc(0); //sout << "bpc2=" << (int)img->getBpc() << '\n'; //Files::FILEW f2(fopen("t.dump2","wb")); //PTS_dynamic_cast(Image::Indexed*,img)->dumpDebug(f2); //f2.close(); PSEncoder *cp=PSEncoder::newDCTEncode(*bp, img->getWd(), img->getHt(), 1); cp->vi_write(img->getRowbeg(), img->getWd()*img->getHt()); cp->vi_write(0,0); #endif delete cp; delete bp; } } static void test_predictor() { /* by pts@fazekas.hu at Tue Mar 12 10:51:27 CET 2002 */ Image::SampledInfo info(Image::load("mixing1.xpm", SimBuffer::B())); info.setSampleFormat(Image::SF_Indexed2, false, false, 0x1000000L); Image::Sampled *img=info.getImg(); /* Imp: test predictors with rgb-4 */ unsigned char pred=11; Files::FILEW f2(fopen("predictor_gen.eps","wb")); f2 << "%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 " << img->getWd() << ' ' << img->getHt() << "\n%%EndComments\n" << "% `*image' forces grayscale :-(\nsave 99 dict begin\n" "{[ /Indexed /DeviceRGB " << ((img->getRowbeg()-img->getHeadp())/3-1) << " currentfile " << (img->getRowbeg()-img->getHeadp()) << " string readstring pop ] setcolorspace\n" "/f currentfile <getWd() << " /Colors " << (unsigned)img->getCpp() << " /BitsPerComponent " << (unsigned)img->getBpc() << ">> /FlateDecode filter def\n" // "/f currentfile /FlateDecode filter def\n" << img->getWd() << ' ' << img->getHt() << ' ' << (unsigned)img->getBpc() << "[1 0 0 -1 0 " << img->getHt() << "]f image\nf closefile}\n" "%%BeginData:\nexec\n"; f2.vi_write(img->getHeadp(), img->getRowbeg()-img->getHeadp()); /* Write palette */ PSEncoder *bp=PSEncoder::newFlateEncode(f2); // Encoder *cp=Encoder::newTIFFPredictor2(*bp, img->getBpc(), img->getWd(), img->getCpp()); // Encoder *cp=Encoder::newPNGPredictor11(*bp, img->getBpc(), img->getWd(), img->getCpp()); Encoder *cp=PSEncoder::newPredictor(*bp, pred, img->getBpc(), img->getWd(), img->getCpp()); cp->vi_write(img->getRowbeg(), img->getRlen()*img->getHt()); cp->vi_write(0,0); f2 << "\n%%EndData\nend\nrestore showpage\n%%Trailer\n%%EOF\n"; f2.close(); /* destructor of info frees all memory */ } static void test_dump() { MiniPS::VALUE e=(MiniPS::VALUE)new MiniPS::Dict(); MiniPS::VALUE d=(MiniPS::VALUE)new MiniPS::Dict(); MiniPS::VALUE a=(MiniPS::VALUE)new MiniPS::Array(); MiniPS::RARRAY(a)->push(MiniPS::Qinteger(3)); MiniPS::VALUE b=(MiniPS::VALUE)new MiniPS::Array(); MiniPS::RARRAY(b)->push(MiniPS::Qinteger(4)); MiniPS::RARRAY(b)->push(MiniPS::Qinteger(5)); MiniPS::RARRAY(b)->push(MiniPS::Qinteger(6)); MiniPS::RARRAY(b)->push((MiniPS::VALUE)new MiniPS::String("Hel\tna \n\n\n\n\n\n\n",15)); #if 0 MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/alma",5), MiniPS::Qinteger(42)); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/korte",6), MiniPS::Qnull); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/szilva",7), MiniPS::Qtrue); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/narancs",8), MiniPS::Qfalse); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/naranc2",8), (MiniPS::VALUE)new MiniPS::Array()); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/naranc3",8), a); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/naranc4",8), b); MiniPS::RDICT(d)->push((MiniPS::VALUE)new MiniPS::Sname("/naranc5",8), e); #else MiniPS::RDICT(d)->push("/alma",5, MiniPS::Qinteger(42)); MiniPS::RDICT(d)->push("/korte",6, MiniPS::Qnull); MiniPS::RDICT(d)->push("/szilva",7, MiniPS::Qtrue); MiniPS::RDICT(d)->push("/narancs",8, MiniPS::Qfalse); MiniPS::RDICT(d)->push("/naranc2",8, (MiniPS::VALUE)new MiniPS::Array()); MiniPS::RDICT(d)->push("/naranc3",8, a); MiniPS::RDICT(d)->push("/naranc4",8, b); MiniPS::RDICT(d)->push("/naranc5",8, e); #endif MiniPS::dump(sout, d); MiniPS::delete0(d); } static void test_tokenizer() { Files::FILER sin(stdin); MiniPS::Tokenizer pst(sin); int i; while ((i=pst.yylex())!=pst.EOFF) { putchar(i); putchar('\n'); } } static void test_parser() { { MiniPS::Parser p("-"); /* STDIN */ MiniPS::VALUE d=p.parse1(); MiniPS::dump(sout, d); MiniPS::delete0(d); } } static void test_hash() { {Mapping::H h(6); h.set("alma",4,"apple"); printf("alma=%s.\n", h.get("alma",4)); printf("korte=%s.\n", h.get("korte",5)); h.set("korte",5,"bear_"); printf("alma=%s.\n", h.get("alma",4)); printf("kort=%s.\n", h.get("korte",4)); printf("korte=%s.\n", h.get("korte",5)); } /* Dat: this might take a long time to run */ /* Imp: srand, but that would make the test less predictable */ char tmp[2]; unsigned i, j; Mapping::H h(sizeof(tmp)); for (i=0; i<10000000; i++) { // printf("%u\n", i); for (j=0; j=0) { putchar(':'); putchar(i); if (i!=(*p>='A' && *p<='Z'?*p+'a'-'A':*p)) abort(); p++; } pd.vi_read(0,0); /* Dat: the destructors do their jobs; freeing is not necessary */ } int main(int argc, char **argv) { (void)argc; (void)argv; Error::argv0=argc>=1 ? argv[0] : "test_main"; /* Imp: update this */ Error::tmpargv0="test_main"; Files::tmpRemove=0; init_loader(); test_data(); test_hash(); test_decoder(); // test_image(); // Needs file and more refactoring. // test_encoder(); // Needs file. test_dump(); // test_parser(); // Needs stdin. // test_tokenizer(); // Needs stdin. // test_predictor(); // Needs file and more refactoring. sout << "Success (test_main).\n"; fflush(stdout); Error::cexit(Error::runCleanups(0)); assert(0); return 0; /*notreached*/ } sam2p-0.49.2/testfax_main.c0000644000175100017510000001032212211371426013653 0ustar ptspts/* * testfax_main.c -- CCITTFax(En|De)code usage sample * by pts@fazekas.hu at Sat Jul 6 20:03:35 CEST 2002 * Sun Jul 7 22:25:55 CEST 2002 * * Note that this sample is incomplete since the parameters (such as /K) * cannot be set from the command line. */ #include "pts_fax.h" #include #include #include #include #ifdef __GNUC__ #pragma implementation #endif #if OBJDEP # warning PROVIDES: testfax_main #endif static void* gsfax_xalloc(unsigned n) { void *ret; if ((ret=malloc(n))==0) abort(); return ret; } static void gsfax_free(void *ptr) { free(ptr); } static void gsfax_memset(void *s, int c, unsigned n) { /*return*/ memset(s,c,n); } static void gsfax_memcpy(void *dest, const void *src, unsigned n) { /*return*/ memcpy(dest, src, n); } #if 0 CCITTFaxEncode: bool Uncompressed=false; int K=0; bool EndOfLine=false; bool EncodedByteAlign=false; int Columns=1728; int Rows=0; // Decode only bool EndOfBlock=true; bool BlackIs1=false; int DamagedRowsBeforeError=0; // Decode only bool FirstBitLowOrder=false; // GS only int DecodedByteAlign=1; // GS only bool CloseSource; bool CloseTarget; #endif /* GS expected * min_left=0 * bits_left=32 * */ static void work(FILE *f, stream_template const*template_, stream_state *state) { unsigned got, pog; stream_cursor_read r; stream_cursor_write w; unsigned char rbuf[4096], wbuf[1000], *hard, *rlimit; bool last; #if __CHECKER__ memset(&r, 0, sizeof(r)); memset(&w, 0, sizeof(w)); #endif template_->init(state); r.ptr=rlimit=rbuf-1; hard=rbuf+sizeof(rbuf)-1; assert(hard-r.ptr>=(int)template_->min_in_size); last=false; while (1) { assert(r.ptr==rbuf-1); if (last==false) { if (0==(got=fread(rlimit+1, 1, hard-rlimit, f))) last=true; rlimit+=got; } /* if (r.ptr==rlimit) break; */ w.ptr=wbuf-1; w.limit=wbuf+sizeof(wbuf)-1; assert(w.limit-w.ptr>=(int)template_->min_out_size); r.limit=rlimit; pog=template_->process(state, &r, &w, last); fprintf(stderr, "pog=%d write=%d last=%d\n", pog, w.ptr-(wbuf-1), last); if ((int)pog==PTSFAX_ERRC) { fprintf(stderr, "syntax error!\n"); abort(); } /* assert(last || r.ptr>=rbuf); */ fwrite(wbuf, 1, w.ptr-(wbuf-1), stdout); if (last && (pog==0 || (int)pog==PTSFAX_EOFC)) break; if (r.ptr!=rbuf-1) { fprintf(stderr, "limit=%d\n", rlimit-r.ptr); memmove(rbuf, r.ptr+1, rlimit-r.ptr); rlimit=rbuf-1+(rlimit-r.ptr); r.ptr=rbuf-1; } } template_->release(state); } int main(int argc, char **argv) { FILE *f; (void)argc; (void)argv; /* -* Define a limit on the Rows parameter, close to max_int. *- #define cf_max_height 32000 if (code >= 0 && (state.K < -cf_max_height || state.K > cf_max_height || state.Columns < 0 || state.Columns > cfe_max_width || state.Rows < 0 || state.Rows > cf_max_height || state.DamagedRowsBeforeError < 0 || state.DamagedRowsBeforeError > cf_max_height || state.DecodedByteAlign < 1 || state.DecodedByteAlign > 16 || (state.DecodedByteAlign & (state.DecodedByteAlign - 1)) != 0) ) */ f=stdin; /* f=fopen("stdpre.x","rb"); */ /* f=fopen("216","rb"); */ assert(f!=0); if (0) { #if USE_BUILTIN_FAXE #if OBJDEP # warning REQUIRES: pts_faxe #endif } else if (argc==2 && 0==strcmp(argv[1], "encode")) { stream_CFE_state sCFEs; sCFEs.memset_=gsfax_memset; sCFEs.xalloc_=gsfax_xalloc; sCFEs.free_=gsfax_free; sCFEs.memcpy_=gsfax_memcpy; s_CFE_template.set_defaults((stream_state*)&sCFEs); /* sCFEs.K=-1; ... */ work(f, (stream_template const*)&s_CFE_template, (stream_state*)&sCFEs); #endif #if USE_BUILTIN_FAXD #if OBJDEP # warning REQUIRES: pts_faxd #endif } else if (argc==2 && 0==strcmp(argv[1], "decode")) { stream_CFD_state sCFDs; sCFDs.memset_=gsfax_memset; sCFDs.xalloc_=gsfax_xalloc; sCFDs.free_=gsfax_free; sCFDs.memcpy_=gsfax_memcpy; s_CFD_template.set_defaults((stream_state*)&sCFDs); /* sCFEs.K=-1; ... */ work(f, (stream_template const*)&s_CFD_template, (stream_state*)&sCFDs); #endif } else { fprintf(stderr, "Usage: %s encode|decode OUTFILE\n", argv[0]); return 2; } fclose(f); return 0; } sam2p-0.49.2/snprintf.h0000644000175100017510000000132312211371426013042 0ustar ptspts/* * snprintf.h -- interface for our fixup vsnprintf() etc. functions */ #ifndef SNPRINTF_H #define SNPRINTF_H 1 #ifdef __GNUC__ #pragma interface #endif #include "config2.h" #include /* ... */ #ifndef __cplusplus # define EXTERN_C extern #else # define EXTERN_C extern "C" #endif EXTERN_C slen_t fixup_vsnprintf(char *str, slen_t count, PTS_const char *fmt, va_list args); EXTERN_C slen_t fixup_snprintf(char *str,slen_t count,PTS_const char *fmt,...); EXTERN_C slen_t fixup_vasprintf(char **ptr, PTS_const char *format, va_list ap); EXTERN_C slen_t fixup_asprintf(char **ptr, PTS_const char *format, ...); EXTERN_C slen_t fixup_sprintf(char *ptr, PTS_const char *format, ...); #endif /* snprintf.h */ sam2p-0.49.2/snprintf.c0000644000175100017510000005647412211371426013056 0ustar ptspts/* * snprintf.c * ripped from rsync sources by pts@inf.bme.hu at Thu Mar 7 18:16:00 CET 2002 * ripped from reTCP sources by pts@fazekas.hu at Tue Jun 11 14:47:01 CEST 2002 * * Why does this .c file rock? * * -- minimal dependencies: only is included * -- minimal dependencies: not even -lm is required * -- can print floating point numbers * -- can print `long long' and `long double' * -- C99 semantics (NULL arg for vsnprintf OK, always returns the length * that would have been printed) * -- provides all vsnprintf(), snprintf(), vasprintf(), asprintf() */ /**** pts: sam2p-specific defines ****/ #include "snprintf.h" /* #include -- from snprintf.h */ #define P_CONST PTS_const #ifdef NULL /* as on Mac OS/X 10.5.7 */ # undef NULL #endif #define NULL ((void*)0) #ifdef __cplusplus # define malloc ::operator new #else # include /* malloc() */ #endif #define size_t slen_t /* normally defined in */ #define sizeret_t slen_t /* normally: int, unsigned */ #undef HAVE_LONG_DOUBLE #undef HAVE_LONG_LONG #undef HAVE_C99_VSNPRINTF /* force local implementation */ #undef HAVE_ASPRINTF #undef HAVE_VASPRINTF #undef TEST_SNPRINTF #undef DEBUG_SNPRINTF #define NEED_SPRINTF 1 #define vsnprintf fixup_vsnprintf #define snprintf fixup_snprintf #define vasprintf fixup_vasprintf #define asprintf fixup_asprintf #define sprintf fixup_sprintf typedef slen_t ret_t; /* vvv repeat prototypes in snprintf.h */ EXTERN_C sizeret_t fixup_vsnprintf(char *str, size_t count, P_CONST char *fmt, va_list args); EXTERN_C sizeret_t fixup_snprintf(char *str,size_t count,P_CONST char *fmt,...); EXTERN_C sizeret_t fixup_vasprintf(char **ptr, P_CONST char *format, va_list ap); EXTERN_C sizeret_t fixup_asprintf(char **ptr, P_CONST char *format, ...); EXTERN_C sizeret_t fixup_sprintf(char *ptr, P_CONST char *format, ...); /* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * It may be used for any purpose as long as this notice remains intact * on all source code distributions */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formated the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Andrew Tridgell (tridge@samba.org) Oct 1998 * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * * tridge@samba.org, idra@samba.org, April 2001 * got rid of fcvt code (twas buggy and made testing harder) * added C99 semantics * **************************************************************/ #if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) /* only include stdio.h if we are not re-defining snprintf or vsnprintf */ #include /* make the compiler happy with an empty file */ void dummy_snprintf(void) {} #else #if HAVE_LONG_DOUBLE && NEED_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif #if HAVE_LONG_LONG && NEED_LONG_LONG #define LLONG long long #else #define LLONG long #endif static size_t dopr(char *buffer, size_t maxlen, P_CONST char *format, va_list args); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); /* * dopr(): poor man's version of doprintf */ /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 #define char_to_int(p) ((p)- '0') #ifndef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif /**** pts ****/ #undef isdigit #define isdigit(c) ((unsigned char)((c)-'0')<=(unsigned char)('9'-'0')) static size_t dopr(char *buffer, size_t maxlen, P_CONST char *format, va_list args) { char ch; LLONG value; LDOUBLE fvalue; char *strvalue; int min; int max; int state; int flags; int cflags; size_t currlen; state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { if (ch == '\0') state = DP_S_DONE; switch(state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; else dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int (ch); ch = *format++; } else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; } else { state = DP_S_DOT; } break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else { state = DP_S_MOD; } break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; } else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; } else { state = DP_S_MOD; } break; case DP_S_MOD: switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': cflags = DP_C_LONG; ch = *format++; if (ch == 'l') { /* It's a long long */ cflags = DP_C_LLONG; ch = *format++; } break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) value = va_arg (args, int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); else if (cflags == DP_C_LLONG) value = va_arg (args, LLONG); else value = va_arg (args, int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (long)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); /* um, floating point? */ fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'c': dopr_outch (buffer, &currlen, maxlen, (char)va_arg (args, int)); break; case 's': strvalue = va_arg (args, char *); if (max == -1) { /**** pts ****/ for (max = 0; strvalue[max]; ++max); /* strlen */ } if (min > 0 && max >= 0 && min > max) max = min; fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); break; case 'p': strvalue = (char*)(va_arg (args, void *)); fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = (long int)currlen; } else if (cflags == DP_C_LLONG) { LLONG *num; num = va_arg (args, LLONG *); *num = (LLONG)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; case '%': dopr_outch (buffer, &currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } if (maxlen != 0) { if (currlen < maxlen - 1) buffer[currlen] = '\0'; else if (maxlen > 0) buffer[maxlen - 1] = '\0'; } return currlen; } static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; #ifdef DEBUG_SNPRINTF printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); #endif if (value == 0) { value = (char*)""; } for (strln = 0; value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) { int signvalue = 0; unsigned long uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if( value < 0 ) { signvalue = '-'; uvalue = -value; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); } while(uvalue && (place < 20)); if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch (buffer, currlen, maxlen, (char)signvalue); /* pacify VC6.0 */ /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch (buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++spadlen; } } static LDOUBLE abs_val(LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE POW10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static LLONG ROUND(LDOUBLE value) { LLONG intpart; intpart = (LLONG)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } /* a replacement for modf that doesn't need the math library. Should be portable, but slow */ static double my_modf(double x0, double *iptr) { int i; long l=0; double x = x0; double f = 1.0; for (i=0;i<100;i++) { l = (long)x; if (l <= (x+1) && l >= (x-1)) break; x *= 0.1; f *= 10.0; } if (i == 100) { /* yikes! the number is beyond what we can handle. What do we do? */ (*iptr) = 0; return 0; } if (i != 0) { double i2; double ret; ret = my_modf(x0-l*f, &i2); (*iptr) = l*f + i2; return ret; } (*iptr) = l; return x - (*iptr); } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; char iconvert[311]; char fconvert[311]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; int index; double intpart; double fracpart; double temp; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) { signvalue = '-'; } else { if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else { if (flags & DP_F_SPACE) signvalue = ' '; } } #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif #if 0 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ #endif /* * Sorry, we only support 16 digits past the decimal because of our * conversion method */ if (max > 16) max = 16; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ temp = ufvalue; my_modf(temp, &intpart); fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); if (fracpart >= POW10(max)) { intpart++; fracpart -= POW10(max); } /* Convert integer part */ do { temp = intpart; my_modf(intpart*0.1, &intpart); temp = temp*0.1; index = (int) ((temp -intpart +0.05)* 10.0); /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ /* printf ("%llf, %f, %x\n", temp, intpart, index); */ iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while (intpart && (iplace < 311)); if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ if (fracpart) { do { temp = fracpart; my_modf(fracpart*0.1, &fracpart); temp = temp*0.1; index = (int) ((temp -fracpart +0.05)* 10.0); /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */ /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */ fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while(fracpart && (fplace < 311)); if (fplace == 311) fplace--; } fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch (buffer, currlen, maxlen, (char)signvalue); --padlen; signvalue = 0; } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) dopr_outch (buffer, currlen, maxlen, (char)signvalue); while (iplace > 0) dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch (buffer, currlen, maxlen, '.'); while (fplace > 0) dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { if (*currlen < maxlen) { buffer[(*currlen)] = c; } (*currlen)++; } #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) sizeret_t vsnprintf (char *str, size_t count, P_CONST char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) sizeret_t snprintf(char *str,size_t count,P_CONST char *fmt,...) { size_t ret; va_list ap; PTS_va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } #endif #endif #ifndef HAVE_VASPRINTF sizeret_t vasprintf(char **ptr, P_CONST char *format, va_list ap) { size_t ret; ret = vsnprintf((char*)NULL, 0, format, ap); if (ret+1 <= 1) return ret; /* pts: bit of old unsigned trick... */ if (NULLP==(*ptr = (char *)malloc(ret+1))) return (sizeret_t)-1; ret = vsnprintf(*ptr, ret+1, format, ap); return ret; } #endif #ifndef HAVE_ASPRINTF sizeret_t asprintf(char **ptr, P_CONST char *format, ...) { va_list ap; sizeret_t ret; PTS_va_start(ap, format); ret = vasprintf(ptr, format, ap); va_end(ap); return ret; } #endif /**** pts ****/ #ifdef NEED_SPRINTF sizeret_t sprintf(char *ptr, P_CONST char *format, ...) { va_list ap; sizeret_t ret; PTS_va_start(ap, format); #if 0 ret = vsnprintf(NULL, 0, format, ap); if (ret+1 <= 1) return ret; ret = vsnprintf(ptr, ret, format, ap); #else ret = vsnprintf(ptr, (slen_t)-1, format, ap); #endif va_end(ap); return ret; } #endif #ifdef TEST_SNPRINTF sizeret_t sprintf(char *str,P_CONST char *fmt,...); int main (void) { char buf1[1024]; char buf2[1024]; char *fp_fmt[] = { "%1.1f", "%-1.5f", "%1.5f", "%123.9f", "%10.5f", "% 10.5f", "%+22.9f", "%+4.9f", "%01.3f", "%4f", "%3.1f", "%3.2f", "%.0f", "%f", "-16.16f", NULL }; double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 0}; char *int_fmt[] = { "%-1.5d", "%1.5d", "%123.9d", "%5.5d", "%10.5d", "% 10.5d", "%+22.33d", "%01.3d", "%4d", "%d", NULL }; long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; char *str_fmt[] = { "10.5s", "5.10s", "10.1s", "0.10s", "10.0s", "1.10s", "%s", "%.1s", "%.10s", "%10s", NULL }; char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; int x, y; int fail = 0; int num = 0; printf ("Testing snprintf format codes against system sprintf...\n"); for (x = 0; fp_fmt[x] ; x++) { for (y = 0; fp_nums[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]); int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); sprintf (buf2, fp_fmt[x], fp_nums[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", fp_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]); fail++; } num++; } } for (x = 0; int_fmt[x] ; x++) { for (y = 0; int_nums[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]); int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); sprintf (buf2, int_fmt[x], int_nums[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", int_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]); fail++; } num++; } } for (x = 0; str_fmt[x] ; x++) { for (y = 0; str_vals[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]); int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); sprintf (buf2, str_fmt[x], str_vals[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", str_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]); fail++; } num++; } } printf ("%d tests failed out of %d.\n", fail, num); printf("seeing how many digits we support\n"); { double v0 = 0.12345678901234567890123456789012345678901; for (x=0; x<100; x++) { snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x)); sprintf(buf2, "%1.1f", v0*pow(10, x)); if (strcmp(buf1, buf2)) { printf("we seem to support %d digits\n", x-1); break; } } } return 0; } #endif /* SNPRINTF_TEST */ sam2p-0.49.2/pts_fax.c0000644000175100017510000023602212211371426012644 0ustar ptspts/* * pts_fax.c -- a compact CCITTFax compressor and uncompressor) implementation * compiled by pts@fazekas.hu at Sun Jul 7 19:51:42 CEST 2002 * * algorithm ripped from GNU Ghostscript, implementation and (C): * Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. GNU Ghostscript is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. GNU Ghostscript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program so you can know your rights and responsibilities. It should be in a file named doc/COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. */ #include "pts_fax.h" #if 0 /* doesn't work in C++ */ # define intern static # define impl static # define intern_const static const # define impl_const static const #else # define intern static # define impl static # define intern_const extern const # define impl_const const #endif /* #define cxxintern extern */ #ifdef __GNUC__ #pragma implementation #endif /* misc_types.h by pts@fazekas.hu at Sat Jul 6 19:20:17 CEST 2002 */ #ifndef MISC_TYPES_H #define MISC_TYPES_H 1 /* #include "config2.h" */ #define BEGIN do { #define END } while (0) #ifndef DO_NOTHING # define DO_NOTHING BEGIN END #endif # define if_debug0(c,s) DO_NOTHING # define if_debug1(c,s,a1) DO_NOTHING # define if_debug2(c,s,a1,a2) DO_NOTHING # define if_debug3(c,s,a1,a2,a3) DO_NOTHING # define if_debug4(c,s,a1,a2,a3,a4) DO_NOTHING # define if_debug5(c,s,a1,a2,a3,a4,a5) DO_NOTHING # define if_debug6(c,s,a1,a2,a3,a4,a5,a6) DO_NOTHING # define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7) DO_NOTHING # define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8) DO_NOTHING # define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9) DO_NOTHING # define if_debug10(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) DO_NOTHING # define if_debug11(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) DO_NOTHING # define if_debug12(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) DO_NOTHING /* to the one that all the compilers seem to have.... */ #ifndef min # define min(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef max # define max(a, b) (((a) > (b)) ? (a) : (b)) #endif /* Define a standard way to round values to a (constant) modulus. */ #define ROUND_DOWN(value, modulus)\ ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\ (value) - (value) % (modulus) :\ (value) & -(modulus) ) #define ROUND_UP(value, modulus)\ ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\ ((value) + ((modulus) - 1)) / (modulus) * (modulus) :\ ((value) + ((modulus) - 1)) & -(modulus) ) #define countof(a) (sizeof(a) / sizeof((a)[0])) #define gs_alloc_bytes(a, n, c) ss->xalloc_(n) #define gs_free_object(a, ptr, c) ss->free_(ptr) #endif /* gstypes.h */ /* end of former misc_types.h */ /* gsbittab.h */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Interface to tables for bit operations */ #ifndef gsbittab_INCLUDED # define gsbittab_INCLUDED /* * Generate tables for transforming 2, 4, 6, or 8 bits. */ #define btab2_(v0,v2,v1)\ v0,v1+v0,v2+v0,v2+v1+v0 #define bit_table_2(v0,v2,v1) btab2_(v0,v2,v1) #define btab4_(v0,v8,v4,v2,v1)\ btab2_(v0,v2,v1), btab2_(v4+v0,v2,v1),\ btab2_(v8+v0,v2,v1), btab2_(v8+v4+v0,v2,v1) #define bit_table_4(v0,v8,v4,v2,v1) btab4_(v0,v8,v4,v2,v1) #define btab6_(v0,v20,v10,v8,v4,v2,v1)\ btab4_(v0,v8,v4,v2,v1), btab4_(v10+v0,v8,v4,v2,v1),\ btab4_(v20+v0,v8,v4,v2,v1), btab4_(v20+v10+v0,v8,v4,v2,v1) #define bit_table_6(v0,v20,v10,v8,v4,v2,v1) btab6_(v0,v20,v10,v8,v4,v2,v1) #define bit_table_8(v0,v80,v40,v20,v10,v8,v4,v2,v1)\ btab6_(v0,v20,v10,v8,v4,v2,v1), btab6_(v40+v0,v20,v10,v8,v4,v2,v1),\ btab6_(v80+v0,v20,v10,v8,v4,v2,v1), btab6_(v80+v40+v0,v20,v10,v8,v4,v2,v1) /* * byte_reverse_bits[B] = the unsigned char B with the order of bits reversed. */ intern_const unsigned char byte_reverse_bits[256]; /* * byte_right_mask[N] = a unsigned char with N trailing 1s, 0 <= N <= 8. */ intern_const unsigned char byte_right_mask[9]; /* * byte_count_bits[B] = the number of 1-bits in a unsigned char with value B. */ intern_const unsigned char byte_count_bits[256]; /* * byte_bit_run_length_N[B], for 0 <= N <= 7, gives the length of the * run of 1-bits starting at bit N in a unsigned char with value B, * numbering the bits in the unsigned char as 01234567. If the run includes * the low-order bit (i.e., might be continued into a following unsigned char), * the run length is increased by 8. */ intern_const unsigned char byte_bit_run_length_0[256], byte_bit_run_length_1[256], byte_bit_run_length_2[256], byte_bit_run_length_3[256], byte_bit_run_length_4[256], byte_bit_run_length_5[256], byte_bit_run_length_6[256], byte_bit_run_length_7[256]; /* * byte_bit_run_length[N] points to byte_bit_run_length_N. * byte_bit_run_length_neg[N] = byte_bit_run_length[-N & 7]. */ intern_const unsigned char *const byte_bit_run_length[8]; intern_const unsigned char *const byte_bit_run_length_neg[8]; /* * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters * denote the individual bits of the unsigned char. */ intern_const unsigned char byte_acegbdfh_to_abcdefgh[256]; #endif /* gsbittab_INCLUDED */ /* end of former gsbittab.h */ /* shc.h */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Common definitions for filters using Huffman coding */ #ifndef shc_INCLUDED # define shc_INCLUDED /* #include "gsbittab.h" */ #define hc_bits_size (SIZEOF_INT * 8) #define s_hce_init_inline(ss)\ ((ss)->bits = 0, (ss)->bits_left = hc_bits_size) #define s_hcd_init_inline(ss)\ ((ss)->bits = 0, (ss)->bits_left = 0) /* * These definitions are valid for code lengths up to 16 bits * and non-negative decoded values up to 15 bits. * * We define 3 different representations of the code: encoding tables, * decoding tables, and a definition table which can be generated easily * from frequency information and which in turn can easily generate * the encoding and decoding tables. * * The definition table has two parts: a list of the number of i-bit * codes for each i >= 1, and the decoded values corresponding to * the code values in increasing lexicographic order (which will also * normally be decreasing code frequency). Calling these two lists * L[1..M] and V[0..N-1] respectively, we have the following invariants: * - 1 <= M <= max_hc_length, N >= 2. * - L[0] = 0. * - for i=1..M, L[i] >= 0. * - sum(i=1..M: L[i]) = N. * - sum(i=1..M: L[i] * 2^-i) = 1. * - V[0..N-1] are a permutation of the integers 0..N-1. */ #define max_hc_length 16 typedef struct hc_definition_s { unsigned short *counts; /* [0..M] */ unsigned int num_counts; /* M */ unsigned short *values; /* [0..N-1] */ unsigned int num_values; /* N */ } hc_definition; /**** pts ****/ struct stream_hc_state_s; /* definition moved to pts_fax.h */ /* ------ Encoding tables ------ */ /* Define the structure for the encoding tables. */ typedef struct hce_code_s { unsigned short code; unsigned short code_length; } hce_code; #define hce_entry(c, len) { c, len } typedef struct hce_table_s { unsigned int count; hce_code *codes; } hce_table; #define hce_bits_available(n)\ (ss->bits_left >= (n) || wlimit - q > ((n) - ss->bits_left - 1) >> 3) /* ------ Encoding utilities ------ */ /* * Put a code on the output. The client is responsible for ensuring * that q does not exceed pw->limit. */ #ifdef DEBUG # define hc_print_value(code, clen)\ (gs_debug_c('W') ?\ (dlprintf2("[W]0x%x,%d\n", code, clen), 0) : 0) # define hc_print_value_then(code, clen) hc_print_value(code, clen), #else # define hc_print_value(code, clen) 0 # define hc_print_value_then(code, clen) /* */ #endif #define hc_print_code(rp) hc_print_value((rp)->code, (rp)->code_length) /* Declare variables that hold the encoder state. */ #define hce_declare_state\ register unsigned int bits;\ register int bits_left /* Load the state from the stream. */ /* Free variables: ss, bits, bits_left. */ #define hce_load_state()\ bits = ss->bits, bits_left = ss->bits_left /* Store the state back in the stream. */ /* Free variables: ss, bits, bits_left. */ #define hce_store_state()\ ss->bits = bits, ss->bits_left = bits_left /* Put a code on the stream. */ intern void hc_put_code_proc _((bool, unsigned char *, unsigned int)); #define hc_put_value(ss, q, code, clen)\ (hc_print_value_then(code, clen)\ ((bits_left -= (clen)) >= 0 ?\ (bits += (code) << bits_left) :\ (hc_put_code_proc((ss)->FirstBitLowOrder,\ q += hc_bits_size >> 3,\ (bits + ((code) >> -bits_left))),\ bits = (code) << (bits_left += hc_bits_size)))) #define hc_put_code(ss, q, cp)\ hc_put_value(ss, q, (cp)->code, (cp)->code_length) /* * Force out the final bits to the output. * Note that this does a store_state, but not a load_state. */ intern unsigned char *hc_put_last_bits_proc _((struct stream_hc_state_s *, unsigned char *, unsigned int, int)); #define hc_put_last_bits(ss, q)\ hc_put_last_bits_proc(ss, q, bits, bits_left) /* ------ Decoding tables ------ */ /* * Define the structure for the decoding tables. * First-level nodes are either leaves, which have * value = decoded value * code_length <= initial_bits * or non-leaves, which have * value = the index of a sub-table * code_length = initial_bits + the number of additional dispatch bits * Second-level nodes are always leaves, with * code_length = the actual number of bits in the code - initial_bits. */ typedef struct hcd_code_s { short value; unsigned short code_length; } hcd_code; typedef struct hcd_table_s { unsigned int count; unsigned int initial_bits; hcd_code *codes; } hcd_table; /* Declare variables that hold the decoder state. */ #define hcd_declare_state\ register const unsigned char *p;\ const unsigned char *rlimit;\ unsigned int bits;\ int bits_left /* Load the state from the stream. */ /* Free variables: pr, ss, p, rlimit, bits, bits_left. */ #define hcd_load_state()\ p = pr->ptr,\ rlimit = pr->limit,\ bits = ss->bits,\ bits_left = ss->bits_left /* Store the state back in the stream. */ /* Put back any complete bytes into the input buffer. */ /* Free variables: pr, ss, p, bits, bits_left. */ #define hcd_store_state()\ pr->ptr = p -= (bits_left >> 3),\ ss->bits = bits >>= (bits_left & ~7),\ ss->bits_left = bits_left &= 7 /* Macros to get blocks of bits from the input stream. */ /* Invariants: 0 <= bits_left <= bits_size; */ /* bits [bits_left-1..0] contain valid data. */ #define hcd_bits_available(n)\ (bits_left >= (n) || rlimit - p > ((n) - bits_left - 1) >> 3) /* For hcd_ensure_bits, n must not be greater than 8. */ #define HCD_ENSURE_BITS_ELSE(n)\ if (bits_left >= n)\ DO_NOTHING;\ else HCD_MORE_BITS_ELSE #define hcd_ensure_bits(n, outl)\ BEGIN HCD_ENSURE_BITS_ELSE(n) goto outl; END /* Load more bits into the buffer. */ #define HCD_MORE_BITS_1_ELSE\ if (p < rlimit) {\ int c = *++p;\ \ if (ss->FirstBitLowOrder)\ c = byte_reverse_bits[c];\ bits = (bits << 8) + c, bits_left += 8;\ } else #if hc_bits_size == 16 # define HCD_MORE_BITS_ELSE HCD_MORE_BITS_1_ELSE #else /* hc_bits_size >= 32 */ # define HCD_MORE_BITS_ELSE\ if (rlimit - p >= 3) {\ if (ss->FirstBitLowOrder)\ bits = (bits << 24) + ((unsigned int)byte_reverse_bits[p[1]] << 16) + ((unsigned int)byte_reverse_bits[p[2]] << 8) + byte_reverse_bits[p[3]];\ else\ bits = (bits << 24) + ((unsigned int)p[1] << 16) + ((unsigned int)p[2] << 8) + p[3];\ bits_left += 24, p += 3;\ } else HCD_MORE_BITS_1_ELSE #endif #define hcd_more_bits(outl)\ BEGIN HCD_MORE_BITS_ELSE goto outl; END #define hcd_peek_bits(n) ((bits >> (bits_left - (n))) & ((1 << (n)) - 1)) /* hcd_peek_var_bits requires bits_left <= 8. */ #define hcd_peek_var_bits(n)\ ((bits >> (bits_left - (n))) & byte_right_mask[n]) /* hcd_peek_bits_left requires bits_left <= 8. */ #define hcd_peek_bits_left()\ (bits & byte_right_mask[bits_left]) #define hcd_skip_bits(n) (bits_left -= (n)) #endif /* shc_INCLUDED */ /* end of former shc.h */ /* scf.h */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Common definitions for CCITTFax encoding and decoding filters */ #ifndef scf_INCLUDED # define scf_INCLUDED /* #include "shc.h" */ /* * The CCITT Group 3 (T.4) and Group 4 (T.6) fax specifications map * run lengths to Huffman codes. White and black have different mappings. * If the run length is 64 or greater, two or more codes are needed: * - One or more 'make-up' codes for 2560 pixels; * - A 'make-up' code that encodes the multiple of 64; * - A 'termination' code for the remainder. * For runs of 63 or less, only the 'termination' code is needed. */ /* ------ Encoding tables ------ */ /* * The maximum possible length of a scan line is determined by the * requirement that 3 runs have to fit into the stream buffer. * A run of length N requires approximately ceil(N / 2560) makeup codes, * hence 1.5 * ceil(N / 2560) bytes. Taking the largest safe stream * buffer size as 32K, we arrive at the following maximum width: */ #if SIZEOF_INT > 2 # define cfe_max_width (2560 * 32000 * 2 / 3) #else # define cfe_max_width (max_int - 40) /* avoid overflows */ #endif /* The +5 in cfe_max_code_bytes is a little conservative. */ #define cfe_max_code_bytes(width) ((width) / 2560 * 3 / 2 + 5) typedef hce_code cfe_run; /* Codes common to 1-D and 2-D encoding. */ /* The decoding algorithms know that EOL is 0....01. */ #define run_eol_code_length 12 #define run_eol_code_value 1 intern_const cfe_run cf_run_eol; typedef struct cf_runs_s { cfe_run termination[64]; cfe_run make_up[41]; } cf_runs; intern_const cf_runs cf_white_runs, cf_black_runs; intern_const cfe_run cf_uncompressed[6]; intern_const cfe_run cf_uncompressed_exit[10]; /* indexed by 2 x length of */ /* white run + (1 if next run black, 0 if white) */ /* 1-D encoding. */ intern_const cfe_run cf1_run_uncompressed; /* 2-D encoding. */ intern_const cfe_run cf2_run_pass; #define cf2_run_pass_length 4 #define cf2_run_pass_value 0x1 #define cf2_run_vertical_offset 3 intern_const cfe_run cf2_run_vertical[7]; /* indexed by b1 - a1 + offset */ intern_const cfe_run cf2_run_horizontal; #define cf2_run_horizontal_value 1 #define cf2_run_horizontal_length 3 intern_const cfe_run cf2_run_uncompressed; /* 2-D Group 3 encoding. */ intern_const cfe_run cf2_run_eol_1d; intern_const cfe_run cf2_run_eol_2d; /* ------ Decoding tables ------ */ typedef hcd_code cfd_node; #define run_length value /* * The value in the decoding tables is either a white or black run length, * or a (negative) exceptional value. */ #define run_error (-1) #define run_zeros (-2) /* EOL follows, possibly with more padding first */ #define run_uncompressed (-3) /* 2-D codes */ #define run2_pass (-4) #define run2_horizontal (-5) #define cfd_white_initial_bits 8 #define cfd_white_min_bits 4 /* shortest white run */ /* intern_const cfd_node cf_white_decode[]; */ #define cfd_black_initial_bits 7 #define cfd_black_min_bits 2 /* shortest black run */ /* intern_const cfd_node cf_black_decode[]; */ #define cfd_2d_initial_bits 7 #define cfd_2d_min_bits 4 /* shortest non-H/V 2-D run */ /* intern_const cfd_node cf_2d_decode[]; */ #define cfd_uncompressed_initial_bits 6 /* must be 6 */ /* intern_const cfd_node cf_uncompressed_decode[]; */ /* ------ Run detection macros ------ */ /* * For the run detection macros: * white_byte is 0 or 0xff for BlackIs1 or !BlackIs1 respectively; * data holds p[-1], inverted if !BlackIs1; * count is the number of valid bits remaining in the scan line. */ /* Aliases for bit processing tables. */ #define cf_byte_run_length byte_bit_run_length_neg #define cf_byte_run_length_0 byte_bit_run_length_0 /* Skip over white pixels to find the next black pixel in the input. */ /* Store the run length in rlen, and update data, p, and count. */ /* There are many more white pixels in typical input than black pixels, */ /* and the runs of white pixels tend to be much longer, so we use */ /* substantially different loops for the two cases. */ #define skip_white_pixels(data, p, count, white_byte, rlen)\ BEGIN\ rlen = cf_byte_run_length[count & 7][data ^ 0xff];\ if ( rlen >= 8 ) { /* run extends past unsigned char boundary */\ if ( white_byte == 0 ) {\ if ( p[0] ) { data = p[0]; p += 1; rlen -= 8; }\ else if ( p[1] ) { data = p[1]; p += 2; }\ else {\ while ( !(p[2] | p[3] | p[4] | p[5]) )\ p += 4, rlen += 32;\ if ( p[2] ) {\ data = p[2]; p += 3; rlen += 8;\ } else if ( p[3] ) {\ data = p[3]; p += 4; rlen += 16;\ } else if ( p[4] ) {\ data = p[4]; p += 5; rlen += 24;\ } else /* p[5] */ {\ data = p[5]; p += 6; rlen += 32;\ }\ }\ } else {\ if ( p[0] != 0xff ) { data = (unsigned char)~p[0]; p += 1; rlen -= 8; }\ else if ( p[1] != 0xff ) { data = (unsigned char)~p[1]; p += 2; }\ else {\ while ( (p[2] & p[3] & p[4] & p[5]) == 0xff )\ p += 4, rlen += 32;\ if ( p[2] != 0xff ) {\ data = (unsigned char)~p[2]; p += 3; rlen += 8;\ } else if ( p[3] != 0xff ) {\ data = (unsigned char)~p[3]; p += 4; rlen += 16;\ } else if ( p[4] != 0xff ) {\ data = (unsigned char)~p[4]; p += 5; rlen += 24;\ } else /* p[5] != 0xff */ {\ data = (unsigned char)~p[5]; p += 6; rlen += 32;\ }\ }\ }\ rlen += cf_byte_run_length_0[data ^ 0xff];\ }\ count -= rlen;\ END /* Skip over black pixels to find the next white pixel in the input. */ /* Store the run length in rlen, and update data, p, and count. */ #define skip_black_pixels(data, p, count, white_byte, rlen)\ BEGIN\ rlen = cf_byte_run_length[count & 7][data];\ if ( rlen >= 8 ) {\ if ( white_byte == 0 )\ for ( ; ; p += 4, rlen += 32 ) {\ if ( p[0] != 0xff ) { data = p[0]; p += 1; rlen -= 8; break; }\ if ( p[1] != 0xff ) { data = p[1]; p += 2; break; }\ if ( p[2] != 0xff ) { data = p[2]; p += 3; rlen += 8; break; }\ if ( p[3] != 0xff ) { data = p[3]; p += 4; rlen += 16; break; }\ }\ else\ for ( ; ; p += 4, rlen += 32 ) {\ if ( p[0] ) { data = (unsigned char)~p[0]; p += 1; rlen -= 8; break; }\ if ( p[1] ) { data = (unsigned char)~p[1]; p += 2; break; }\ if ( p[2] ) { data = (unsigned char)~p[2]; p += 3; rlen += 8; break; }\ if ( p[3] ) { data = (unsigned char)~p[3]; p += 4; rlen += 16; break; }\ }\ rlen += cf_byte_run_length_0[data];\ }\ count -= rlen;\ END #endif /* scf_INCLUDED */ /* end of former scf.h */ #if USE_BUILTIN_FAXE #if OBJDEP # warning PROVIDES: pts_faxe #endif /* scfe.c */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* CCITTFax encoding filter */ /* #include "config2.h" */ /* #include "scf.h" */ /* #include "scfx.h" */ /* ------ Macros and support routines ------ */ /* Statistics */ #ifdef DEBUG typedef struct stats_runs_s { unsigned long termination[64]; unsigned long make_up[41]; } stats_runs_t; static stats_runs_t stats_white_runs, stats_black_runs; #define COUNT_RUN(tab, i) (tab)[i]++; static void print_run_stats(const stats_runs_t * stats) { int i; unsigned long total; for (i = 0, total = 0; i < 41; i++) dprintf1(" %lu", stats->make_up[i]), total += stats->make_up[i]; dprintf1(" total=%lu\n\t", total); for (i = 0, total = 0; i < 64; i++) dprintf1(" %lu", stats->termination[i]), total += stats->termination[i]; dprintf1(" total=%lu\n", total); } #else /* !DEBUG */ #define COUNT_RUN(cnt, i) DO_NOTHING #endif /* DEBUG */ /* Put a run onto the output stream. */ /* Free variables: q, bits, bits_left. */ #define CF_PUT_RUN(ss, lenv, rt, stats)\ BEGIN\ cfe_run rr;\ \ if ( lenv >= 64 ) {\ hce_store_state();\ q = cf_put_long_run(ss, q, lenv, &rt);\ hce_load_state();\ lenv &= 63;\ }\ rr = rt.termination[lenv];\ COUNT_RUN(stats.termination, lenv);\ hc_put_value(ss, q, rr.code, rr.code_length);\ END static unsigned char * cf_put_long_run(stream_CFE_state * ss, unsigned char * q, int lenv, const cf_runs * prt) { hce_declare_state; cfe_run rr; #ifdef DEBUG stats_runs_t *pstats = (prt == &cf_white_runs ? &stats_white_runs : &stats_black_runs); #endif hce_load_state(); while (lenv >= 2560 + 64) { rr = prt->make_up[40]; COUNT_RUN(pstats->make_up, 40); hc_put_value(ss, q, rr.code, rr.code_length); lenv -= 2560; } rr = prt->make_up[lenv >> 6]; COUNT_RUN(pstats->make_up, lenv >> 6); hc_put_value(ss, q, rr.code, rr.code_length); hce_store_state(); return q; } #define CF_PUT_WHITE_RUN(ss, lenv)\ CF_PUT_RUN(ss, lenv, cf_white_runs, stats_white_runs) #define CF_PUT_BLACK_RUN(ss, lenv)\ CF_PUT_RUN(ss, lenv, cf_black_runs, stats_black_runs) /* ------ CCITTFaxEncode ------ */ /* private_st_CFE_state(); */ static void s_CFE_release _((stream_state *)); /* Set default parameter values. */ static void s_CFE_set_defaults(register stream_state * st) { stream_CFE_state *const ss = (stream_CFE_state *) st; s_CFE_set_defaults_inline(ss); } /* Initialize CCITTFaxEncode filter */ static int s_CFE_init(register stream_state * st) { stream_CFE_state *const ss = (stream_CFE_state *) st; int columns = ss->Columns; /* * The worst case for encoding is alternating white and black pixels. * For 1-D encoding, the worst case is 9 bits per 2 pixels; for 2-D * (horizontal), 12 bits per 2 pixels. To fill out a scan line, * we may add up to 6 12-bit EOL codes. */ /**** pts: added UL ****/ int code_bytes = ((columns * (ss->K == 0 ? 9UL : 12UL)) >> 4) + 20; /* add slop */ int raster = ss->raster = ROUND_UP((columns + 7) >> 3, ss->DecodedByteAlign); s_hce_init_inline(ss); ss->lbuf = ss->lprev = ss->lcode = 0; /* in case we have to release */ if (columns > cfe_max_width) return PTSFAX_ERRC; /****** WRONG ******/ /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ ss->lbuf = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFE lbuf"); ss->lcode = (unsigned char*)gs_alloc_bytes(st->memory, code_bytes, "CFE lcode"); if (ss->lbuf == 0 || ss->lcode == 0) { s_CFE_release(st); return PTSFAX_ERRC; /****** WRONG ******/ } if (ss->K != 0) { ss->lprev = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFE lprev"); if (ss->lprev == 0) { s_CFE_release(st); return PTSFAX_ERRC; /****** WRONG ******/ } /* Clear the initial reference line for 2-D encoding. */ /* Make sure it is terminated properly. */ ss->memset_(ss->lprev, (ss->BlackIs1 ? 0 : 0xff), raster); if (columns & 7) ss->lprev[raster - 1] ^= 0x80 >> (columns & 7); else ss->lprev[raster] = ~ss->lprev[0]; } ss->read_count = raster; ss->write_count = 0; ss->k_left = (ss->K > 0 ? 1 : ss->K); ss->max_code_bytes = code_bytes; return 0; } /* Release the filter. */ static void s_CFE_release(stream_state * st) { stream_CFE_state *const ss = (stream_CFE_state *) st; gs_free_object(st->memory, ss->lprev, "CFE lprev(close)"); gs_free_object(st->memory, ss->lcode, "CFE lcode(close)"); gs_free_object(st->memory, ss->lbuf, "CFE lbuf(close)"); } /* Flush the buffer */ static void cf_encode_1d _((stream_CFE_state *, const unsigned char *, stream_cursor_write *)); static void cf_encode_2d _((stream_CFE_state *, const unsigned char *, stream_cursor_write *, const unsigned char *)); static int s_CFE_process(stream_state * st, stream_cursor_read * pr, stream_cursor_write * pw, bool last) { stream_CFE_state *const ss = (stream_CFE_state *) st; const unsigned char *rlimit = pr->limit; unsigned char *wlimit = pw->limit; int raster = ss->raster; unsigned char end_mask = 1 << (-ss->Columns & 7); int status = 0; for (;;) { stream_cursor_write w; if_debug2('w', "[w]CFE: read_count = %d, write_count=%d,\n", ss->read_count, ss->write_count); if_debug6('w', " pr = 0x%lx(%d)0x%lx, pw = 0x%lx(%d)0x%lx\n", (unsigned long) pr->ptr, (int)(rlimit - pr->ptr), (unsigned long) rlimit, (unsigned long) pw->ptr, (int)(wlimit - pw->ptr), (unsigned long) wlimit); if (ss->write_count) { /* Copy more of an encoded line to the caller. */ int wcount = wlimit - pw->ptr; int ccount = min(wcount, ss->write_count); ss->memcpy_(pw->ptr + 1, ss->lcode + ss->code_bytes - ss->write_count, ccount); pw->ptr += ccount; if ((ss->write_count -= ccount) > 0) { status = 1; break; } } if (ss->read_count) { /* Copy more of an unencoded line from the caller. */ int rcount = rlimit - pr->ptr; int ccount = min(rcount, ss->read_count); if (rcount == 0 && last) break; ss->memcpy_(ss->lbuf + raster - ss->read_count, pr->ptr + 1, ccount); pr->ptr += ccount; if ((ss->read_count -= ccount) != 0) break; } /* * We have a full scan line in lbuf. Ensure that it ends with * two polarity changes. */ { unsigned char *end = ss->lbuf + raster - 1; unsigned char end_bit = *end & end_mask; unsigned char not_bit = end_bit ^ end_mask; *end &= -end_mask; if (end_mask == 1) end[1] = (end_bit ? 0x40 : 0x80); else if (end_mask == 2) *end |= not_bit >> 1, end[1] = end_bit << 7; else *end |= (not_bit >> 1) | (end_bit >> 2); } /* * Write the output directly to the caller's buffer if it's large * enough, otherwise to our own buffer. */ if (wlimit - pw->ptr >= ss->max_code_bytes) { w = *pw; } else { w.ptr = ss->lcode - 1; w.limit = w.ptr + ss->max_code_bytes; } #ifdef DEBUG if (ss->K > 0) { if_debug1('w', "[w]new row, k_left=%d\n", ss->k_left); } else { if_debug0('w', "[w]new row\n"); } #endif /* * Write an EOL (actually a "beginning of line") if requested. */ if (ss->EndOfLine) { const cfe_run *rp = (ss->K <= 0 ? &cf_run_eol : ss->k_left > 1 ? &cf2_run_eol_2d : &cf2_run_eol_1d); cfe_run run; hce_declare_state; hce_load_state(); if (ss->EncodedByteAlign) { run = *rp; /* Pad the run on the left */ /* so it winds up unsigned char-aligned. */ run.code_length += (bits_left - run_eol_code_length) & 7; if (run.code_length > 16) /* <= 23 */ bits_left -= run.code_length & 7, run.code_length = 16; rp = &run; } hc_put_code(ss, w.ptr, rp); hce_store_state(); } else if (ss->EncodedByteAlign) ss->bits_left &= ~7; /* Encode the line. */ if (ss->K == 0) cf_encode_1d(ss, ss->lbuf, &w); /* pure 1-D */ else if (ss->K < 0) cf_encode_2d(ss, ss->lbuf, &w, ss->lprev); /* pure 2-D */ else if (--(ss->k_left)) /* mixed, use 2-D */ cf_encode_2d(ss, ss->lbuf, &w, ss->lprev); else { /* mixed, use 1-D */ cf_encode_1d(ss, ss->lbuf, &w); ss->k_left = ss->K; } /* * If we didn't write directly to the client's buffer, schedule * the output data to be written. */ if (w.limit == wlimit) pw->ptr = w.ptr; else ss->write_count = ss->code_bytes = w.ptr - (ss->lcode - 1); if (ss->K != 0) { /* In 2-D modes, swap the current and previous scan lines. */ unsigned char *temp = ss->lbuf; ss->lbuf = ss->lprev; ss->lprev = temp; } /* Note that the input buffer needs refilling. */ ss->read_count = raster; } /* * When we exit from the loop, we know that write_count = 0, and * there is no line waiting to be processed in the input buffer. */ if (last && status == 0) { const cfe_run *rp = (ss->K > 0 ? &cf2_run_eol_1d : &cf_run_eol); int i = (!ss->EndOfBlock ? 0 : ss->K < 0 ? 2 : 6); unsigned int bits_to_write = hc_bits_size - ss->bits_left + i * rp->code_length; unsigned char *q = pw->ptr; hce_declare_state; if (0U+(wlimit - q) < (bits_to_write + 7) >> 3) { /* PTS_UNSIGNED */ status = 1; goto out; } hce_load_state(); if (ss->EncodedByteAlign) bits_left &= ~7; while (--i >= 0) hc_put_code(ss, q, rp); /* Force out the last unsigned char or bytes. */ pw->ptr = hc_put_last_bits((stream_hc_state *) ss, q); } out: if_debug9('w', "[w]CFE exit %d: read_count = %d, write_count = %d,\n pr = 0x%lx(%d)0x%lx; pw = 0x%lx(%d)0x%lx\n", status, ss->read_count, ss->write_count, (unsigned long) pr->ptr, (int)(rlimit - pr->ptr), (unsigned long) rlimit, (unsigned long) pw->ptr, (int)(wlimit - pw->ptr), (unsigned long) wlimit); #ifdef DEBUG if (pr->ptr > rlimit || pw->ptr > wlimit) { lprintf("Pointer overrun!\n"); status = PTSFAX_ERRC; } if (gs_debug_c('w') && status == 1) { dlputs("[w]white runs:"); print_run_stats(&stats_white_runs); dlputs("[w]black runs:"); print_run_stats(&stats_black_runs); } #endif return status; } /* Encode a 1-D scan line. */ static void cf_encode_1d(stream_CFE_state * ss, const unsigned char * lbuf, stream_cursor_write * pw) { unsigned int count = ss->raster << 3; unsigned char *q = pw->ptr; int end_count = -ss->Columns & 7; int rlen; hce_declare_state; const unsigned char *p = lbuf; unsigned char invert = (ss->BlackIs1 ? 0 : 0xff); /* Invariant: data = p[-1] ^ invert. */ unsigned int data = *p++ ^ invert; hce_load_state(); while (count != 0U+end_count) { /* PTS_UNSIGNED */ /* Parse a white run. */ skip_white_pixels(data, p, count, invert, rlen); CF_PUT_WHITE_RUN(ss, rlen); if (count == 0U+end_count) /* PTS_UNSIGNED */ break; /* Parse a black run. */ skip_black_pixels(data, p, count, invert, rlen); CF_PUT_BLACK_RUN(ss, rlen); } hce_store_state(); pw->ptr = q; } /* Encode a 2-D scan line. */ static void cf_encode_2d(stream_CFE_state * ss, const unsigned char * lbuf, stream_cursor_write * pw, const unsigned char * lprev) { unsigned char invert_white = (ss->BlackIs1 ? 0 : 0xff); unsigned char invert = invert_white; unsigned int count = ss->raster << 3; int end_count = -ss->Columns & 7; const unsigned char *p = lbuf; unsigned char *q = pw->ptr; unsigned int data = *p++ ^ invert; hce_declare_state; /* * In order to handle the nominal 'changing white' at the beginning of * each scan line, we need to suppress the test for an initial black bit * in the reference line when we are at the very beginning of the scan * line. To avoid an extra test, we use two different mask tables. */ static const unsigned char initial_count_bit[8] = { 0, 1, 2, 4, 8, 0x10, 0x20, 0x40 }; static const unsigned char further_count_bit[8] = { 0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40 }; const unsigned char *count_bit = initial_count_bit; hce_load_state(); while (count != 0U+end_count) { /* PTS_UNSIGNED */ /* * If invert == invert_white, white and black have their * correct meanings; if invert == ~invert_white, * black and white are interchanged. */ unsigned int a0 = count; unsigned int a1; #define b1 (a1 - diff) /* only for printing */ int diff; unsigned int prev_count = count; const unsigned char *prev_p = p - lbuf + lprev; unsigned char prev_data = prev_p[-1] ^ invert; int rlen; /* Find the a1 and b1 transitions. */ skip_white_pixels(data, p, count, invert, rlen); a1 = count; if ((prev_data & count_bit[prev_count & 7])) { /* Look for changing white first. */ skip_black_pixels(prev_data, prev_p, prev_count, invert, rlen); } count_bit = further_count_bit; /* no longer at beginning */ pass: if (prev_count != 0U+end_count) /* PTS_UNSIGNED */ skip_white_pixels(prev_data, prev_p, prev_count, invert, rlen); diff = a1 - prev_count; /* i.e., logical b1 - a1 */ /* In all the comparisons below, remember that count */ /* runs downward, not upward, so the comparisons are */ /* reversed. */ if (diff <= -2) { /* Could be a pass mode. Find b2. */ if (prev_count != 0U+ end_count) /* PTS_UNSIGNED */ skip_black_pixels(prev_data, prev_p, prev_count, invert, rlen); if (prev_count > a1) { /* Use pass mode. */ if_debug4('W', "[W]pass: count = %d, a1 = %d, b1 = %d, new count = %d\n", a0, a1, b1, prev_count); hc_put_value(ss, q, cf2_run_pass_value, cf2_run_pass_length); a0 = prev_count; goto pass; } } /* Check for vertical coding. */ if (diff <= 3 && diff >= -3) { /* Use vertical coding. */ const cfe_run *cp = &cf2_run_vertical[diff + 3]; if_debug5('W', "[W]vertical %d: count = %d, a1 = %d, b1 = %d, new count = %d\n", diff, a0, a1, b1, count); hc_put_code(ss, q, cp); invert = ~invert; /* a1 polarity changes */ data ^= 0xff; continue; } /* No luck, use horizontal coding. */ if (count != 0U+end_count) /* PTS_UNSIGNED */ skip_black_pixels(data, p, count, invert, rlen); /* find a2 */ hc_put_value(ss, q, cf2_run_horizontal_value, cf2_run_horizontal_length); a0 -= a1; a1 -= count; if (invert == invert_white) { if_debug3('W', "[W]horizontal: white = %d, black = %d, new count = %d\n", a0, a1, count); CF_PUT_WHITE_RUN(ss, a0); CF_PUT_BLACK_RUN(ss, a1); } else { if_debug3('W', "[W]horizontal: black = %d, white = %d, new count = %d\n", a0, a1, count); CF_PUT_BLACK_RUN(ss, a0); CF_PUT_WHITE_RUN(ss, a1); #undef b1 } } hce_store_state(); pw->ptr = q; } /* Stream template */ const stream_template s_CFE_template = { /*0, &st_CFE_state*/ s_CFE_init, s_CFE_process, 1, 1, s_CFE_release, s_CFE_set_defaults, 0 }; /* end of former scfe.c */ /* scfetab.c */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Tables for CCITTFaxEncode filter */ /* #include "scommon.h" */ /* for scf.h */ /* #include "scf.h" */ /* We make this a separate file so that it can be used by */ /* the program that generates the tables for the CCITTFaxDecode filter. */ /* ------ Run encoding tables ------ */ /* Abbreviate hce_entry to make the file smaller. */ #define RUN(c,len) hce_entry(c,len) /* Define the end-of-line code. */ /* Code in scfd.c and scfdgen.c knows that the run value is 1. */ impl_const cfe_run cf_run_eol = RUN(run_eol_code_value, run_eol_code_length); /* Define the 1-D code that signals uncompressed data. */ impl_const cfe_run cf1_run_uncompressed = RUN(0xf, 12); /* Define the 2-D run codes. */ impl_const cfe_run cf2_run_pass = RUN(cf2_run_pass_value, cf2_run_pass_length); impl_const cfe_run cf2_run_vertical[7] = { RUN(0x3, 7), RUN(0x3, 6), RUN(0x3, 3), RUN(0x1, 1), RUN(0x2, 3), RUN(0x2, 6), RUN(0x2, 7) }; impl_const cfe_run cf2_run_horizontal = RUN(cf2_run_horizontal_value, cf2_run_horizontal_length); impl_const cfe_run cf2_run_uncompressed = RUN(0xf, 10); /* EOL codes for Group 3 2-D. */ /* Code in scfd.c knows that these are 0...01x. */ impl_const cfe_run cf2_run_eol_1d = RUN((run_eol_code_value << 1) + 1, run_eol_code_length + 1); impl_const cfe_run cf2_run_eol_2d = RUN((run_eol_code_value << 1) + 0, run_eol_code_length + 1); /* White run codes. */ impl_const cf_runs cf_white_runs = { { /* Termination codes */ RUN(0x35, 8), RUN(0x7, 6), RUN(0x7, 4), RUN(0x8, 4), RUN(0xb, 4), RUN(0xc, 4), RUN(0xe, 4), RUN(0xf, 4), RUN(0x13, 5), RUN(0x14, 5), RUN(0x7, 5), RUN(0x8, 5), RUN(0x8, 6), RUN(0x3, 6), RUN(0x34, 6), RUN(0x35, 6), RUN(0x2a, 6), RUN(0x2b, 6), RUN(0x27, 7), RUN(0xc, 7), RUN(0x8, 7), RUN(0x17, 7), RUN(0x3, 7), RUN(0x4, 7), RUN(0x28, 7), RUN(0x2b, 7), RUN(0x13, 7), RUN(0x24, 7), RUN(0x18, 7), RUN(0x2, 8), RUN(0x3, 8), RUN(0x1a, 8), RUN(0x1b, 8), RUN(0x12, 8), RUN(0x13, 8), RUN(0x14, 8), RUN(0x15, 8), RUN(0x16, 8), RUN(0x17, 8), RUN(0x28, 8), RUN(0x29, 8), RUN(0x2a, 8), RUN(0x2b, 8), RUN(0x2c, 8), RUN(0x2d, 8), RUN(0x4, 8), RUN(0x5, 8), RUN(0xa, 8), RUN(0xb, 8), RUN(0x52, 8), RUN(0x53, 8), RUN(0x54, 8), RUN(0x55, 8), RUN(0x24, 8), RUN(0x25, 8), RUN(0x58, 8), RUN(0x59, 8), RUN(0x5a, 8), RUN(0x5b, 8), RUN(0x4a, 8), RUN(0x4b, 8), RUN(0x32, 8), RUN(0x33, 8), RUN(0x34, 8) }, { /* Make-up codes */ RUN(0, 0) /* dummy */ , RUN(0x1b, 5), RUN(0x12, 5), RUN(0x17, 6), RUN(0x37, 7), RUN(0x36, 8), RUN(0x37, 8), RUN(0x64, 8), RUN(0x65, 8), RUN(0x68, 8), RUN(0x67, 8), RUN(0xcc, 9), RUN(0xcd, 9), RUN(0xd2, 9), RUN(0xd3, 9), RUN(0xd4, 9), RUN(0xd5, 9), RUN(0xd6, 9), RUN(0xd7, 9), RUN(0xd8, 9), RUN(0xd9, 9), RUN(0xda, 9), RUN(0xdb, 9), RUN(0x98, 9), RUN(0x99, 9), RUN(0x9a, 9), RUN(0x18, 6), RUN(0x9b, 9), RUN(0x8, 11), RUN(0xc, 11), RUN(0xd, 11), RUN(0x12, 12), RUN(0x13, 12), RUN(0x14, 12), RUN(0x15, 12), RUN(0x16, 12), RUN(0x17, 12), RUN(0x1c, 12), RUN(0x1d, 12), RUN(0x1e, 12), RUN(0x1f, 12) } }; /* Black run codes. */ impl_const cf_runs cf_black_runs = { { /* Termination codes */ RUN(0x37, 10), RUN(0x2, 3), RUN(0x3, 2), RUN(0x2, 2), RUN(0x3, 3), RUN(0x3, 4), RUN(0x2, 4), RUN(0x3, 5), RUN(0x5, 6), RUN(0x4, 6), RUN(0x4, 7), RUN(0x5, 7), RUN(0x7, 7), RUN(0x4, 8), RUN(0x7, 8), RUN(0x18, 9), RUN(0x17, 10), RUN(0x18, 10), RUN(0x8, 10), RUN(0x67, 11), RUN(0x68, 11), RUN(0x6c, 11), RUN(0x37, 11), RUN(0x28, 11), RUN(0x17, 11), RUN(0x18, 11), RUN(0xca, 12), RUN(0xcb, 12), RUN(0xcc, 12), RUN(0xcd, 12), RUN(0x68, 12), RUN(0x69, 12), RUN(0x6a, 12), RUN(0x6b, 12), RUN(0xd2, 12), RUN(0xd3, 12), RUN(0xd4, 12), RUN(0xd5, 12), RUN(0xd6, 12), RUN(0xd7, 12), RUN(0x6c, 12), RUN(0x6d, 12), RUN(0xda, 12), RUN(0xdb, 12), RUN(0x54, 12), RUN(0x55, 12), RUN(0x56, 12), RUN(0x57, 12), RUN(0x64, 12), RUN(0x65, 12), RUN(0x52, 12), RUN(0x53, 12), RUN(0x24, 12), RUN(0x37, 12), RUN(0x38, 12), RUN(0x27, 12), RUN(0x28, 12), RUN(0x58, 12), RUN(0x59, 12), RUN(0x2b, 12), RUN(0x2c, 12), RUN(0x5a, 12), RUN(0x66, 12), RUN(0x67, 12) }, { /* Make-up codes. */ RUN(0, 0) /* dummy */ , RUN(0xf, 10), RUN(0xc8, 12), RUN(0xc9, 12), RUN(0x5b, 12), RUN(0x33, 12), RUN(0x34, 12), RUN(0x35, 12), RUN(0x6c, 13), RUN(0x6d, 13), RUN(0x4a, 13), RUN(0x4b, 13), RUN(0x4c, 13), RUN(0x4d, 13), RUN(0x72, 13), RUN(0x73, 13), RUN(0x74, 13), RUN(0x75, 13), RUN(0x76, 13), RUN(0x77, 13), RUN(0x52, 13), RUN(0x53, 13), RUN(0x54, 13), RUN(0x55, 13), RUN(0x5a, 13), RUN(0x5b, 13), RUN(0x64, 13), RUN(0x65, 13), RUN(0x8, 11), RUN(0xc, 11), RUN(0xd, 11), RUN(0x12, 12), RUN(0x13, 12), RUN(0x14, 12), RUN(0x15, 12), RUN(0x16, 12), RUN(0x17, 12), RUN(0x1c, 12), RUN(0x1d, 12), RUN(0x1e, 12), RUN(0x1f, 12) } }; /* Uncompressed codes. */ impl_const cfe_run cf_uncompressed[6] = { RUN(1, 1), RUN(1, 2), RUN(1, 3), RUN(1, 4), RUN(1, 5), RUN(1, 6) }; /* Uncompressed exit codes. */ impl_const cfe_run cf_uncompressed_exit[10] = { RUN(2, 8), RUN(3, 8), RUN(2, 9), RUN(3, 9), RUN(2, 10), RUN(3, 10), RUN(2, 11), RUN(3, 11), RUN(2, 12), RUN(3, 12) }; #if 0 /* Some C compilers insist on having executable code in every file.... */ void scfetab_dummy _((void)); /* for picky compilers */ void scfetab_dummy(void) { } #endif /* end of former scfetab.c */ #endif /* USE_BUILTIN_FAXE */ #if USE_BUILTIN_FAXD #if OBJDEP # warning PROVIDES: pts_faxd #endif /* scfdtab.c; must be before scfd.c */ /* #include "scommon.h" */ /* for scf.h */ /* #include "scf.h" */ /* White decoding table. */ impl_const cfd_node cf_white_decode[] = { { 256, 12 }, { 272, 12 }, { 29, 8 }, { 30, 8 }, { 45, 8 }, { 46, 8 }, { 22, 7 }, { 22, 7 }, { 23, 7 }, { 23, 7 }, { 47, 8 }, { 48, 8 }, { 13, 6 }, { 13, 6 }, { 13, 6 }, { 13, 6 }, { 20, 7 }, { 20, 7 }, { 33, 8 }, { 34, 8 }, { 35, 8 }, { 36, 8 }, { 37, 8 }, { 38, 8 }, { 19, 7 }, { 19, 7 }, { 31, 8 }, { 32, 8 }, { 1, 6 }, { 1, 6 }, { 1, 6 }, { 1, 6 }, { 12, 6 }, { 12, 6 }, { 12, 6 }, { 12, 6 }, { 53, 8 }, { 54, 8 }, { 26, 7 }, { 26, 7 }, { 39, 8 }, { 40, 8 }, { 41, 8 }, { 42, 8 }, { 43, 8 }, { 44, 8 }, { 21, 7 }, { 21, 7 }, { 28, 7 }, { 28, 7 }, { 61, 8 }, { 62, 8 }, { 63, 8 }, { 0, 8 }, { 320, 8 }, { 384, 8 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 10, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 11, 5 }, { 27, 7 }, { 27, 7 }, { 59, 8 }, { 60, 8 }, { 288, 9 }, { 290, 9 }, { 18, 7 }, { 18, 7 }, { 24, 7 }, { 24, 7 }, { 49, 8 }, { 50, 8 }, { 51, 8 }, { 52, 8 }, { 25, 7 }, { 25, 7 }, { 55, 8 }, { 56, 8 }, { 57, 8 }, { 58, 8 }, { 192, 6 }, { 192, 6 }, { 192, 6 }, { 192, 6 }, { 1664, 6 }, { 1664, 6 }, { 1664, 6 }, { 1664, 6 }, { 448, 8 }, { 512, 8 }, { 292, 9 }, { 640, 8 }, { 576, 8 }, { 294, 9 }, { 296, 9 }, { 298, 9 }, { 300, 9 }, { 302, 9 }, { 256, 7 }, { 256, 7 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 2, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 128, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 8, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 9, 5 }, { 16, 6 }, { 16, 6 }, { 16, 6 }, { 16, 6 }, { 17, 6 }, { 17, 6 }, { 17, 6 }, { 17, 6 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 14, 6 }, { 14, 6 }, { 14, 6 }, { 14, 6 }, { 15, 6 }, { 15, 6 }, { 15, 6 }, { 15, 6 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 64, 5 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { 7, 4 }, { -2, 3 }, { -2, 3 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -3, 4 }, { 1792, 3 }, { 1792, 3 }, { 1984, 4 }, { 2048, 4 }, { 2112, 4 }, { 2176, 4 }, { 2240, 4 }, { 2304, 4 }, { 1856, 3 }, { 1856, 3 }, { 1920, 3 }, { 1920, 3 }, { 2368, 4 }, { 2432, 4 }, { 2496, 4 }, { 2560, 4 }, { 1472, 1 }, { 1536, 1 }, { 1600, 1 }, { 1728, 1 }, { 704, 1 }, { 768, 1 }, { 832, 1 }, { 896, 1 }, { 960, 1 }, { 1024, 1 }, { 1088, 1 }, { 1152, 1 }, { 1216, 1 }, { 1280, 1 }, { 1344, 1 }, { 1408, 1 } }; /* Black decoding table. */ impl_const cfd_node cf_black_decode[] = { { 128, 12 }, { 160, 13 }, { 224, 12 }, { 256, 12 }, { 10, 7 }, { 11, 7 }, { 288, 12 }, { 12, 7 }, { 9, 6 }, { 9, 6 }, { 8, 6 }, { 8, 6 }, { 7, 5 }, { 7, 5 }, { 7, 5 }, { 7, 5 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 6, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 1, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, { -2, 4 }, { -2, 4 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -3, 5 }, { 1792, 4 }, { 1792, 4 }, { 1984, 5 }, { 2048, 5 }, { 2112, 5 }, { 2176, 5 }, { 2240, 5 }, { 2304, 5 }, { 1856, 4 }, { 1856, 4 }, { 1920, 4 }, { 1920, 4 }, { 2368, 5 }, { 2432, 5 }, { 2496, 5 }, { 2560, 5 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 18, 3 }, { 52, 5 }, { 52, 5 }, { 640, 6 }, { 704, 6 }, { 768, 6 }, { 832, 6 }, { 55, 5 }, { 55, 5 }, { 56, 5 }, { 56, 5 }, { 1280, 6 }, { 1344, 6 }, { 1408, 6 }, { 1472, 6 }, { 59, 5 }, { 59, 5 }, { 60, 5 }, { 60, 5 }, { 1536, 6 }, { 1600, 6 }, { 24, 4 }, { 24, 4 }, { 24, 4 }, { 24, 4 }, { 25, 4 }, { 25, 4 }, { 25, 4 }, { 25, 4 }, { 1664, 6 }, { 1728, 6 }, { 320, 5 }, { 320, 5 }, { 384, 5 }, { 384, 5 }, { 448, 5 }, { 448, 5 }, { 512, 6 }, { 576, 6 }, { 53, 5 }, { 53, 5 }, { 54, 5 }, { 54, 5 }, { 896, 6 }, { 960, 6 }, { 1024, 6 }, { 1088, 6 }, { 1152, 6 }, { 1216, 6 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 64, 3 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 13, 1 }, { 23, 4 }, { 23, 4 }, { 50, 5 }, { 51, 5 }, { 44, 5 }, { 45, 5 }, { 46, 5 }, { 47, 5 }, { 57, 5 }, { 58, 5 }, { 61, 5 }, { 256, 5 }, { 16, 3 }, { 16, 3 }, { 16, 3 }, { 16, 3 }, { 17, 3 }, { 17, 3 }, { 17, 3 }, { 17, 3 }, { 48, 5 }, { 49, 5 }, { 62, 5 }, { 63, 5 }, { 30, 5 }, { 31, 5 }, { 32, 5 }, { 33, 5 }, { 40, 5 }, { 41, 5 }, { 22, 4 }, { 22, 4 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 14, 1 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 15, 2 }, { 128, 5 }, { 192, 5 }, { 26, 5 }, { 27, 5 }, { 28, 5 }, { 29, 5 }, { 19, 4 }, { 19, 4 }, { 20, 4 }, { 20, 4 }, { 34, 5 }, { 35, 5 }, { 36, 5 }, { 37, 5 }, { 38, 5 }, { 39, 5 }, { 21, 4 }, { 21, 4 }, { 42, 5 }, { 43, 5 }, { 0, 3 }, { 0, 3 }, { 0, 3 }, { 0, 3 } }; /* 2-D decoding table. */ impl_const cfd_node cf_2d_decode[] = { { 128, 11 }, { 144, 10 }, { 6, 7 }, { 0, 7 }, { 5, 6 }, { 5, 6 }, { 1, 6 }, { 1, 6 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -4, 4 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { -5, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, { -2, 4 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -1, 0 }, { -3, 3 } }; /* Uncompresssed decoding table. */ impl_const cfd_node cf_uncompressed_decode[] = { { 64, 12 }, { 5, 6 }, { 4, 5 }, { 4, 5 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { -1, 0 }, { -1, 0 }, { 8, 6 }, { 9, 6 }, { 6, 5 }, { 6, 5 }, { 7, 5 }, { 7, 5 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 5, 4 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 }, { 1, 2 } }; #if 0 /* Dummy executable code to pacify compilers. */ void scfdtab_dummy _((void)); void scfdtab_dummy() { } #endif /* end of former scfdtab.c */ /* scfd.c */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* CCITTFax decoding filter */ /* #include "gstypes.h" */ /* #include "scf.h" */ /* #include "scfx.h" */ /* Utility procedures */ int stream_move _((stream_cursor_read *, stream_cursor_write *)); /* in stream.c */ /* ------ CCITTFaxDecode ------ */ /* private_st_CFD_state(); */ /* Set default parameter values. */ static void s_CFD_set_defaults(register stream_state * st) { stream_CFD_state *const ss = (stream_CFD_state *) st; s_CFD_set_defaults_inline(ss); } /* Initialize CCITTFaxDecode filter */ static int s_CFD_init(stream_state * st) { stream_CFD_state *const ss = (stream_CFD_state *) st; int raster = ss->raster = ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign); unsigned char white = (ss->BlackIs1 ? 0 : 0xff); s_hcd_init_inline(ss); /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ ss->lbuf = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFD lbuf"); ss->lprev = 0; if (ss->lbuf == 0) return PTSFAX_ERRC; /****** WRONG ******/ if (ss->K != 0) { ss->lprev = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFD lprev"); if (ss->lprev == 0) return PTSFAX_ERRC; /****** WRONG ******/ /* Clear the initial reference line for 2-D encoding. */ ss->memset_(ss->lbuf, white, raster); /* Ensure that the scan of the reference line will stop. */ ss->lbuf[raster] = 0xa0; } ss->k_left = min(ss->K, 0); ss->run_color = 0; ss->damaged_rows = 0; ss->skipping_damage = false; ss->cbit = 0; ss->uncomp_run = 0; ss->rows_left = (ss->Rows <= 0 || ss->EndOfBlock ? -1 : ss->Rows + 1); ss->rpos = ss->wpos = raster - 1; ss->eol_count = 0; ss->invert = white; ss->min_left = 1; return 0; } /* Release the filter. */ static void s_CFD_release(stream_state * st) { stream_CFD_state *const ss = (stream_CFD_state *) st; gs_free_object(st->memory, ss->lprev, "CFD lprev(close)"); gs_free_object(st->memory, ss->lbuf, "CFD lbuf(close)"); } /* Declare the variables that hold the state. */ #define cfd_declare_state\ hcd_declare_state;\ register unsigned char *q;\ int qbit /* Load the state from the stream. */ #define cfd_load_state()\ hcd_load_state(),\ q = ss->lbuf + ss->wpos, qbit = ss->cbit /* Store the state back in the stream. */ #define cfd_store_state()\ hcd_store_state(),\ ss->wpos = q - ss->lbuf, ss->cbit = qbit /* Macros to get blocks of bits from the input stream. */ /* Invariants: 0 <= bits_left <= bits_size; */ /* bits [bits_left-1..0] contain valid data. */ #define avail_bits(n) hcd_bits_available(n) #define ensure_bits(n, outl) hcd_ensure_bits(n, outl) #define peek_bits(n) hcd_peek_bits(n) #define peek_var_bits(n) hcd_peek_var_bits(n) #define skip_bits(n) hcd_skip_bits(n) /* Get a run from the stream. */ #ifdef DEBUG # define IF_DEBUG(expr) expr #else # define IF_DEBUG(expr) DO_NOTHING #endif #define get_run(decode, initial_bits, min_bits, runlen, str, locl, outl)\ BEGIN\ const cfd_node *np;\ int clen;\ \ HCD_ENSURE_BITS_ELSE(initial_bits) {\ /* We might still have enough bits for the specific code. */\ if (bits_left < min_bits) goto outl;\ np = &decode[hcd_peek_bits_left() << (initial_bits - bits_left)];\ if ((clen = np->code_length) > bits_left) goto outl;\ goto locl;\ }\ np = &decode[peek_bits(initial_bits)];\ if ((clen = np->code_length) > initial_bits) {\ IF_DEBUG(unsigned int init_bits = peek_bits(initial_bits));\ if (!avail_bits(clen)) goto outl;\ clen -= initial_bits;\ skip_bits(initial_bits);\ ensure_bits(clen, outl); /* can't goto outl */\ np = &decode[np->run_length + peek_var_bits(clen)];\ if_debug4('W', "%s xcode=0x%x,%d rlen=%d\n", str,\ (init_bits << np->code_length) +\ peek_var_bits(np->code_length),\ initial_bits + np->code_length,\ np->run_length);\ skip_bits(np->code_length);\ } else {\ locl: if_debug4('W', "%s code=0x%x,%d rlen=%d\n", str,\ peek_var_bits(clen), clen, np->run_length);\ skip_bits(clen);\ }\ runlen = np->run_length;\ END /* Skip data bits for a white run. */ /* rlen is either less than 64, or a multiple of 64. */ #define skip_data(rlen, makeup_label)\ if ( (qbit -= rlen) < 0 )\ { q -= qbit >> 3, qbit &= 7;\ if ( rlen >= 64 ) goto makeup_label;\ } /* Invert data bits for a black run. */ /* If rlen >= 64, execute makeup_action: this is to handle */ /* makeup codes efficiently, since these are always a multiple of 64. */ #define invert_data(rlen, black_byte, makeup_action, d)\ if ( rlen > qbit )\ { *q++ ^= (1 << qbit) - 1;\ rlen -= qbit;\ switch ( rlen >> 3 )\ {\ case 7: /* original rlen possibly >= 64 */\ if ( rlen + qbit >= 64 ) goto d;\ *q++ = black_byte;\ case 6: *q++ = black_byte;\ case 5: *q++ = black_byte;\ case 4: *q++ = black_byte;\ case 3: *q++ = black_byte;\ case 2: *q++ = black_byte;\ case 1: *q = black_byte;\ rlen &= 7;\ if ( !rlen ) { qbit = 0; break; }\ q++;\ case 0: /* know rlen != 0 */\ qbit = 8 - rlen;\ *q ^= 0xff << qbit;\ break;\ default: /* original rlen >= 64 */\ d: ss->memset_(q, black_byte, rlen >> 3);\ q += rlen >> 3;\ rlen &= 7;\ if ( !rlen ) qbit = 0, q--;\ else qbit = 8 - rlen, *q ^= 0xff << qbit;\ makeup_action;\ }\ }\ else\ qbit -= rlen,\ *q ^= ((1 << rlen) - 1) << qbit /* Buffer refill for CCITTFaxDecode filter */ static int cf_decode_eol _((stream_CFD_state *, stream_cursor_read *)); static int cf_decode_1d _((stream_CFD_state *, stream_cursor_read *)); static int cf_decode_2d _((stream_CFD_state *, stream_cursor_read *)); static int cf_decode_uncompressed _((stream_CFD_state *, stream_cursor_read *)); static int s_CFD_process(stream_state * st, stream_cursor_read * pr, stream_cursor_write * pw, bool last) { stream_CFD_state *const ss = (stream_CFD_state *) st; int wstop = ss->raster - 1; int eol_count = ss->eol_count; int k_left = ss->k_left; int rows_left = ss->rows_left; int status = 0; (void)last; /**** pts ****/ #ifdef DEBUG const unsigned char *rstart = pr->ptr; const unsigned char *wstart = pw->ptr; #endif top: #ifdef DEBUG { hcd_declare_state; hcd_load_state(); if_debug8('w', "\ [w]CFD_process top: eol_count=%d, k_left=%d, rows_left=%d\n\ bits=0x%lx, bits_left=%d, read %u, wrote %u%s\n", eol_count, k_left, rows_left, (unsigned long) bits, bits_left, (unsigned int) (p - rstart), (unsigned int) (pw->ptr - wstart), (ss->skipping_damage ? ", skipping damage" : "")); } #endif if (ss->skipping_damage) { /* Skip until we reach an EOL. */ hcd_declare_state; int skip; status = 0; do { switch ((skip = cf_decode_eol(ss, pr))) { default: /* not EOL */ hcd_load_state(); skip_bits(-skip); hcd_store_state(); continue; case 0: /* need more input */ goto out; case 1: /* EOL */ { /* Back up over the EOL. */ hcd_load_state(); bits_left += run_eol_code_length; hcd_store_state(); } ss->skipping_damage = false; } } while (ss->skipping_damage); ss->damaged_rows++; } /* * Check for a completed input scan line. This isn't quite as * simple as it seems, because we could have run out of input data * between a makeup code and a 0-length termination code, or in a * 2-D line before a final horizontal code with a 0-length second * run. There's probably a way to think about this situation that * doesn't require a special check, but I haven't found it yet. */ if (ss->wpos == wstop && ss->cbit <= (-ss->Columns & 7) && (k_left == 0 ? !(ss->run_color & ~1) : ss->run_color == 0) ) { /* Check for completed data to be copied to the client. */ /* (We could avoid the extra copy step for 1-D, but */ /* it's simpler not to, and it doesn't cost much.) */ if (ss->rpos < ss->wpos) { stream_cursor_read cr; cr.ptr = ss->lbuf + ss->rpos; cr.limit = ss->lbuf + ss->wpos; status = stream_move(&cr, pw); ss->rpos = cr.ptr - ss->lbuf; if (status) goto out; } if (rows_left > 0 && --rows_left == 0) { status = EOFC; goto out; } if (ss->K != 0) { unsigned char *prev_bits = ss->lprev; ss->lprev = ss->lbuf; ss->lbuf = prev_bits; if (ss->K > 0) k_left = (k_left == 0 ? ss->K : k_left) - 1; } ss->rpos = ss->wpos = -1; ss->eol_count = eol_count = 0; ss->cbit = 0; ss->invert = (ss->BlackIs1 ? 0 : 0xff); ss->memset_(ss->lbuf, ss->invert, wstop + 1); ss->run_color = 0; /* * If EndOfLine is true, we want to include the unsigned char padding * in the string of initial zeros in the EOL. If EndOfLine * is false, we aren't sure what we should do.... */ if (ss->EncodedByteAlign & !ss->EndOfLine) ss->bits_left &= ~7; } /* If we're between scan lines, scan for EOLs. */ if (ss->wpos < 0) { while ((status = cf_decode_eol(ss, pr)) > 0) { if_debug0('w', "[w]EOL\n"); /* If we are in a Group 3 mixed regime, */ /* check the next bit for 1- vs. 2-D. */ if (ss->K > 0) { hcd_declare_state; hcd_load_state(); ensure_bits(1, out); /* can't fail */ k_left = (peek_bits(1) ? 0 : 1); skip_bits(1); hcd_store_state(); } ++eol_count; /* * According to Adobe, the decoder should always check for * the EOD sequence, regardless of EndOfBlock: the Red Book's * documentation of EndOfBlock is wrong. */ if (eol_count == (ss->K < 0 ? 2 : 6)) { status = EOFC; goto out; } } if (status == 0) /* input empty while scanning EOLs */ goto out; switch (eol_count) { case 0: if (ss->EndOfLine) { /* EOL is required, but none is present. */ status = PTSFAX_ERRC; goto check; } case 1: break; default: status = PTSFAX_ERRC; goto check; } } /* Now decode actual data. */ if (k_left < 0) { if_debug0('w', "[w2]new row\n"); status = cf_decode_2d(ss, pr); } else if (k_left == 0) { if_debug0('w', "[w1]new row\n"); status = cf_decode_1d(ss, pr); } else { if_debug1('w', "[w1]new 2-D row, %d left\n", k_left); status = cf_decode_2d(ss, pr); } if_debug3('w', "[w]CFD status = %d, wpos = %d, cbit = %d\n", status, ss->wpos, ss->cbit); check:switch (status) { case 1: /* output full */ goto top; case PTSFAX_ERRC: /* Check for special handling of damaged rows. */ if (ss->damaged_rows >= ss->DamagedRowsBeforeError || !(ss->EndOfLine && ss->K >= 0) ) break; /* Substitute undamaged data if appropriate. */ /****** NOT IMPLEMENTED YET ******/ { ss->wpos = wstop; ss->cbit = -ss->Columns & 7; ss->run_color = 0; } ss->skipping_damage = true; goto top; default: ss->damaged_rows = 0; /* finished a good row */ } out:ss->k_left = k_left; ss->rows_left = rows_left; ss->eol_count = eol_count; return status; } /* * Decode a leading EOL, if any. * If an EOL is present, skip over it and return 1; * if no EOL is present, read no input and return -N, where N is the * number of initial bits that can be skipped in the search for an EOL; * if more input is needed, return 0. * Note that if we detected an EOL, we know that we can back up over it; * if we detected an N-bit non-EOL, we know that at least N bits of data * are available in the buffer. */ static int cf_decode_eol(stream_CFD_state * ss, stream_cursor_read * pr) { hcd_declare_state; int zeros; int look_ahead; hcd_load_state(); for (zeros = 0; zeros < run_eol_code_length - 1; zeros++) { ensure_bits(1, out); if (peek_bits(1)) return -(zeros + 1); skip_bits(1); } /* We definitely have an EOL. Skip further zero bits. */ look_ahead = (ss->K > 0 ? 2 : 1); for (;;) { ensure_bits(look_ahead, back); if (peek_bits(1)) break; skip_bits(1); } skip_bits(1); hcd_store_state(); return 1; back: /* * We ran out of data while skipping zeros. * We know we are at a unsigned char boundary, and have just skipped * at least run_eol_code_length - 1 zeros. However, * bits_left may be 1 if look_ahead == 2. */ bits &= (1 << bits_left) - 1; bits_left += run_eol_code_length - 1; hcd_store_state(); out:return 0; } /* Decode a 1-D scan line. */ static int cf_decode_1d(stream_CFD_state * ss, stream_cursor_read * pr) { cfd_declare_state; unsigned char black_byte = (ss->BlackIs1 ? 0xff : 0); int end_bit = -ss->Columns & 7; unsigned char *stop = ss->lbuf - 1 + ss->raster; int run_color = ss->run_color; int status; int bcnt; cfd_load_state(); if_debug1('w', "[w1]entry run_color = %d\n", ss->run_color); if (ss->run_color > 0) goto db; else goto dw; #define q_at_stop() (q >= stop && (qbit <= end_bit || q > stop)) top:run_color = 0; if (q_at_stop()) goto done; dw: /* Decode a white run. */ get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, bcnt, "[w1]white", dwl, out0); if (bcnt < 0) { /* exceptional situation */ switch (bcnt) { case run_uncompressed: /* Uncompressed data. */ cfd_store_state(); bcnt = cf_decode_uncompressed(ss, pr); if (bcnt < 0) return bcnt; cfd_load_state(); if (bcnt) goto db; else goto dw; /*case run_error: */ /*case run_zeros: *//* Premature end-of-line. */ default: status = PTSFAX_ERRC; goto out; } } skip_data(bcnt, dwx); if (q_at_stop()) { run_color = 0; /* not inside a run */ goto done; } run_color = 1; db: /* Decode a black run. */ get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, bcnt, "[w1]black", dbl, out1); if (bcnt < 0) { /* All exceptional codes are invalid here. */ /****** WRONG, uncompressed IS ALLOWED ******/ status = PTSFAX_ERRC; goto out; } /* Invert bits designated by black run. */ invert_data(bcnt, black_byte, goto dbx, idb); goto top; dwx: /* If we run out of data after a makeup code, */ /* note that we are still processing a white run. */ run_color = -1; goto dw; dbx: /* If we run out of data after a makeup code, */ /* note that we are still processing a black run. */ run_color = 2; goto db; done:if (q > stop || qbit < end_bit) status = PTSFAX_ERRC; else status = 1; out:cfd_store_state(); ss->run_color = run_color; if_debug1('w', "[w1]exit run_color = %d\n", run_color); return status; out0: /* We already set run_color to 0 or -1. */ status = 0; goto out; out1: /* We already set run_color to 1 or 2. */ status = 0; goto out; } /* Decode a 2-D scan line. */ static int cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr) { cfd_declare_state; unsigned char invert_white = (ss->BlackIs1 ? 0 : 0xff); unsigned char black_byte = ~invert_white; unsigned char invert = ss->invert; int end_count = -ss->Columns & 7; unsigned int raster = ss->raster; unsigned char *q0 = ss->lbuf; unsigned char *prev_q01 = ss->lprev + 1; unsigned char *endptr = q0 - 1 + raster; int init_count = raster << 3; register int count; int rlen; int status; cfd_load_state(); count = ((endptr - q) << 3) + qbit; endptr[1] = 0xa0; /* a unsigned char with some 0s and some 1s, */ /* to ensure run scan will stop */ if_debug1('W', "[w2]raster=%d\n", raster); switch (ss->run_color) { case -2: ss->run_color = 0; goto hww; case -1: ss->run_color = 0; goto hbw; case 1: ss->run_color = 0; goto hwb; case 2: ss->run_color = 0; goto hbb; /*case 0: */ } top:if (count <= end_count) { status = (count < end_count ? PTSFAX_ERRC : 1); goto out; } /* If invert == invert_white, white and black have their */ /* correct meanings; if invert == ~invert_white, */ /* black and white are interchanged. */ if_debug1('W', "[w2]%4d:\n", count); #ifdef DEBUG /* Check the invariant between q, qbit, and count. */ { int pcount = (endptr - q) * 8 + qbit; if (pcount != count) dlprintf2("[w2]Error: count=%d pcount=%d\n", count, pcount); } #endif /* * We could just use get_run here, but we can do better. However, * we must be careful to handle the case where the very last codes * in the input stream are 1-bit "vertical 0" codes: we can't just * use ensure_bits(3, ...) and go to get more data if it fails. */ ensure_bits(3, out3); #define vertical_0 (countof(cf2_run_vertical) / 2) switch (peek_bits(3)) { default /*4..7*/ : /* vertical(0) */ v0: skip_bits(1); rlen = vertical_0; break; case 2: /* vertical(+1) */ skip_bits(3); rlen = vertical_0 + 1; break; case 3: /* vertical(-1) */ skip_bits(3); rlen = vertical_0 - 1; break; case 1: /* horizontal */ skip_bits(3); if (invert == invert_white) goto hww; else goto hbb; case 0: /* everything else */ get_run(cf_2d_decode, cfd_2d_initial_bits, cfd_2d_min_bits, rlen, "[w2]", d2l, out0); /* rlen may be run2_pass, run_uncompressed, or */ /* 0..countof(cf2_run_vertical)-1. */ if (rlen < 0) switch (rlen) { case run2_pass: break; case run_uncompressed: { int which; cfd_store_state(); which = cf_decode_uncompressed(ss, pr); if (which < 0) { status = which; goto out; } cfd_load_state(); /****** ADJUST count ******/ invert = (which ? ~invert_white : invert_white); } goto top; default: /* run_error, run_zeros */ status = PTSFAX_ERRC; goto out; } } /* Interpreting the run requires scanning the */ /* previous ('reference') line. */ { int prev_count = count; unsigned char prev_data; int dlen; static const unsigned char count_bit[8] = {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40}; unsigned char *prev_q = prev_q01 + (q - q0); int plen; if (!(count & 7)) prev_q++; /* because of skip macros */ prev_data = prev_q[-1] ^ invert; /* Find the b1 transition. */ if ((prev_data & count_bit[prev_count & 7]) && (prev_count < init_count || invert != invert_white) ) { /* Look for changing white first. */ if_debug1('W', " data=0x%x", prev_data); skip_black_pixels(prev_data, prev_q, prev_count, invert, plen); if (prev_count < end_count) /* overshot */ prev_count = end_count; if_debug1('W', " b1 other=%d", prev_count); } if (prev_count != end_count) { if_debug1('W', " data=0x%x", prev_data); skip_white_pixels(prev_data, prev_q, prev_count, invert, plen); if (prev_count < end_count) /* overshot */ prev_count = end_count; if_debug1('W', " b1 same=%d", prev_count); } /* b1 = prev_count; */ if (rlen == run2_pass) { /* Pass mode. Find b2. */ if (prev_count != end_count) { if_debug1('W', " data=0x%x", prev_data); skip_black_pixels(prev_data, prev_q, prev_count, invert, plen); if (prev_count < end_count) /* overshot */ prev_count = end_count; } /* b2 = prev_count; */ if_debug2('W', " b2=%d, pass %d\n", prev_count, count - prev_count); } else { /* Vertical coding. */ /* Remember that count counts *down*. */ prev_count += rlen - vertical_0; /* a1 */ if_debug2('W', " vertical %d -> %d\n", rlen - vertical_0, prev_count); } /* Now either invert or skip from count */ /* to prev_count, and reset count. */ if (invert == invert_white) { /* Skip data bits. */ q = endptr - (prev_count >> 3); qbit = prev_count & 7; } else { /* Invert data bits. */ dlen = count - prev_count; invert_data(dlen, black_byte, DO_NOTHING, idd); } count = prev_count; if (rlen >= 0) /* vertical mode */ invert = ~invert; /* polarity changes */ } goto top; out3: if (bits_left > 0 && peek_bits(1)) { /* This is a 1-bit "vertical 0" code, which we can still process. */ goto v0; } /* falls through */ out0:status = 0; /* falls through */ out:cfd_store_state(); ss->invert = invert; return status; /* * We handle horizontal decoding here, so that we can * branch back into it if we run out of input data. */ /* White, then black. */ hww:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, rlen, " white", wwl, outww); if ((count -= rlen) < end_count) { status = PTSFAX_ERRC; goto out; } skip_data(rlen, hww); /* Handle the second half of a white-black horizontal code. */ hwb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, rlen, " black", wbl, outwb); if ((count -= rlen) < end_count) { status = PTSFAX_ERRC; goto out; } invert_data(rlen, black_byte, goto hwb, ihwb); goto top; outww:ss->run_color = -2; goto out0; outwb:ss->run_color = 1; goto out0; /* Black, then white. */ hbb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, rlen, " black", bbl, outbb); if ((count -= rlen) < end_count) { status = PTSFAX_ERRC; goto out; } invert_data(rlen, black_byte, goto hbb, ihbb); /* Handle the second half of a black-white horizontal code. */ hbw:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, rlen, " white", bwl, outbw); if ((count -= rlen) < end_count) { status = PTSFAX_ERRC; goto out; } skip_data(rlen, hbw); goto top; outbb:ss->run_color = 2; goto out0; outbw:ss->run_color = -1; goto out0; } #if 1 /*************** */ static int cf_decode_uncompressed(stream_CFD_state * ss, stream_cursor_read * pr) { (void)ss; (void)pr; /**** pts ****/ return PTSFAX_ERRC; } #else /*************** */ /* Decode uncompressed data. */ /* (Not tested: no sample data available!) */ /****** DOESN'T CHECK FOR OVERFLOWING SCAN LINE ******/ static int cf_decode_uncompressed(stream * s) { cfd_declare_state; const cfd_node *np; int clen, rlen; cfd_load_state(); while (1) { ensure_bits(cfd_uncompressed_initial_bits, NOOUT); np = &cf_uncompressed_decode[peek_bits(cfd_uncompressed_initial_bits)]; clen = np->code_length; rlen = np->run_length; if (clen > cfd_uncompressed_initial_bits) { /* Must be an exit code. */ break; } if (rlen == cfd_uncompressed_initial_bits) { /* Longest representable white run */ if_debug1('W', "[wu]%d\n", rlen); if ((qbit -= cfd_uncompressed_initial_bits) < 0) qbit += 8, q++; } else { if_debug1('W', "[wu]%d+1\n", rlen); if (qbit -= rlen < 0) qbit += 8, q++; *q ^= 1 << qbit; } skip_bits(clen); } clen -= cfd_uncompressed_initial_bits; skip_bits(cfd_uncompressed_initial_bits); ensure_bits(clen, NOOUT); np = &cf_uncompressed_decode[rlen + peek_var_bits(clen)]; rlen = np->run_length; skip_bits(np->code_length); if_debug1('w', "[wu]exit %d\n", rlen); if (rlen >= 0) { /* Valid exit code, rlen = 2 * run length + next polarity */ if ((qbit -= rlen >> 1) < 0) qbit += 8, q++; rlen &= 1; } out: /******* WRONG ******/ cfd_store_state(); return rlen; } #endif /*************** */ /* Move as much data as possible from one buffer to another. */ /* Return 0 if the input became empty, 1 if the output became full. */ int stream_move(stream_cursor_read * pr, stream_cursor_write * pw) { unsigned int rcount = pr->limit - pr->ptr; unsigned int wcount = pw->limit - pw->ptr; unsigned int count; int status; if (rcount <= wcount) count = rcount, status = 0; else count = wcount, status = 1; /**** pts ****/ /* Dat: memcpy should be enough instead of memmove */ #if 0 memmove(pw->ptr + 1, pr->ptr + 1, count); pr->ptr += count; pw->ptr += count; #else while (count--!=0) *++pw->ptr=*++pr->ptr; #endif return status; } #if 1 /**** pts ****/ /* Stream template */ const stream_template s_CFD_template = {/*0, &st_CFD_state*/ s_CFD_init, s_CFD_process, 1, 1, s_CFD_release, s_CFD_set_defaults, 0 }; #endif /* end of former scfd.c */ #endif /* USE_BUILTIN_FAXD */ #if USE_BUILTIN_FAXE || USE_BUILTIN_FAXD /* shc.c */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Support code for shc.h */ /* #include "scommon.h" */ /* #include "shc.h" */ /* #include "scfx.h" */ /**** pts ****/ /* struct stream_hc_state_s */ /* ------ Encoding ------ */ /* Empty the 1-word buffer onto the output stream. */ /* q has already been incremented. */ static void hc_put_code_proc(bool reverse_bits, unsigned char * q, unsigned int cw) { #define cb(n) ((unsigned char)(cw >> (n * 8))) if (reverse_bits) { #if hc_bits_size > 16 q[-3] = byte_reverse_bits[cb(3)]; q[-2] = byte_reverse_bits[cb(2)]; #endif q[-1] = byte_reverse_bits[cb(1)]; q[0] = byte_reverse_bits[cb(0)]; } else { #if hc_bits_size > 16 q[-3] = cb(3); q[-2] = cb(2); #endif q[-1] = cb(1); q[0] = cb(0); } #undef cb } /* Put out any final bytes. */ /* Note that this does a store_state, but not a load_state. */ static unsigned char * hc_put_last_bits_proc(stream_hc_state * ss, unsigned char * q, unsigned int bits, int bits_left) { while (bits_left < hc_bits_size) { unsigned char c = (unsigned char) (bits >> (hc_bits_size - 8)); if (ss->FirstBitLowOrder) c = byte_reverse_bits[c]; *++q = c; bits <<= 8; bits_left += 8; } ss->bits = bits; ss->bits_left = bits_left; return q; } /* end of former shc.c */ /* gsbittab.c */ /*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */ /* Tables for bit operations */ /* #include "gstypes.h" */ /* #include "gsbittab.h" */ /* ---------------- Byte processing tables ---------------- */ /* * byte_reverse_bits[B] = the unsigned char B with the order of bits reversed. */ impl_const unsigned char byte_reverse_bits[256] = { bit_table_8(0, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80) }; /* * byte_right_mask[N] = a unsigned char with N trailing 1s, 0 <= N <= 8. */ impl_const unsigned char byte_right_mask[9] = { 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; /* * byte_count_bits[B] = the number of 1-bits in a unsigned char with value B. */ impl_const unsigned char byte_count_bits[256] = { bit_table_8(0, 1, 1, 1, 1, 1, 1, 1, 1) }; /* ---------------- Scanning tables ---------------- */ /* * byte_bit_run_length_N[B], for 0 <= N <= 7, gives the length of the * run of 1-bits starting at bit N in a unsigned char with value B, * numbering the bits in the unsigned char as 01234567. If the run includes * the low-order bit (i.e., might be continued into a following unsigned char), * the run length is increased by 8. */ #define t8(n) n,n,n,n,n+1,n+1,n+2,n+11 #define r8(n) n,n,n,n,n,n,n,n #define r16(n) r8(n),r8(n) #define r32(n) r16(n),r16(n) #define r64(n) r32(n),r32(n) #define r128(n) r64(n),r64(n) impl_const unsigned char byte_bit_run_length_0[256] = { r128(0), r64(1), r32(2), r16(3), r8(4), t8(5) }; impl_const unsigned char byte_bit_run_length_1[256] = { r64(0), r32(1), r16(2), r8(3), t8(4), r64(0), r32(1), r16(2), r8(3), t8(4) }; impl_const unsigned char byte_bit_run_length_2[256] = { r32(0), r16(1), r8(2), t8(3), r32(0), r16(1), r8(2), t8(3), r32(0), r16(1), r8(2), t8(3), r32(0), r16(1), r8(2), t8(3) }; impl_const unsigned char byte_bit_run_length_3[256] = { r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2), r16(0), r8(1), t8(2) }; impl_const unsigned char byte_bit_run_length_4[256] = { r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), }; #define rr8(a,b,c,d,e,f,g,h)\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h impl_const unsigned char byte_bit_run_length_5[256] = { rr8(0, 0, 0, 0, 1, 1, 2, 11) }; impl_const unsigned char byte_bit_run_length_6[256] = { rr8(0, 0, 1, 10, 0, 0, 1, 10) }; impl_const unsigned char byte_bit_run_length_7[256] = { rr8(0, 9, 0, 9, 0, 9, 0, 9) }; /* Pointer tables indexed by bit number. */ impl_const unsigned char *const byte_bit_run_length[8] = { byte_bit_run_length_0, byte_bit_run_length_1, byte_bit_run_length_2, byte_bit_run_length_3, byte_bit_run_length_4, byte_bit_run_length_5, byte_bit_run_length_6, byte_bit_run_length_7 }; impl_const unsigned char *const byte_bit_run_length_neg[8] = { byte_bit_run_length_0, byte_bit_run_length_7, byte_bit_run_length_6, byte_bit_run_length_5, byte_bit_run_length_4, byte_bit_run_length_3, byte_bit_run_length_2, byte_bit_run_length_1 }; /* * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters * denote the individual bits of the unsigned char. */ impl_const unsigned char byte_acegbdfh_to_abcdefgh[256] = { bit_table_8(0, 0x80, 0x20, 0x08, 0x02, 0x40, 0x10, 0x04, 0x01) }; #if 0 /* Some C compilers insist on having executable code in every file.... */ void gsbittab_dummy _((void)); /* for picky compilers */ void gsbittab_dummy(void) { } #endif /* end of former gsbittab.c */ #endif /* USE_BUILTIN_FAXE || USE_BUILTIN_FAXD */ /* end of pts_fax.c */ sam2p-0.49.2/pts_fax.h0000644000175100017510000004616112211371426012654 0ustar ptspts/* * pts_fax.h -- a compact CCITTFax compressor and uncompressor) interface * compiled by pts@fazekas.hu at Sun Jul 7 19:51:42 CEST 2002 * * For usage example, see fax_test.c. * * algorithm ripped from GNU Ghostscript, implementation and (C): * Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. GNU Ghostscript is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. GNU Ghostscript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program so you can know your rights and responsibilities. It should be in a file named doc/COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. */ /*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */ /* CCITTFax filter state definition */ /* Requires strimpl.h */ #ifndef PTS_FAX_H # define PTS_FAX_H 1 #ifdef __GNUC__ #pragma interface #endif /* #include "scommon.h" */ /*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */ /* Definitions common to stream clients and implementors */ /* #ifndef scommon_DEFINED */ /* # define scommon_DEFINED */ /**** pts ****/ #if 0 #include "gsmemory.h" #include "gsstype.h" /* for extern_st */ #endif /**** pts ****/ #include "config2.h" /* ^^^ should #define SIZEOF_INT * ^^^ should #define _, and ___ * ^^^ should #define? USE_BULITIN_FAXD * ^^^ should #define? USE_BULITIN_FAXE * ^^^ should define const */ #if 0 /* example for Linux i386 gcc 2.95: */ #define SIZEOF_INT 4 #if ((defined(__STDC__) || defined(__PROTOTYPES__)) && !defined(NO_PROTO)) || defined(__cplusplus) # define _(args) args # define OF(args) args # define ___(arg2s,arg1s,argafter) arg2s /* Dat: no direct comma allowed in args :-( */ #else # define _(args) () # define OF(args) () # define ___(arg2s,arg1s,argafter) arg1s argafter /* Dat: no direct comma allowed in args :-( */ #endif #define USE_BUILTIN_FAXE 1 #define USE_BUILITN_FAXD 1 #endif typedef void (*gssss_memset_t)(void *s, int c, unsigned n); /* Imp: not `unsigned' len */ /** The function must not return out of memory. */ typedef void* (*gssss_xalloc_t)(unsigned len); /* Imp: not `unsigned' len */ typedef void (*gssss_free_t)(void *ptr); typedef void (*gssss_memcpy_t)(void *dest, const void *src, unsigned len); /* Imp: not `unsigned' len */ /* * There are three major structures involved in the stream package. * * A stream is an "object" that owns a buffer, which it uses to implement * unsigned char-oriented sequential access in a standard way, and a set of * procedures that handle things like buffer refilling. See stream.h * for more information about streams. */ #ifndef stream_DEFINED # define stream_DEFINED typedef struct stream_s stream; #endif /* * A stream_state records the state specific to a given variety of stream. * The buffer processing function of a stream maintains this state. */ typedef struct stream_state_s stream_state; /* * A stream_template provides the information needed to create a stream. * The client must fill in any needed setup parameters in the appropriate * variety of stream_state, and then call the initialization function * provided by the template. See strimpl.h for more information about * stream_templates. */ typedef struct stream_template_s stream_template; /* * The stream package works with bytes, not chars. * This is to ensure unsigned representation on all systems. * A stream currently can only be read or written, not both. * Note also that the read procedure returns an int, not a char or a unsigned char; * we use negative values to indicate exceptional conditions. * (We cast these values to int explicitly, because some compilers * don't do this if the other arm of a conditional is a unsigned char.) */ /* End of data */ #define PTSFAX_EOFC ((int)(-1)) /* Error */ #define PTSFAX_ERRC ((int)(-2)) /* Interrupt */ /* #define INTC ((int)(-3)) */ /****** INTC IS NOT USED YET ******/ /* Callout */ /* #define CALLC ((int)(-4)) */ #define max_stream_exception 4 /* The following hack is needed for initializing scan_char_array in iscan.c. */ #define stream_exception_repeat(x) x, x, x, x /* * Define cursors for reading from or writing into a buffer. * We lay them out this way so that we can alias * the write pointer and the read limit. */ typedef struct stream_cursor_read_s { const unsigned char *ptr; const unsigned char *limit; unsigned char *_skip; } stream_cursor_read; typedef struct stream_cursor_write_s { const unsigned char *_skip; unsigned char *ptr; unsigned char *limit; } stream_cursor_write; typedef union stream_cursor_s { stream_cursor_read r; stream_cursor_write w; } stream_cursor; /* * Define the prototype for the procedures known to both the generic * stream code and the stream implementations. */ /* Initialize the stream state (after the client parameters are set). */ #define stream_proc_init(proc)\ int proc _((stream_state *)) /* Process a buffer. See strimpl.h for details. */ #define stream_proc_process(proc)\ int proc _((stream_state *, stream_cursor_read *,\ stream_cursor_write *, bool)) /* Release the stream state when closing. */ #define stream_proc_release(proc)\ void proc _((stream_state *)) /* Initialize the client parameters to default values. */ #define stream_proc_set_defaults(proc)\ void proc _((stream_state *)) /* Reinitialize any internal stream state. Note that this does not */ /* affect buffered data. We declare this as returning an int so that */ /* it can be the same as the init procedure; however, reinit cannot fail. */ #define stream_proc_reinit(proc)\ int proc _((stream_state *)) /* Report an error. Note that this procedure is stored in the state, */ /* not in the main stream structure. */ #define stream_proc_report_error(proc)\ int proc _((stream_state *, const char *)) stream_proc_report_error(s_no_report_error); /* * Some types of streams have the ability to read their parameters from * a parameter list, and to write all (or only the non-default) * parameters to a parameter list. Since these are not virtual * procedures for the stream (they operate on stream_state structures * even if no actual stream has been created), we name them differently. */ #define stream_state_proc_get_params(proc, state_type)\ int proc _((gs_param_list *plist, const state_type *ss, bool all)) #define stream_state_proc_put_params(proc, state_type)\ int proc _((gs_param_list *plist, state_type *ss)) /* * Define a generic stream state. If a processing procedure has no * state of its own, it can use stream_state; otherwise, it must * create a "subclass". There is a hack in stream.h to allow the stream * itself to serve as the "state" of a couple of heavily used stream types. * * In order to simplify the structure descriptors for concrete streams, * we require that the generic stream state not contain any pointers * to garbage-collectable storage. */ #define STREAM_MAX_ERROR_STRING 79 #define stream_state_common\ const stream_template *template_; /**** pts C++ */\ gssss_memset_t memset_;\ gssss_xalloc_t xalloc_;\ gssss_free_t free_;\ gssss_memcpy_t memcpy_;\ /* gs_memory_t *memory; */ /**** pts ****/ \ stream_proc_report_error((*report_error));\ int min_left; /* required bytes for lookahead */ \ char error_string[STREAM_MAX_ERROR_STRING + 1] struct stream_state_s { stream_state_common; }; /* extern_st(st_stream_state); */ /**** pts ****/ #define public_st_stream_state() /* in stream.c */\ gs_public_st_simple(st_stream_state, stream_state, "stream_state") /**** pts ****/ /* original strimpl.h coming */ /*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */ /* Definitions for stream implementors */ /* Requires stdio.h */ /* * The 'process' procedure does the real work of the stream. * It must process as much input information (from pr->ptr + 1 through * pr->limit) as it can, subject to space available for output * (pw->ptr + 1 through pw->limit), updating pr->ptr and pw->ptr. * * The procedure return value must be one of: * PTSFAX_EOFC - an end-of-data pattern was detected in the input, * or no more input can be processed for some other reason (e.g., * the stream was told only to read a certain amount of data). * PTSFAX_ERRC - a syntactic error was detected in the input. * 0 - more input data is needed. * 1 - more output space is needed. * If the procedure returns PTSFAX_EOFC, it can assume it will never be called * again for that stream. * * If the procedure is called with last = 1, this is an indication that * no more input will ever be supplied (after the input in the current * buffer defined by *pr); the procedure should produce as much output * as possible, including an end-of-data marker if applicable. In this * case: * - If the procedure returns 1, it may be called again (also with * last = 1). * - If the procedure returns any other value other than 1, the * procedure will never be called again for that stream. * - If the procedure returns 0, this is taken as equivalent to * returning PTSFAX_EOFC. * - If the procedure returns PTSFAX_EOFC (or 0), the stream's end_status * is set to PTSFAX_EOFC, meaning no more writing is allowed. * * Note that these specifications do not distinguish input from output * streams. This is deliberate: The processing procedures should work * regardless of which way they are oriented in a stream pipeline. * (The PostScript language does take a position as whether any given * filter may be used for input or output, but this occurs at a higher level.) * * The value returned by the process procedure of a stream whose data source * or sink is external (i.e., not another stream) is interpreted slightly * differently. For an external data source, a return value of 0 means * "no more input data are available now, but more might become available * later." For an external data sink, a return value of 1 means "there is * no more room for output data now, but there might be room later." * * It appears that the Adobe specifications, read correctly, require that when * the process procedure of a decoding filter has filled up the output * buffer, it must still peek ahead in the input to determine whether or not * the next thing in the input stream is EOD. If the next thing is an EOD (or * end-of-data, indicated by running out of input data with last = true), the * process procedure must return PTSFAX_EOFC; if the next thing is definitely not * an EOD, the process procedure must return 1 (output full) (without, of * course, consuming the non-EOD datum); if the procedure cannot determine * whether or not the next thing is an EOD, it must return 0 (need more input). * Decoding filters that don't have EOD (for example, NullDecode) can use * a simpler algorithm: if the output buffer is full, then if there is more * input, return 1, otherwise return 0 (which is taken as PTSFAX_EOFC if last * is true). All this may seem a little awkward, but it is needed in order * to have consistent behavior regardless of where buffer boundaries fall -- * in particular, if a buffer boundary falls just before an EOD. It is * actually quite easy to implement if the main loop of the process * procedure tests for running out of input rather than for filling the * output: with this structure, exhausting the input always returns 0, * and discovering that the output buffer is full when attempting to store * more output always returns 1. * * Even this algorithm for handling end-of-buffer is not sufficient if an * EOD falls just after a buffer boundary, but the generic stream code * handles this case: the process procedures need only do what was just * described. */ /* * The set_defaults procedure in the template has a dual purpose: it sets * default values for all parameters that the client can set before calling * the init procedure, and it also must initialize all pointers in the * stream state to a value that will be valid for the garbage collector * (normally 0). The latter implies that: * * Any stream whose state includes additional pointers (beyond those * in stream_state_common) must have a set_defaults procedure. */ /* * Note that all decoding filters that require an explicit EOD in the * source data must have an init procedure that sets min_left = 1. * This effectively provides a 1-unsigned char lookahead in the source data, * which is required so that the stream can close itself "after reading * the last unsigned char of data" (per Adobe specification), as noted above. */ /* * Define a template for creating a stream. * * The meaning of min_in_size and min_out_size is the following: * If the amount of input information is at least min_in_size, * and the available output space is at least min_out_size, * the process procedure guarantees that it will make some progress. * (It may make progress even if this condition is not met, but this is * not guaranteed.) */ struct stream_template_s { /* Define the structure type for the stream state. */ /* gs_memory_type_ptr_t stype; */ /**** pts ****/ /* Define an optional initialization procedure. */ stream_proc_init((*init)); /* Define the processing procedure. */ /* (The init procedure can reset other procs if it wants.) */ stream_proc_process((*process)); /* Define the minimum buffer sizes. */ unsigned int min_in_size; /* minimum size for process input */ unsigned int min_out_size; /* minimum size for process output */ /* Define an optional releasing procedure. */ stream_proc_release((*release)); /* Define an optional parameter defaulting and pointer initialization */ /* procedure. */ stream_proc_set_defaults((*set_defaults)); /* Define an optional reinitialization procedure. */ stream_proc_reinit((*reinit)); }; #if 0 /* Hex decoding utility procedure */ typedef enum { hex_ignore_garbage = 0, hex_ignore_whitespace = 1, hex_ignore_leading_whitespace = 2 } hex_syntax; int s_hex_process _((stream_cursor_read *, stream_cursor_write *, int *, hex_syntax)); /* in sstring.c */ #endif /* end of former strimpl.h */ /* #endif */ /* scommon_INCLUDED */ /* end of former scommon.h */ /* ------ Common state ------ */ /* * Define the common stream state for Huffman-coded filters. * Invariants when writing: * 0 <= bits_left <= hc_bits_size; * Only the leftmost (hc_bits_size - bits_left) bits of bits * contain valid data. */ #define stream_hc_state_common\ stream_state_common;\ /* The client sets the following before initialization. */\ bool FirstBitLowOrder;\ /* The following are updated dynamically. */\ unsigned int bits; /* most recent bits of input or */\ /* current bits of output */\ int bits_left /* # of valid low bits (input) or */\ /* unused low bits (output) in above, */\ /* 0 <= bits_left <= 7 */ typedef struct stream_hc_state_s { stream_hc_state_common; } stream_hc_state; /* Common state */ #define stream_CF_state_common\ stream_hc_state_common;\ /* The client sets the following before initialization. */\ bool Uncompressed;\ int K;\ bool EndOfLine;\ bool EncodedByteAlign;\ int Columns;\ int Rows;\ bool EndOfBlock;\ bool BlackIs1;\ int DamagedRowsBeforeError; /* (Decode only) */\ /*bool FirstBitLowOrder;*/ /* in stream_hc_state_common */\ int DecodedByteAlign;\ /* The init procedure sets the following. */\ unsigned int raster;\ unsigned char *lbuf; /* current scan line buffer */\ /* (only if decoding or 2-D encoding) */\ unsigned char *lprev; /* previous scan line buffer (only if 2-D) */\ /* The following are updated dynamically. */\ int k_left /* number of next rows to encode in 2-D */\ /* (only if K > 0) */ typedef struct stream_CF_state_s { stream_CF_state_common; } stream_CF_state; /* Define common default parameter setting. */ #define s_CF_set_defaults_inline(ss)\ ((ss)->Uncompressed = false,\ (ss)->K = 0,\ (ss)->EndOfLine = false,\ (ss)->EncodedByteAlign = false,\ (ss)->Columns = 1728,\ (ss)->Rows = 0,\ (ss)->EndOfBlock = true,\ (ss)->BlackIs1 = false,\ /* Added by Adobe since the Red Book */\ (ss)->DamagedRowsBeforeError = 0, /* always set, for s_CF_get_params */\ (ss)->FirstBitLowOrder = false,\ /* Added by us */\ (ss)->DecodedByteAlign = 1,\ /* Clear pointers */\ (ss)->lbuf = 0, (ss)->lprev = 0) /* CCITTFaxEncode */ typedef struct stream_CFE_state_s { stream_CF_state_common; /* The init procedure sets the following. */ int max_code_bytes; /* max # of bytes for an encoded line */ unsigned char *lcode; /* buffer for encoded output line */ /* The following change dynamically. */ int read_count; /* # of bytes to copy into lbuf */ int write_count; /* # of bytes to copy out of lcode */ int code_bytes; /* # of occupied bytes in lcode */ } stream_CFE_state; #define private_st_CFE_state() /* in scfe.c */\ gs_private_st_ptrs3(st_CFE_state, stream_CFE_state, "CCITTFaxEncode state",\ cfe_enum_ptrs, cfe_reloc_ptrs, lbuf, lprev, lcode) #define s_CFE_set_defaults_inline(ss)\ (s_CF_set_defaults_inline(ss), (ss)->lcode = 0) #if USE_BUILTIN_FAXE /**** pts ****/ #if SIZEOF_INT > 2 # define cfe_max_width (2560 * 32000 * 2 / 3) #else # define cfe_max_width ((int)((unsigned)-1/2 - 40)) /* avoid overflows */ #endif #ifdef __cplusplus extern "C" #else extern #endif const stream_template s_CFE_template; #endif /* CCITTFaxDecode */ typedef struct stream_CFD_state_s { stream_CF_state_common; int cbit; /* bits left to fill in current decoded */ /* unsigned char at lbuf[wpos] (0..7) */ int rows_left; /* number of rows left */ int rpos; /* rptr for copying lbuf to client */ int wpos; /* rlimit/wptr for filling lbuf or */ /* copying to client */ int eol_count; /* number of EOLs seen so far */ unsigned char invert; /* current value of 'white' */ /* for 2-D decoding */ int run_color; /* -1 if processing white run, */ /* 0 if between runs but white is next, */ /* 1 if between runs and black is next, */ /* 2 if processing black run */ int damaged_rows; /* # of consecutive damaged rows preceding */ /* the current row */ bool skipping_damage; /* true if skipping a damaged row looking */ /* for EOL */ /* The following are not used yet. */ int uncomp_run; /* non-0 iff we are in an uncompressed */ /* run straddling a scan line (-1 if white, */ /* 1 if black) */ int uncomp_left; /* # of bits left in the run */ int uncomp_exit; /* non-0 iff this is an exit run */ /* (-1 if next run white, 1 if black) */ } stream_CFD_state; #define private_st_CFD_state() /* in scfd.c */\ gs_private_st_ptrs2(st_CFD_state, stream_CFD_state, "CCITTFaxDecode state",\ cfd_enum_ptrs, cfd_reloc_ptrs, lbuf, lprev) #define s_CFD_set_defaults_inline(ss)\ s_CF_set_defaults_inline(ss) #if USE_BUILTIN_FAXD extern const stream_template s_CFD_template; #endif #endif /* pts_fax.h */ sam2p-0.49.2/examples/pts2.pbm0000644000175100017510000006726012211371426014250 0ustar ptsptsP4 #Created with The GIMP 419 534 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU""""""""""""*"""""""""************************** UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUQ"""""*""""""""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUT@ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU********************+++UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@""""""""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@*UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@**********"""************+*++UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@*UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@"""""""""""""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@"****"****""""*******+ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ꪪUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@"*""""""""""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ꪪUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@**********"***"*"***++ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUUUUUUUUUUwwwwwwwuUUUUUUUUUUUUUUUUUUUUUU@"""""""""""""""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUUUUUUUUUUWUUUwwwwwUUUUUUUUUUUUUUUUUUUUU@"**"****"********+***+ UUUUUUUUUUUUUUUUUUUUUUUUUU]UUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUUUUUUWwwwwwuUUUUUUUUUUUUUUUUUUUU@""""""""""""""""**UUUUUUUUUUUUUUUUUUUUUUUUUU]UUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUUUUUUUUUUUUUWwwwwwwuUUUUUUUUUUUUUUUUUUU@"""****"""*""*""+** UUUUUUUUUUUUUUUUUUUUUUUUU_]UUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUuUUUWwwwwwwwwUUUUUUUUUUUUUUUUUUU@"""""""""""""""" UUUUUUUUUUUUUUUUUUUUUU]UUUUUUUUUUUUUUUUUUUU@*ꪪUUUUUUUUUUUUUUUUWUWUUUWwwWwwwwwuUUUUUUUUUUUUUUUUUU@"*"****"""""""*++++ UUUUUUUUUUUUUUUU]UUUUU]U_]UUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUuWuUUwwwwwwwwwwwwUUUUUUUUUUUUUUUUUU@""""""""""""""UUUUUUUUUUUUUUUUU]UUUUUUUUUUUUUUUUUUUU@*ꪪUUUUUUUUUUUUUUWwWuWUWwwwwwwwwUUUUUUUUUUUUUUUUUU@"""***""""""*+ UUUUUUUUUUUUUU]U]UUU]UU]_UUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUwwwUwUwwwwwwwwwuUUUUUUUUUUUUUUUUU@""""""""""""#UUUUUUUUUUUUUUUU]UUUUUUUUUUUUUUUUUU@*UUUUUUUUUUUUUwwwwwwwwwwwwUUWUUUUUUUUUUUUUUU@"*"""""""""";***+** UUUUUUUUUUUUU]_]UUUUUUUUUUUUUUU@ UUUUUUUUUUUUWwwwwwwwwwwwwwwwwwUUUUUUUUUUUUUU@"""""""""""# UUUUUUUUUUUU]]]UUUUUUUUUUUUUU@ꪪUUUUUUUUUUUUwwwwwwwwwwwwwwwwuWwwuUUUUUUUUUUUUU@"""""*""""";***+*** UUUUUUUUUUUU_U]UUUUUUUUUUUUU@ ꪪUUUUUUUUUUUWwwwwwwwwwwwwwwwwwwuWwwwuUUUUUUUUUUUU@"""""""""""UUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUwwwwwwwwwwwwwwwwwwwwwwuUUUUUUUUUUUU@""""""""""++***+* UUUUUUUUUUU_]]]U]_UUUUUUUUUUUU@ ꪪUUUUUUUUUUWwwwwwwwwwwwwUwwwwwwwwwUUUUUUUUUUUU@""""""""""UUUUUUUUUUU]UUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUWwwwwuwWUUUUUWUWWwwwwuUUUUUUUUUUU@"""""""""+******** UUUUUUUUUU_UUUUUUUUUUUU]UUUUUUUUUUU@ ﮪUUUUUUUUUUwwwwwUUUUUUUUUUUUUWwwwwwwUUUUUUUUUUU@"""""""""+"""": UUUUUUUUUU_UUUUUUUUUUUUUU]UUUUUUUUUUU@ꪪUUUUUUUUUWwwuUUUUUUUUUUUUUUWwwwwUUUUUUUUUUU@"""""""""?""""#********* UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@  UUUUUUUUUWwwwwUUUQUUUUUUUUUUUUwwwwwuUUUUUUUUUU@""""""""" """#""" UUUUUUUUU]UUUUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUWwwUUUUUUWwwuUUUUUUUUUU@""""""""+"""#***"***** UUUUUUUUU]UUUUUEUUUUUUUUUUU]UUUUUUUUUU@ꪪUUUUUUUUUwwwwUUQQUQUUUUUUwwwwwUUUUUUUUUU@""""""""+ "";""""UUUUUUUUU]UUUUUUUUUUUUUUUUUUUUUUUUUUU@ꪪUUUUUUUUUwwwwwwwuUUUUUUUWwwwwuUUUUUUUUU@""""""""+ ""+******** UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@  UUUUUUUUWwwwwwwuUQQUUUUUUwwwuUUUUUUUUU@"""""""";"""""""" UUUUUUUUUUUUUUUTUUUUUUUUUUU]UUUUUUUUU@ꪪUUUUUUUUWwwwwwwUUUUUUUwwwwUUUUUUUUU@""""""""?"""+**"*"*** UUUUUUUUUUUUUUEEEEEEUUUUUUUU_UUUUUUUUU@ꪪUUUUUUUUWwwwwwwUUUUUUUWwwwUUUUUUUUU@""""""""? ""*"""""" UUUUUUUUU]UUUTTDTDDTEUUUUUUUUUUUUUUUUU@UUUUUUUUWwwwwwwuUUUUUUWwwwwuUUUUUUUU@""""""""?"+"""**"* UUUUUUUUUUUDDEEEDEUUUUUUUUUUUUUUU@ UUUUUUUUWwwwwwwuUQUUUUUwwUUUUUUUU@""""""""""""""""""" UUUUUUUUUUTDD@DDDDDDDTUUUUUUUUUUUUUUU@UUUUUUUUWwwwwwwUUUUUUUwwwwUUUUUUUU@"""""""""*""""""" UUUUUUUUUUUEDDDEEUUUUUU]UUUUUUUU@ꪪUUUUUUUUWwwwwwwUQUUUUUwwwUUUUUUUU@""""""""""""""""" UUUUUUUUUUUD@@DDDDDDDDDDUUUUUU]UUUUUUUU@ꪪUUUUUUUUWwwwwwwUUUUUUWwwwUUUUUUUU@""""""""?""+""""*"" UUUUUUUU]UEDEUUUUUU__UUUUUUUU@ ꊊUUUUUUUUWwwwwwwuUUUUUUWwwwwUUUUUUUU@""""""""? """""""""" UUUUUUUU]UUTD@@@@DDD@@DDDUUUUUUUUUUUUUU@UUUUUUUUWwwwwwwUUUUUUWwwwuUUUUUUU@""""""""?"+""""""" UUUUUUUU_UUUEDDEEUUUUUUUUUUUUU@  UUUUUUUUwwwuwUUUQUUUUUuwuUUUUUUU@"""""""" """"""""" UUUUUUUU]UUUTTDDD@D@@@DDDDDEUUUUUUUUUUUUU@UUUUUUUUwwwuuUUUUUUUUwwwwwuUUUUUUU@"""""""" "*+""""""" UUUUUUUU]UUUUUDDDEUUUUUU]UUUUUUU@ UUUUUUUUwwwuUUUQUUUUUWwwwwUUUUUUU@""""""""""""""""" UUUUUUUU]UUUUUTDDD@@@DDDD@DDUUUUUUUUUUUUUUU@UUUUUUUUwwwuUUUUUUUWwwwwwuUUUUUUU@"""""""""""+""""*" UUUUUUUU]UUUUUUEDDEEUUUUUUU_UUUUUUU@UUUUUUUUwwwuUUUQUUUUUWwwwUUUUUUUU@""""""""""""""""""" UUUUUUUU]UUUUUTDD@@@DDD@DEUUUUUUUUUUUUUUUU@ꨪUUUUUUUUwwwUUUUUUUUUWwwuUUUUUUUU@"""""""""""""""""" UUUUUUUU]WUUUUUEEDEEUUUUUUU_UUUUUUUU@ UUUUUUUUwwwuUUUQUUUUUWwwuUUUUUUUU@"""""""""" """"""""" UUUUUUUU]UUUUUT@@@DDD@DUUUUUUUUUUUUUUUU@ꨀUUUUUUUUwwwUUUUUUUUUWwwwwuUUUUUUUU@""""""""""""#+"""""""" UUUUUUUU]UUUUUUDEEUUUUUUU]UUUUUUUU@ UUUUUUUUWwwUUUUUUUUUUUwwwwuUUUUUUUU@""""""""?"" """"""""""" UUUUUUUUUUUUUUUTD@@DDDDDDUUUUUUUUUUUUUUUUU@ꈈUUUUUUUUWwwUUUUUUUUUUUUUwwuUUUUUUUU@""""""""?""+ """""""""" UUUUUUUUUUUUUUUUUUDDEEUEUUUUUUU_UUUUUUUU@  UUUUUUUUWwuUUUUWUuUUQQUUUUUUUwwwwuUUUUUUUU@""""""""?#"""""""""""" UUUUUUUUUUUUUUUUUTDDDUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUWwwUUWWWWWwUUUUUUUUUUUUUUwwUUUUUUUUU@"""""""/#+"**+"""""""" UUUUUUUUU]UU]UUUUUUUDDEUUUUUUUUUUUUU_UUUUUUUUU@/ ꈈUUUUUUUUUwuUUUUUUwuUUQUWwwuUUUUUUUUwwwUUUUUUUUU@""""""""+; ;""""""""" UUUUUUUUU_UUUUUUUUUUTDDDUUUUUUUUUUUUUU_UUUUUUUUU@*ꪪꨀUUUUUUUUUWwUUUUUUUUUUQUUWWwUWUUUUUUwuUUUUUUUUU@"""""""#:""+""""""""" UUUUUUUUU_UUUUUUUUUUUDDEUUUU]UUUUUUUUUUUUUUUUUU@ UUUUUUUUUWuUUUUUUUUUUQUUUuUUUWuUUUUwuUUUUUUUUU@""""""""""""""";"";""""""""" UUUUUUUUUUUUUUUUUUUUTDDDUUUUUUUUUUUUUUUUUUUUUUU@ꪪUUUUUUUUUUuUUUUUUUUUUQUUUUUUUUWUUUUwwuUUUUUUUUU@""""""""+""#"""""+++""""""""" UUUUUUUUUU]UUUUUUUUUUUDUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUuUUUUUUUUUUQUUUUUUUUUUUUUUUUUUUUUUUU@"""""""""+"""#;* " :""""""""""" UUUUUUUUUUUUUUUUUUUUUUDDEUUUUUUUUUUUUUUUUUUUUUUUU@  ꪪUUUUUUUUUUUUUUUWWwuUUUUUUUUUUUUUUUUWuUUUUUUUUUU@"""""""""+"""+* #""*"*""""""""" UUUUUUUUUUUUUUUUU]UUUUDUUUUUUUUUUUUUUUUUUUUUUUUUU@  UUUUUUUUUUUUUUUuWWUUUUUUUUUUUUUUUUUWwUuUUUUUUUUU@"""""""""#""";?:" +"+"""""""""" UUUUUUUUUUUUUUUUUUUUTDUUUUU]UUUUUUUUUUUUUUUUUUU@  UUUUUUUUUUUUUUUUwQUUUUUWWWUUUUUUUUwUUUUUUUUUUU@"""#""""++"+""""""""" UUUUUUUUUUUUUUUUUUTUUUUEUUUUU_]UUUUUUUUUUUUUUUUUUU@   UUUUUUUUUUUUUUUUQUQUQUQUUUUwuWuUUUUUUwuUUUUUUUUUUU@""""" " """"**" ""?""""""""""" UUUUUUUUUUUUUUUUUUUUUUUUUUUTEUUUUUUUUUUUUUUUUUUUUU@  ꈊ꨺UUUUUUUUUUUUUUUUUUUUUQUUUUUUUUUUUUUWUUUUUUUUUUUU@"""""*""""""*""?+"""""""""""" UUUUUUUUUUUUUUUUUUUUUUUEUUUUEUUUUUUUUUUUUUUUUUUUUUU@  *UUUUUUUUUUUUUUUUUUUUUUQUUUQUUUUUUUUUUuUUUUUUUUUUUU@" "" "" " "" """"  #""#""""""""" UUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUWUUUUUUUUUUUUU@""""""""""#""+#""""""""" UUUUUUUUUUUUUUUUUUUUUUUEUUUUUUUUUUUUUUUUUUUUUUUUUUUU@  UUUUUUUUUUUUUQUUQUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ """" " """"""""" ""#""""""""" UUUUUUUUUUUUUUUUTTEUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUQUUUUUUUUUUUUUUUUUUUUUUUUUU@""*"""+#""""""""" UUUUUUUUUUUUUUEEEEEUUUTEUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUQUUUUUQQUUUUUUUUUUUUUUUUUU@" "" " """"#""""""""" UUUUUUUUUUUUUUDDDEUUUUTEUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@*""*""+";"""""""" UUUUUUUUUUUUUEEDEEUUUTUUUUUUEEEUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUQUUUQUUUUUUUUUUUUUUUUUU@"""""":"; """"""""" UUUUUUUUUUUUUUTDDDEUUUTDUUUUUTDUUUUUUUUUUUUUUUUUUUUU@ ꀪUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@"""""+"""UUUUUUUUUUUUUEDDDEUUUTUUUUEEDEEUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUQUUUQUUUUUUUUUUUUUUUUUU@ " """""; "" """" UUUUUUUUUUUUUUD@@@EUUUTEUUUTDDDDUUUUUUUUUUUUUUUUUUUU@ꪪUUUUUUUUUQUUUUUUUUUUUUUUUUUU@"*""+"""UUUUUUUUUUUUUUDEUUUDUUUUDDEEEUUUUUUUUUUUUUUUUUUU@着UUUUUUUUQQUUUQUUQUUUQUUUUUUUUUUUUUUUUUUU@" """"*  "" UUUUUUUUUUUUUUD@@EUUUDEUUUTDDDEUUUUUUUUUUUUUUUUUUUU@ꊪUUUUUUUUUUUUUUUUUUUUUUUU@""+""""UUUUUUUUUUUUUUDUUUDUUUUDEUUUUUUUUUUUUUUUUUUUU@ UUUUUUQQUUUUUQUUUUUUUUUUUUUUUUUUU@" ""* UUUUUUUUUUUUUUD@@DEUUT@DUUUUD@DDUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUU@"*"+"UUUUUUUUUUUUUUDDEUUDUUUUDEUUUUUUUUUUUUUUUUUUUU@ UUQUQUQUUQUUUUUUUUUUUUUQUUUUUUUU@ "" "+" UUUUUUUUUUUUUUDDDDUUUTDEUUUUTDDEUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUU@:"*"*""+UUUUUUUUUEEUUUEDEEUUUUUUUUUUEDEEUUUUUUUUUUUUUUUUUUU@ QQUQUUUUUUUUUQUUUUUUQQQQQUUUUUUU@ "# ""UUUUUUUUUUUUUUTDDEUUUUUUUUUUTDDEUUUUUUUUUUUUUUUUUUUU@*UUUUUUUUUUUUUWUU"+"*"+UUUUUUUUEEEUUUEEDEUUUUUUUUUUDDEEUUUUUUUUUUUUUUUUUUUU@ UUUUUUUQQUUUUUQQQUUUUUU@  ""UUUUUUUUUUUUUUUTDUUUUUUUUUUUDDUUUUUUUUUUUUUUUUUUUUUU@ UUUUUUUUUUU"""+UUUUUUUEEEEEUUUUEUEEUUUUUEEEDEEUUUUUUUUUUUUUUUUUUUUU@  UUQUUUUUUUUUUUUQUUU@" """ "UUUUUUUUTUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUU"#""" # UEEUUEEEEEEEUUUUUUUUUUUUUUEEEEUUUUUUUUUEEUUUUUUUUUUU@UUQQUUUUUUUUUQUUUUUUUQQUQ@"""";""UUUUUUUTTDTEUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@UUUUUUUUUUUUUUUUU#;+""""*+EEEEEEEEEEEEUUUUUUUUUUUUUUUUUUUUUUUUUEEUEEUUUUUUUUUU@ ꮪ UUUUUUUUUUUUUUUUUUUUUUUQ@ """* ""*UUUUTTTDDDTDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@ꪮUUUUUWUUUUUUUUUUUUUUUUUU***+""*+UEEEEEEEEEEEEUUUUUUUUUUUUUUUUUUUUUUUUEEEEEEEEUEUUUUU@ ꪪ UUUUUUUUUUUUUwUUUUUUUUUQ" +"+"""UTUUTTDDTDDDEUUUUUUUUUUUUUUUUUUUUUUUUTUTTUUUUUUUUUUU@ UUUUUUUUUUUUUUUUUUUUQ""+*"+EEEEEEEDDDDDEUUUUUUUUUUUUUUUUUUUUUUUUEEEEEEEEEEEEUUU@UUUUUUUQUUUUUUUUUUUQ" " """*TTTTDTDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUTTDTDTDUUUUUUUUU@UUUUUUUUUUUUUUUUUUQ""""""+EEEDEDDDDDUUUUUUUUUUUUUUUUUUUUUUUEEEEEEEEEEEEEEEE@ UUUQUUUUUUUUUUUUUUUUQ " """ """DDDDDDDDDDDDDEUUUUUUUUUUUUUUUUUUUUUUTDDDDDDTTUTTTUUU@UUUUUUUUUUUUUUUUU"""+DEDEDDDUUUUUUUUUUUUUUUUUUUUUUEEEEEDEEEEEEEEEE@ UUQUUQUUUUUUUUUUUQ" """DDDDDDDDDDDDDDUUUUUTUUUUUUUUUUUUUUUUTDDDDDDDDDDTDTTT@UUUUUUUUUUUUQ""*+DDDDDDUUUUEEEEEUEUUUUUUUUUUUUDDDDDDDEEEEEEEE@ UUQUUUUUUUUUUu ""*DDDDDDDD@@@DUUUUUTDDDUUUUUUUUUUUUUUDDDDDDDDDDDDTDD@?ꪮWUUUUUUUUUUUwQ?""]UUUUEDDEUUUUUUUUUUU]TDDDDDDEDEDE@? wUUQUUUUUUUUUUWQ" ""?DDDDD@@@E]UUUTDDDDDUUUUUUUUUUUUDDDDDDDDDDDDDD@ꪪwUUUUUUUUUUUUWu""+*]UUUUUDDDDEUUUUUUUUUUEDDDDDDDD@ wUUUQUUUUUUUUUUwQ"""";*@D@@@EUUUUDDTDTUUUUUUUUUUUET@D@@DDDDDDDDD@耀ꪪwUUUUUUUUUUUUUUwQ""""*+U_UUUUEEEEEUUUUUUUUUUU_DD@ WwUUUUUUUUUUUUUUUUwu? ""+""?]UUUUUUUUUUUUUUUUUUUUT]D@@@@DDDDDDDD@ꪪ?wwUUUUUUUUUUUUUUUUWwQ"" #***+?U]UUUUUUUUUUUUUUUUUUUUT_T ꪪ?WwwUUUUUUUUUUUUUUUUUUQwu?  "+""?UEUUUUUUUUUUUUUUUUUUU@U@@@@@@DDDDD@ꪪwwwQUUUUUUUUUUUUUUUUUUwwQ "*"""""+****U_EUUUUUUUUUUUUUUUUUUUUUD? WwwwQUQQUUUUUUUUUUUUUUUUwwuQ#""" U]UUUUUUUUUUUUUUUUUUTUU@@@@D@@@@ꪪWwwwwQUUUUUUUUUUUUUUUQwwwuQ?"*"***"""]UUUUUUUUUUUUUUUUU@UD wwwwqUUUUUUUUUUUUUUUwwwwuQ?"""""""""""UUUUUUUUUUUUUUUUUTUT@@@@@@wwwwuUUUUUUUUUUUQwwwwwU """"""" U]UUUUUUUUUUUUUUU@WT? WwwwwuQUUUUUUUUUwwwwwwU""""""?U]@UUUUUUUUUUUUUUUUT@/?WwwwwwwUUUUUUwwwwwu"""" ?]]_@UEEUUUUUUUUUUT]UD?UwwwwwwwPUUUUUPWwwwwuQ?" "?UDTTTUEUUUUUU@UUD?wwwwwwwwwqUUUUWwwwwwwwwU?" ?U]EEEEEUUUUUT_TwwwwwwwuUUUUPwwwwwwwwwU " U]UUUUUUUUU@]U@WwwwwwwwwwUUUUwwwwwwwwwwu@ U]]@EUUUUUUUT]@/WwwwwwwwwwwwPUUUUUPwwwwwwwwwwwwww`" "U]]UUUUUUU@]@/WwwwwwwwwwwwwqUUUUUwwwwwwwwwwwww@"" ]]]UUUUUT_@WwwwwwwwwwuUUUUUQwwwwwwwwwwwww@""" UU]@UUUU@T@ Wwwwwwwwwwwwwwww@UUUUUwwwwwwwwwww@?""(?U]]_@UUUUUU@@ WwwwwwwwwwwwwwPUUuUUPwwwwwwwwwwwww`?UU]]UUUUUUTU?WwwwwwwwwwwwwwwuUwWwwWUWwwwwwwwwwwww@? ?U]]_UUU]UUW]@?WwwwwwwwwwwwwwuUuWUwWUuWwwwwwwwwwwwwww@;??U]@UUU]U]WwwwwwwwwwwwwwwwwPUuWUuWwuwwwwwwwwwwwww@?]]_]]]PUU]U]__wwwwwwwwwwwwwwwwPUuWWwwuwwwwwwwwwwwwww@U]U]U]@]WwwwwwwwwwwwwwwwwUUuWUwWwwwwwwwwwwwwwww@U]]_]]]]]UU]WU@]@wwwwwwwwwwwwwwwwwuuwWuwWwUPwwwwwwwwww@?U]@]]U]U@U? WwwwwwwwwwwwwwwwwwQwuwWuwWuQwwwwwwwwwwwwww@??]]_U]WT]]]U]_UEP]?wwwwwwwwwwwwwwwwwwwwUwwWWuwwQPWwwwwwwwwwwwwwww@?U}UUUUTT]@oWwwwwwwwwwwwwwwwwwwwuWwWWuwwQQwwwwwwwwwwwwwwwww@? U]]__]]]]U@UUUU]]DT]@?wwwwwwwwwwwwwwwwwwwuPUWwUuWuwwwwwwwwwwwwwwwww@??UUUU@UU]U]T@@@wwwwwwwWwwwwwwwwwwwwUUWwuwQwwwwwwwwwwwwwwwwu?]]]]]]U]]]]]DUUUU]T]_wwwwwwwwwwuwwuwwwwwwPUwuWQwwwwwwwwwwwwwwwwu?sam2p-0.49.2/examples/ptsbanner.gif0000644000175100017510000002762712211371426015346 0ustar ptsptsGIF87a<f3̙f3f3ffffff3f3333f333f3f3̙f3̙̙̙̙f̙3̙ffffff3f3333f333f3̙f3̙̙f3̙f3ff̙ffff3f33̙33f333̙f3ffffff3ffff̙fff3fffffff3ffffffffffff3fff3f3f3f3ff33f3ffffff3f3333f333333̙3f3333333f3333f3f3f3ff3f33f33333333f333333333f333f3̙f3f3ffffff3f3333f333f3,<@D Y,ȰÇ#TŊpcď %dAQvlT3f29'ϟ;s͟siN;*5g̫XbiզN:jSgm2E,WJjmۣQÒy`7yb/` (p%Ct,x!E(.ї`I EVy@'LX`VHDvmpb`,tB%^jg$/ݙLГ57=dϬ4<:ugϮ>dcGl38P>Y6i s:U"Hj6n\` ‚{;@gNbRpĻх[^ԓetZbWpBM&vIr@Mn ^R+fspmGr,UڂĸmLi2K^+']T)]) IFv o\H20RNs4w Oy 2 )d@\' ίӝ)@7RP)<ЯQ8>9*dqLH$ҒĤ.y5 𿑖0QJ:ҙq&Mm@i4&9Z"HO5Ir6T#uHYZ崧1%5lgM-THXgAɩIԡn-iOӠ+#dgꠋ%fTVcgLbF5)$&0Ҿi IJ#Y'<ג*7g.I c  @ADރDn^GMq, ؔW[Jv]xe-}[D@faeMh f'#Mrq?6F| y3B2xZ6F) !YX瓴ZH0$Aώf)ʔ]ֵ􄭸jKr\- S ^`>EH2 KSJ*'HU 6 ́KKBthQ dh(v F d_8- ^[^6H?IDĬf9i/2Ro}lǻ{c1K9J fnmBֽR#m! ,_qFl! -QbؐR@y 5 %04.DyYIlT!9Gf2ӧ2CkH&4ɵȹt'Z%'Db;:@wFjjlUx\.5+byDAێƬVDsvIWXQ2n\&q?kSrgڑ5'rN,@\ԨyckwQ#q R`22PlL=@ 4ujV[Bfpk! Wd缱=t>bDooxIȩrW8ru-Vt'|*?[R ;˱J:8DtBATWfWyx$=]$3X)F5{E`!Hcm1Q?[>}4dG{G5Efu;7h%I2t7X:wUAXUy}#?hc5uW1V~SD?VLVg@TTDAɧ$?h#Ճ[qWlES=U]&$MQEMlŅmsUMWKE7u]nՆSD6DTcTVa{Q&xQ𓈪eN3HOqCF&W%aHq5o8oC8TL;: 8guwe$\pylw0WW1xDuUQ9t7~s[xe863J^[pCC8D"GLeVq@QfO+!(X#NIGY5OOzqP`RNO42&%NxNe!k 3&h~QHlx-]SaA\V]؅͑AM؄6t0RTR\5TC$x;p]qUVoxCV=Eãw6uRK@BdIM\%UEAT3US^@SNIQGTTeI/E]%VdYXafW݄>$x!OwAs5#sadbs ӃFjQer<Bc[@aw>F$JeMc]d\NvIEV4a@@}SQ\[d:cAC|f/ۗ,fm3(Sfec>t(!a4>aiQ)OUi=5)Jb>e qQrQ$uHt"ڂ72f5"o.blb/L0l(. : ril֣u8A"9 /MCB#zҡiqM{H/c'-W$U$iʙ]%52cJ 1Ycaqk3gNc2k(sh[gʙf2&lʚO'1X!D "G*a!V.cȲo&pƂg=|2l*I"%ou"a-/1U+<2C0bfՆ7J2-摤NdBc+dpQJ;$Q V3{$3k*aX)E3Iu2iG_$h"Ybp]JGhOZJFtr4&Hy3(>~v30Ҥ#7 0b!Êg8ҲQe.bVxv,5B y.r#ZrV\/;0vn Hmh!YmX,7˳G1o.bp/mw޶7sQf 14YajJF2i}6%59sꊠ}~$ggy0 BK$œ76u^C%DI"x*QMI(&_x_ysMT3 -= 4kҧ= 2cl'w|3TI({kܨ k2Kw&5Ba|;GfxUVdug$@^[VЇ-#(w:֩Iɸw|0a;6~»~7@Xu$ב]6gk&83t[ /KD67 #ҥ3CgVxy)Z&`iEZHΣ{!|l=l z{'34ZQHC:VvyK0fDE3CY9\7$^w[ʉD|(3&`q*H׏Ylv@Ń}[ 4H IFٵu<@MCxViRC|^[W/!=wUdVh<>\GCQ[F"s7෽:t7u~n[^R]U@gs_pC:CÓTd6C 7W@o9vz]2@VX7115TP2O)-N'9 P-$NPu Oω4PN룘`>>NQ\5ĺCUֵ1U@RՅCׅw^SPŖ9M#9iAD@c,%UbW]vS?6~_aeUNLW\Wo}RqN][i7A4aɰNUaN%/z򛯈[ ~NQO'O,u2+F(`l(Q1I-%W#WxYV@PdKuV32U-^xS?@.nS@K2?-VR6.-Z SR(륨SE= sH*/'y l]qT$Qbot64Vꫭ]ZTwJGY\s5ףcKYTw YAӶ-jˬl=h;gr3l*NA4in4O:$\э:c,xߊ8BxO gӢkOU * ~'| W~SPŚUSP{T]SOmjkZ+P=A}ve]NegWCݛjSmm ?zݵ}uW Y=PßPe׿e7l7n.c^9y£A,Y e  hdMOiT5DNV.>qUg>󡓼9]CD~1$* 5@=.ȃ z6xp15Pova߳.*U_dʀ 6xѝX7ݹ1TjYAtכ̪1bE]ҁT2)ٌ<ݰ f~<%)j[ڒ;ף$=K]4!%K]r&R HL0uHe `{ړ$8L88t f 5:ov{iƪ7D\ĸm}xr *%e ^leJ&*\d%gv|!J;5ӗnƷQ\+l4R/$uRd ZeRT.%tRdUX s$ayD#d^%Vˍ1`1lHU@ !ch=;NT0+^AL$5EP2 Ta R7h+8]hvǖƐa#DvqPTRULFTXv}FQ780"^]|*Jl;er⧺S1C[ܼ2Rme2j'12X6NܢHvMj$#*p,y@Wa,Oْ{"$D:"B? SdHLHi*_g&9^ IcYS7銍<ы[nWvZv&yƓn=U°wD o4+_m| {OI0IIhIyW8xxht 8! q|rHeJ*#(gTdQYkXC=Gv9 v+mjW+镫*Ce3I%X5u6`k|,q80s=ozKna-^@qd6p=&!I᮴YD=W#1 6G`Бo/r.dd #  0b؊#Jƚ: 6>ɵji`RFZDJ kj)\ej{ev^Csq^_i^YdcE |To{Eol2Mp I8.2!AC C!*f=9=򫌃f58}!7-}M>Yrr7[B|&v}Nn:Cn"]u3VmvGFRUW"wUUL[#e,1a.+̐э#S2 ʐɐ []A 3 3=[^"i &c=P[Ӌ+*"ӏӵ;9 nr0ȑV* Ś0Ы,`*H&%l5ӗp:;a ,S 7Jr U裓9 }6!" >?  Y h [ BQ )>?r?;܊œ mK)SK9sk98Bӥ\b0Q+) X "/A*\z'<05ɪ &v&' 9E cW;B)F0& x0"kc*$}[?67 k)$Sɕ@TClGq,(D8jjB ";)ٜ? J{Yl+B &I9ճ@)ʠtA4)M )HpF:ݸxK( Sb ̷Lt@|4(;ÇHȓ'r`w9 W}@r@r )`6+T6p[/QdJۄH"|$DYtM}aэl ќ!!' :,.[ &=G(.&]k@,kҳ8݀H @k;PH䷱pS@hR|q&ŋ29D>:RQ O([0 6m! qQgQQoUQQQ "%RVɖ8S<΃PVl7<=Tְ@}PZVPַ֯ց1-e-e=!W<5ԲXVc<Ժ e}%g6)[Vo=c}Vuk d%l5ԫPV|kW<ŋp]<-ؔ)E`ҵH؂=pQ <9I^+QΆy))<&\U +5IŠ ZɓH+ Ƽ׭XsXj)UiXADDX݀~uuؾ8V*lj;Tu݋{XZo5VE$S()Fu۸Bukׇ4ֻ=)ܱ۠mh)5TXSE Wr Y٧U֡͗ŁM JJXe(] ]Pѹΰ[iiMJ bRo1Դ^Xυ}G0ymEV> ]awu:SgeRMeZ;p}u1eZ<5 ~̱Քe4!KUFaWMZ 8lY$J5yq'a3 <z\):^O.4jD %HS0<d;@C!IcˊDTGNSN$b t1_TBH$_V6I 9dѩd VNT gUw&U։ѕV4!FrF|78ʬB"`:Ӥ,qe9$c}_Ԝ;P ;,\iOrd?zI>Ny{CǻI!bѡCPd(NH`QӵJx1]/AdQ4XC* խ4> CS,S נL0||? ?G_ri$ lRRm2|~DbviFp08X |ܶ XXA?1nd@nV4YnXkn@M9ؔN HoFoFn6o**Q ~U <Є@KIGD@b-dChLRB`:9}l(/~fD\?(VX{=TҌeCà ɻVly3Lxon fid(#oVѓk) rʵƈd@rV6n*nf,OEs|8do*t[m`ZWC\d\BW>Zȕڭuָ5MgՋm܃uVpE`D`Wز~ZAeEgX׻]CwE-p`ieWZEtp=XXE"6 a] MUr^H7 '7s(:rpgzw>,'Jw0Onh;rxC雲Sm Di t(Xs- fmpe.21@ⱥGݶCx܃ۊܨrGpuMt5VWec5fM75w 4B\?l us}(m%cnzhro(O9nFo^{>n'3Gzov׉6/Oaw{6Քe^pa*D^[^xč[muV ?WEBz%̴V`Ԫ-ԓGWu؅'}'tLH?@rX%.tlUt_[uUt\%~X/W-XK_tXؕ4m"s0q7sݝu۪wEg WR-PUY9Z5$Þ@`@PB ,8AH0p1k4di#Ȃ$1DA)M.ir$ASf0@BAym͆R]V|yj8QvQE[u<+ 90bZVLuks^SH T$KGG5euUPK2mGxF/RZ4SZ_ᄒBa$tqtB89F5,֚gViFfp6Gc7vZqHaד;Y\kƘA_87%o_^VK3dPP$VLH%A8CctUx'o݅VD6A?L(raOFUBE8SDyfMubiԒOHM`vS X]5]UA`L;sam2p-0.49.2/ccdep.pl0000644000175100017510000002654712211371426012460 0ustar ptspts#! /bin/sh -- eval '(exit $?0)' && eval 'PERL_BADLANG=x;export PERL_BADLANG;: \ ;exec perl -T -S -- "$0" ${1+"$@"};#'if 0; eval 'setenv PERL_BADLANG x;exec perl -x -S -- "$0" $argv:q;#'.q #!perl -w +($0=~/(.*)/s);do$1;die$@if$@;__END__+if 0; # Don't touch/remove lines 1--7: http://www.inf.bme.hu/~pts/Magic.Perl.Header # # ccdep.pl v0.32 -- semiautomatic dependency discovery for C/C++ programs # by pts@math.bme.hu at Fri May 31 13:36:29 CEST 2002 # 0.31 by pts@math.bme.hu at Sat Jun 1 15:19:55 CEST 2002 # 0.32 by pts@math.bme.hu at Tue Sep 3 19:12:20 CEST 2002 # 0.33 by pts@math.bme.hu at Thu Oct 31 09:47:25 CET 2002 # # Dat: no -T (tainting checks) anymore, does bad to our readpipe() # OK : emit `TARGETS_yes = ...' # Imp: make #warning etc. in *.h files work as expected # OK : generated.h # Imp: add external libraries (-L...) # Imp: abort if gcc command not found... # Imp: abort if not all .o are mentioned in gcc output # Imp: avoid $ etc. in Makefile # OK : all 8 combinations of PROVIDES|REQUIRES|CONFLICTS # BEGIN { eval { require integer; import integer } } BEGIN { eval { require strict ; import strict } } # Typical invocation: ccdep.pl --FAL=assert,no,yes,checker $(CXX) my @FAL=(); if (@ARGV and $ARGV[0]=~/\A--FAL=(.*)/s) { @FAL=split/\W+/,$1; shift@ARGV } my $GCCP; # 'g++' or 'gcc': C/C++ preproc with `-E -MG' switches $GCCP="@ARGV"; $GCCP="gcc" if $GCCP!~y/ \t//c; # Make sure we get English error messages from gcc. delete $ENV{LANG}; delete $ENV{LANGUAGE}; $ENV{LC_ALL} = "C"; # --- sub find_ds() { #** @return a list of .ds file in the current directory my @L; my $E; die unless opendir DIR, '.'; while (defined($E=readdir DIR)) { push @L, $E if $E=~/\.(c(|c|xx|pp|[+][+])|C)\Z(?!\n)/ and -f $E; } @L } sub expand_glob($$ $) { #** @param $_[0] string containing globs (? and *) #** @param $_[1] listref of names #** @param $_[2] dest listref my $S=quotemeta($_[0]); if (0==($S=~s@\\([?*])@.$1@g)) { push @{$_[2]}, $_[0]; return } my $RE=eval"+sub{\$_[0]=~/$S/}"; die$@if$@; for my $E (@{$_[1]}) { push @{$_[2]}, $E if $RE->($E) } } sub mustbe_subset_of($$ $$) { #** A must be a subset (sublist) of B #** @param $_[0] caption A #** @param $_[1] ref(array(string)) A #** @param $_[2] caption B #** @param $_[3] ref(array(string)) B my @A=sort @{$_[1]}; my @B=sort @{$_[3]}; my($AV,$BV); while (defined($AV=pop@A)) { 1 while defined($BV=pop@B) and $BV gt $AV; if (!defined($BV) or $BV ne $AV) { print STDERR "$0: $_[0] are: @{$_[1]}\n"; print STDERR "$0: $_[2] are: @{$_[3]}\n"; die "$0: $_[0] must be a subset of $_[2]\n"; } } } # --- print "$0: running.\n"; sub unix_shq($) { my $S=$_[0]; $S=~s@'@'\\''@g; "'$S'" } sub shq($) { my $S=$_[0]; return $S if $S!~/[^\w.-]/; if ($^O eq 'MSWin32') { # assume the called program is CygWin/Ming32; see later # Arguments are delimited by white space, which is either a space or a tab. # . A string surrounded by double quotation marks is interpreted as a # single argument, regardless of white space contained within. A quoted # string can be embedded in an argument. Note that the caret (^) is not # recognized as an escape character or delimiter. # . A double quotation mark preceded by a backslash, \", is interpreted as # a literal double quotation mark ("). # . Backslashes are interpreted literally, unless they immediately precede # a double quotation mark. # . If an even number of backslashes is followed by a double quotation # mark, then one backslash (\) is placed in the argv array for every pair # of backslashes (\\), and the double quotation mark (") is interpreted as # a string delimiter. # . If an odd number of backslashes is followed by a double quotation # mark, then one backslash (\) is placed in the argv array for every pair # of backslashes (\\) and the double quotation mark is interpreted as an # escape sequence by the remaining backslash, causing a literal double # quotation mark (") to be placed in argv. $S=~s@"@\\"@g; return qq{"$S"} } else { $S=~s@'@'\\''@g; return qq{'$S'} } } sub backtick(@) { my $S=$_[0]; if ($^O eq 'MSWin32') { # assume the called program is CygWin/Ming32; and we have proper /bin/sh $S="sh -c ".unix_shq($S); # /bin/sh can handle IO-redirections such as `2>&1' right } else { # assume UNIX } print "+ $S\n"; #die unless $ENV{PATH}=~/(.*)/s; # Dat: untaint() #$ENV{PATH}=$1; #die "$ENV{PATH}"; # Dat: if `.' is part of $ENV{PATH}, `Insecure directory...' is reported #die unless $S=~/(.*)/s; # Dat: untaint() readpipe $S # `` qx`` } my @DS=find_ds(); my @DSQ=map{shq$_}@DS; my $DIAG=" -fno-diagnostics-show-caret"; my $Q="$GCCP -DOBJDEP$DIAG -M -MG -E 2>&1 @DSQ"; my $R=backtick($Q); if ($R=~/\berror: .*-fno-diagnostics-show-caret\b/) { # gcc-4.6 and earlier don't have this flag, and they fail. $Q=~s@ -fno-diagnostics-show-caret(?=\s)@@; $DIAG=""; $R=backtick($Q); } if ($R!~/: warning: #warning\b/) { # config2.h:314:4: warning: #warning REQUIRES: c_lgcc3.o # Dat: g++-3.3 ignores #warning with -M -MG -E $R.="\n".backtick("$GCCP -DOBJDEP$DIAG -E 2>&1 >/dev/null @DSQ"); } ## die $R; #** $pro{"x.ds"} is the list of features provided by "x.ds"; multiplicity my %pro; #** $req{"x.ds"} is the list of features required by "x.ds"; multiplicity my %req; #** $con{"x.ds"} is the list of features conflicted by "x.ds"; multiplicity my %con; #** $repro{"feature"} is a hash=>1 of .ds that provide "feature" my %repro; #** $mapro{"executable"} eq "x.ds" if "x.ds" provides main() for "executable" my %mapro; #** $idep{"x"} contains the the dependency line for x.ds my %idep; #** hash=>1 of "feature"s of NULL-PROVIDES my %nullpro; my $included_from; my $BS; # undef while ($R=~/\G(.*)\n?/g) { my $S=$1; if ($S=~/\\\Z/) { if(defined$BS){$BS.="\n$S"}else{$BS=$S} next } if (defined $BS) { $S="$BS\n$S"; undef $BS } if (!length$S) { } elsif ($S=~/\AIn file included from ([^:]+)/) { $included_from=$1; } elsif ($S=~/\A\s{3,}from ([^:]+)/) { # ^^^ gcc-3.2 $included_from=$1; } elsif ($S=~/\A([^:]+):\d+:(\d+:)? warning: #warning (NULL-PROVIDES|PROVIDES|CONFLICTS|REQUIRES):(.*)\Z/) { # ^^^ (\d+:)? added for gcc-3.1 # print STDERR "[$S]\n"; my($DS,$B)=($1,$3); if (defined $included_from) { $DS=$included_from; undef $included_from } # print STDERR "[$DS] [$B] [$4]\n"; if ($B eq 'NULL-PROVIDES') { for my $FEAT (split' ',$4) { $nullpro{$FEAT}=1 } } elsif ($B eq 'PROVIDES') { my @L=split' ',$4; push @{$pro{$DS}}, @L; push @{$con{$DS}}, @L; for my $FEAT (@L) { $repro{$FEAT}{$DS}=1; if ($FEAT=~/\A(.*)_main\Z/) { $mapro{$1}=$DS } } } elsif ($B eq 'REQUIRES') { push @{$req{$DS}}, split' ',$4; } elsif ($B eq 'CONFLICTS') { push @{$con{$DS}}, split' ',$4; } else { die } # print "$1;$2;@L;\n"; undef $included_from; } elsif ($S=~/\A([^: ]+)\.o: (([^: ]+?)\.([^ \n]+).*)\Z/s and $1 eq $3) { # print STDERR "($S)\n"; my($A,$B,$C)=("$1.o",$2,"$3.$4"); die "$0: multi gcc output: $A" if exists $idep{$B}; # ^^^ Dat: maybe both t.c and t.cxx $B=~s@ /[^ ]+@@g; # remove absolute pathnames $B=~s@( \\\n)+@ \\\n@g; $B=~s@ \\\n\Z@@; $B=~s@^ +\\\n@@gsm; # what was left from absolute pathnames $B=~s@ *\\\n *\Z(?!\n)@@gsm; # what was left from absolute pathnames $idep{$C}=$B; # vvv automatic `t.ds: PROVIDES: t.o' # print "::: $C $A\n"; push @{$pro{$C}}, $A; push @{$con{$C}}, $A; $repro{$A}{$C}=1; undef $included_from; } elsif ($S=~/\A([^:]+):\d+: .*\Z/) { print "# $S\n"; undef $included_from; } elsif ($S=~/\A([^:]+):\d+:(\d+:)? warning: ".*?" redefined\Z/) { # ^^^ gcc-3.1 undef $included_from; } elsif ($S=~/\A([^:]+):\d+:(\d+:)? warning: this is the location of /) { # ^^^ gcc-3.1 undef $included_from; } elsif ($S=~/: No such file or directory$/) { # Depends on $ENV{LC_ALL}. # ^^^ gcc-3.3 undef $included_from; } elsif ($S eq 'compilation terminated.') { # Useless message, ignore. } elsif ($S=~/^distcc\[/) { # Useless message, ignore. } elsif ($S=~/^ *#/) { # Useless message from gcc 4.8, ignore. } elsif ($S=~/^ *\^/) { # Useless message from gcc 4.8, ignore. } else { die "$0: invalid depret: [$S]\n"; } } mustbe_subset_of "providers"=>[keys(%pro)], "dep_sources"=>[keys(%idep)]; mustbe_subset_of "dep_sources"=>[keys(%idep)], "sources"=>\@DS; { my @K=keys %repro; while (my($DS,$L)=each%con) { my @R=(); for my $FEAT (@$L) { expand_glob $FEAT, \@K, \@R } # ^^^ multiplicity remains $con{$DS}=\@R; } } die unless open MD, "> Makedep"; die unless print MD ' ifndef CCALL CCALL=$(CC) $(CFLAGS) $(CFLAGSB) $(CPPFLAGS) $(INCLUDES) endif ifndef CXXALL CXXALL=$(CXX) $(CXXFLAGS) $(CXXFLAGSB) $(CPPFLAGS) $(INCLUDES) endif ifndef LDALL LDALL=$(LDY) $(LDFLAGS) $(LIBS) endif ifndef CC CC=gcc endif ifndef CXX CXX=g++ endif ifndef LD LD=$(CC) -s endif ifndef LDXX LDXX=$(CXX) -s endif ifndef LDY LDY=$(LD) endif ifndef CFLAGS CFLAGS=-O2 -W -Wall -fsigned-char endif ifndef CXXFLAGS CXXFLAGS=-O2 -W -Wall -fsigned-char endif ifndef GLOBFILES GLOBFILES=Makefile Makedep endif '; die unless print MD "ALL +=", join(' ',keys%mapro), "\n"; die unless print MD "TARGETS =", join(' ',keys%mapro), "\n"; # vvv Thu Oct 31 09:49:02 CET 2002 # (not required) #my %targets_fal; #for my $FA (@FAL) { $targets_fal{$FA}="TARGETS_$FA =" } while (my($EXE,$MDS)=each%mapro) { print "exe $EXE\n"; my @FEA2BA=("${EXE}_main"); my @DSO=(); # list of .o files required my @DSL=(); # list of .ds files required my %CON=(); # hash=>1 of features already conflicted my %PRO=%nullpro; # hash=>1 of features already provided my $FEAT; while (defined($FEAT=pop@FEA2BA)) { next if exists $PRO{$FEAT}; # print " feat $FEAT (@FEA2BA)\n"; ## # vvv Dat: r.b.e == required by executable die "$0: feature $FEAT r.b.e $EXE conflicts\n" if exists $CON{$FEAT}; my @L=keys%{$repro{$FEAT}}; die "$0: feature $FEAT r.b.e $EXE unprovided\n" if!@L; die "$0: feature $FEAT r.b.e $EXE overprovided: @L\n" if$#L>=1; # Now: $L[0] is a .ds providing the feature push @DSL, $L[0]; my $O=$L[0]; $O=~s@\.[^.]+\Z@.o@; push @DSO, $O; $PRO{$FEAT}=1; for my $FEAT2 (@{$pro{$L[0]}}) { die "$0: extra feature $FEAT2 r.b.e $EXE conflicts\n" if exists $CON{$FEAT2} and not exists $PRO{$FEAT2}; $PRO{$FEAT2}=1; } for my $FEAT2 (@{$req{$L[0]}}) { push @FEA2BA, $FEAT2 if!exists $PRO{$FEAT2} } for my $FEAT2 (@{$con{$L[0]}}) { $CON{$FEAT2}=1 } # die if! exists $PRO{$FEAT}; # assert } die unless print MD "${EXE}_DS=@DSL\n". "$EXE: \$(GLOBFILES) @DSO\n\t\$(LDALL) @DSO -o $EXE\n\t". q!@echo "Created executable file: !.$EXE. q! (size: `perl -e 'print -s "!.$EXE.q!"'`)."!. "\n"; # vvv Sat Jun 1 15:40:19 CEST 2002 for my $FA (@FAL) { die unless print MD "$EXE.$FA: \$(GLOBFILES) \$(${EXE}_DS)\n\t". "\$(CXD_$FA) \$(CXDFAL) \$(${EXE}_DS) -o $EXE.$FA\n"; # $targets_fal{$FA}.=" $EXE.$FA"; } } print MD "\n"; # vvv Thu Oct 31 09:49:02 CET 2002 # (not required) # for my $FA (@FAL) { print MD "$targets_fal{$FA}\n" } # print MD "\n"; while (my($K,$V)=each%idep) { my $O=$K; $O=~s@\.([^.]+)\Z@.o@; print MD "$O: \$(GLOBFILES) $V\n\t\$(", ($1 eq'c'?"CC":"CXX"), "ALL) -c $K\n" } print MD "\n"; die unless close MD; print "$0: done.\n"; __END__ sam2p-0.49.2/helpere.hpp0000644000175100017510000000251112211371426013163 0ustar ptspts/* * helpere.hpp -- help encoding images * by pts@fazekas.hu at Tue Dec 9 10:53:21 CET 2003 */ /* Don't use this here, because we don't have helpere.cpp #ifdef __GNUC__ #pragma interface #endif */ #ifndef HELPERE_HPP #define HELPERE_HPP 1 #include "image.hpp" #include "error.hpp" #include "gensio.hpp" /** Ugly multiple inheritance. !! unify with PNG, TIFF etc. */ class HelperE: public Filter::NullE, public Filter::PipeE { public: inline HelperE(char const*filter_cmd, char const*mainfn=NULL): Filter::NullE(), Filter::PipeE(*(Filter::NullE*)this, filter_cmd, (slendiff_t)mainfn) { /* ^^^ (slendiff_t) is unsafe cast */ // GenBuffer::Writable &out_, char *pipe_tmpl, slendiff_t i=0) } inline virtual void vi_copy(FILE *f) { // img=Image::load("-", SimBuffer::B(), (Image::filep_t)f, (char const*)"PNM"); Filter::UngetFILED ufd((char const*)NULLP, f, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); img=Image::load((Image::Loader::UFD*)(long)&ufd, SimBuffer::B(), (char const*)"PNM"); /* We must close f, this is part of the vi_copy contract. If we fail to * close it, cleanup_remove won't be able to remove the tmp files at * Error::runCleanups() time. */ fclose(f); } inline Image::Sampled *getImg() const { return img; } protected: Image::Sampled *img; }; #endif sam2p-0.49.2/encoder.hpp0000644000175100017510000001123412211371426013160 0ustar ptspts/* encoder.hpp -- specific encoding filters * by pts@fazekas.hu at Tue Feb 26 13:30:02 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef ENCODER_HPP #define ENCODER_HPP 1 #include "config2.h" #include "gensio.hpp" #include class PSEncoder: public Encoder { public: /** @return "Flate", "LZW", "DCT", "RunLength", "CCITTFax", "ASCIIHex", "ASCII85" */ // inline char const* getLongname() const { return longname; } /** @return "Fla", "LZW", "DCT", "RL", "CCF", "AHx", "A85" */ // inline char const* getShortname() const { return shortname; } // inline SimBuffer::Flat const& getFPSname() const { return filter_psname; } // virtual void vi_write(char const*buf, slen_t len) =0; inline virtual ~PSEncoder() {} /* The class methods below may return different implementations according to * the command line and compile-time options. */ static PSEncoder* newASCIIHexEncode(GenBuffer::Writable &out_,unsigned maxcpl_); static PSEncoder* newASCII85Encode(GenBuffer::Writable &out_,unsigned maxcpl_); /** Fax (PSL2 CCITTFaxEncode filter, Uncompressed=true! (parts of the data * can be inserted uncompressed, when the decoder decides that this is * advantageous), K=-1,0,positive, * EndOfLine=false, EncodedByteAlign=false, Columns=..., Rows=0, * EndOfBlock=true, BlackIs1=false, DamagedRowsBeforeError=0 * K must be -1, 0 or positive, see PLRM 3.13.3 * K==-1: Group 4 pure 2D encoding. TIFF COMPRESSION_CCITTFAX4, * GROUP4OPT_UNCOMPRESSED. * K==0: Group 3 pure 1D encoding. TIFF COMPRESSION_CCITTFAX3, * GROUP3OPT_UNCOMPRESSED. * K>=1: Group 3 2D (mixed 1D and 2D), a 1D-line can be followed by at most * K-1 2D-line. TIFF COMPRESSION_CCITTFAX3, GROUP3OPT_UNCOMPRESSED, * GROUP3OPT_2DENCODING (K is explicitly raised to image height). * @param EndOfLine should be false for PS/PDF, but must be true for TIFF. */ static PSEncoder* newCCITTFaxEncode(GenBuffer::Writable &out_,slendiff_t K, slen_t Columns, bool EndOfLine=false, bool BlackIs1=false); /** PSL2 LZWEncode filter EarlyChange=true, UnitLength=8 LowBitFirst=false */ static PSEncoder* newLZWEncode(GenBuffer::Writable &out_); /** PSL3 FlateEncode (ZIP) filter Effort=...: 1..9: 9==highest compression. -1==5 */ static PSEncoder* newFlateEncode(GenBuffer::Writable &out_, signed Effort=-1); /** PSL2 RunLengthEncode filter, similar to TIFF PackBits, recordsize=... */ static PSEncoder* newRunLengthEncode(GenBuffer::Writable &out_, slen_t RecordSize=0); /** PSL2 DCTEncode. Calls the cjpeg utility (in the debian package * libjpeg-progs) to do the task. The input must be RGB or Gray with * BitsPerComponent==8. */ static PSEncoder* newDCTIJGEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char quality /*libJPEG quality: 0..100 */ ); /** @param other_parameters "" or something * like: "/HSamples [1 2 1]/ColorTransform 2" */ static PSEncoder* newDCTEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char ColorTransform, /*0,1,2 3=default*/ SimBuffer::Flat const& other_parameters ); /** PSL2 DCTEncode. Not supported yet. Imp: build support */ static PSEncoder* newDCTEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char quality=75, /*libJPEG quality: 0..100 */ unsigned char const*HSamples=(unsigned char*)NULLP, /*all 1..4, NULLP OK*/ unsigned char const*VSamples=(unsigned char*)NULLP, /*all 1..4, NULLP OK*/ /* vvv pacify VC6.0; no unsigned char (*QuantTables)[64]=(unsigned char(*)[64])NULLP, */ unsigned char (*QuantTables)[64]=0, /*NULLP OK*/ double QFactor=1.0, /*0..1000000*/ unsigned numHuffTables=0, unsigned char **HuffTables=(unsigned char**)NULLP, /*NULLP OK*/ unsigned char ColorTransform=2 /*0,1,2 3=default*/ ); // static Encoder* newTIFFPredictor2(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); // static Encoder* newPNGPredictor11(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); /** @param type: 1: no predictor, 2: TIFFPredictor2, 10: PNGPredictor0 (None) * 11: PNGPredictor1 (Sub), 12: PNGPredictor2 (Up), * 13: PNGPredictor3 (Average), 14: PNGPredictor4 (Paeth), * 15: PNGPredictor5 (optimum). */ static Encoder* newPredictor(GenBuffer::Writable &out_, unsigned char type, unsigned char bpc_, slen_t columns_, unsigned char cpp_); protected: // char const *longname, *shortname; // SimBuffer::B filter_psname; }; #endif /* encoder.hpp */ sam2p-0.49.2/error.hpp0000644000175100017510000001300612212351433012666 0ustar ptspts/* error.hpp -- handling errors/warnings etc. * by pts@fazekas.hu at Fri Mar 1 11:32:36 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef ERROR_HPP #define ERROR_HPP 1 #include "config2.h" #include "gensi.hpp" /** This may be usafe if an error happens inside an error. Usage: * Error::sev(Error::WARNING) << "Zero-length image." << (Error*)0; */ class Error { public: static char const* banner0; static char const* argv0; static char const* tmpargv0; static char const* long_argv0; /** Error types. */ BEGIN_STATIC_ENUM(int,level_t) ASSERT=4, FATAL=3, EERROR=2, /* ERROR conflicts with the Win32 API :-( */ ERROR_CONT=-2, /* error, but continue running program */ WARNING=-3, WARNING_DEFER=-4, /* warning, but defer (and later possibly omit) displaying it */ NOTICE=-5, NOTICE_DEFER=-6, INFO=-111, DEBUG=-222 END_STATIC_ENUM() /** Standard error stream (stderr) of the current process. */ static GenBuffer::Writable * serr; /** Returns address to statically allocated buffer. */ static char const*level2str(level_t level); /** This is the (carefully hidden :-)) method of raising errors (i.e * displaying error messages and terminating the program). * Example usage: * Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires " * "/Predictor " << 1 << (Error*)0; * The error is interpreted according to the current policy. The policy * divides errors into three categories: * * -- secret: nothing happens (even the error message is _not_ printed) * -- recorded: nothing happens (even the error message is _not_ printed), * but the message is remembered for further processing. * -- printed: the error message is printed, and program execution continues * Before printing this message, all recorded errors on the policy stack * are also printed (deepest first). * -- killer: like `printed', but runs cleanup handlers and terminates the * program immediately. * * @param level is one of the constants mentioned above (FATAL, EERROR, * WARNING, NOTICE etc). Can be positive, zero or negative. The larger * the `level', the more severe the error is. The default policy is: * level>=0 errors are killer, -99<=level<=-1 errors are printed, * -199<=level<=-100 are recorded and level<=-200 errors are secret. */ static GenBuffer::Writable& sev(level_t level); public: /** The field order is important in this struct, because of the initializers. */ struct Policy { /** All recorded messages. Default: NULL. This means empty. */ SimBuffer::B *record; /** The highest level of Secret category encountered so far. Default: -9999 */ level_t topSecret; /** The highest level of Recorded category encountered so far. Default: -9999 */ level_t topRecorded; /** Lower bound of these categories in this policy. */ level_t killer, printed, recorded; /** Error stream to print printed and killer messages. */ GenBuffer::Writable *err; /** NULL for top policy */ Policy *prev, *next; /** Level of the current error being raised. */ level_t curlev; }; protected: /** Boundaries of the policy stack. */ static Policy *policy_top, *policy_bottom; public: friend GenBuffer::Writable& operator <<(GenBuffer::Writable&,Error*); /** Creates a new policy and makes it active by pushing it onto the top of * the policy stack. */ static void pushPolicy(level_t killer_, level_t printed_, level_t recorded_, GenBuffer::Writable *err=(GenBuffer::Writable*)NULLP); /** @return the messages already recorded, and clears the `record' entry * of the current policy. The caller is responsible for deleting the * pointer returned. May return NULLP for empty records. Typical example: * delete Error::getRecorded(); */ static SimBuffer::B *getRecorded(); /** Prints all recorded error messages, and removes the topmost element of * the policy stack. Typical example: * delete Error::getRecorded(); popPolicy(); */ static void popPolicy(); /** @example Error::setTopPrinted(Error::ERROR_CONT); suppress anything * below error, such as warnings. */ static void setTopPrinted(level_t printed_); static level_t getTopPrinted(); /** The Cleanup mechanism is similar to atexit(3) and on_exit(3). This is * just a simple struct with no destructors, virtual methods or inheritance. */ struct Cleanup { /** Must _not_ cause any Errors * @return an exit code. If larger than the current one, replaces it */ typedef int (*handler_t)(Cleanup*); handler_t handler; /** size of extra data allocated */ slen_t size; /** arbitrary data */ void *data; /** NULLP: no next, end of chain */ Cleanup *next; inline char *getBuf() { return (char*)(this+1); } inline slen_t getSize() { return size; } }; /** Creates and registers a new Cleanup, and puts it before old ones. */ static Cleanup* newCleanup(Cleanup::handler_t handler, void *data, slen_t size); static Cleanup* newCleanup(Cleanup::handler_t handler, void *data, char const*cstr); /** Reverts to the default logging policy, * executes the cleanups (in reverse-registration order), and returns the * new exit code, which is at least exitCode. */ static int runCleanups(int exitCode); /* Exits from the process with the specified exit code. */ static void cexit(int exitCode); protected: static Cleanup *first_cleanup; }; GenBuffer::Writable& operator <<(GenBuffer::Writable&,Error*); #endif sam2p-0.49.2/gensi.hpp0000644000175100017510000007530212211371426012654 0ustar ptspts/* gensi.hpp -- generic char buffer and I/O facilities * by pts@fazekas.hu at Sun Feb 24 15:56:02 CET 2002 */ /* Imp: get rid of gensio.o (Buffer::Writable::printf requires B...) */ #ifdef __GNUC__ #pragma interface #endif #ifndef GENSI_HPP #define GENSI_HPP 1 #include "config2.h" #include /* va_list */ #if 'a'!=97 || '!'!=33 #error You need an ASCII system to compile this. #endif /** A very generic, abstract char (pure 8-bit octet) buffer class. This class * doesn't have any attributes. */ class GenBuffer { public: virtual inline ~GenBuffer() {} static inline unsigned hexc2n(char c) { return ((unsigned char)(c-'0')<=(unsigned char)('9'-'0')) ? c-'0' : ((unsigned char)(c-'A')<=(unsigned char)('F'-'A')) ? c-'A'+10 : ((unsigned char)(c-'a')<=(unsigned char)('f'-'a')) ? c-'a'+10 : 16; } /** English ASCII letters [a-zA-Z] */ static void tolower_memcpy(char *dst, char const*s, slen_t slen); /** English ASCII letters [a-zA-Z] */ static void toupper_memcpy(char *dst, char const*s, slen_t slen); /** All letters treated as lower case. @return -1, 0 or 1 */ static int nocase_memcmp(char const*a, char const *s, slen_t slen); static int nocase_strcmp(char const*a, char const *b); /** All letters treated as lower case. @return -1, 0 or 1 */ static bool nocase_strbegins(char const*a, char const *with); static bool strbegins(char const*a, char const *with); static bool parseBool(char const *s, slen_t slen); /* Imp: convert usage of each_sub to first_sub+next_sub */ typedef void (*block_sub_t)(char const*beg, slen_t len, void *data); typedef void (*block_char_t)(char c, void *data); struct Sub { char const*beg; slen_t len; void *data, *data2; }; /** Writable. */ struct SubW { char *beg; slen_t len; void *data, *data2; }; virtual slen_t getLength() const =0; /** Iterates through each subrange of (this), and calls param `block' * for each range. Must call block with positive `len's, and -- as a final * call -- with len==0. * @param data arbitrary data, to be passed to param `block' */ virtual void each_sub(block_sub_t block, void *data) const =0; /** Iterates through each character of (this), and calls param `block' * for each char. Implemented by calling (this).each_sub */ /** Produces sub.len==0 if empty. */ virtual void first_sub(Sub &sub) const =0; /** Produces sub.len==0 if no more subs. * @param sub fields `beg' and `len' are assumed to contain garbage (!) * before invocation. Only `data' and `data2' can be relied upon. */ virtual void next_sub(Sub &sub) const =0; inline void each_char(block_char_t block, void *data) const { void *t[2]= { data, (void*)(long)block }; each_sub(iter_char_sub, (void*)t); } inline bool isEmpty() const { return getLength()==0; } /** @return true iff not empty */ inline virtual operator void*() const { return (void*)(getLength()!=0); } /** @return true iff not empty; pacify VC6.0 */ // inline virtual operator bool() const { return (void*)(getLength()!=0); } // inline virtual operator bool() const { return getLength()!=0; } /** @return true iff empty */ inline virtual bool operator!() const { return getLength()==0; } /** @return getLength() */ virtual slen_t copyRange(char *to, slen_t cfrom, slen_t clen) const; /** @return true on conversion error */ bool toBool(bool &dst); /** @return true on conversion error (overflow etc.) */ bool toInteger(unsigned long &dst); /** @return true on conversion error (overflow etc.) */ bool toInteger(signed long &dst); #if HAVE_LONG_LONG && NEED_LONG_LONG /** @return true on conversion error (overflow etc.) */ bool toInteger(unsigned PTS_CFG_LONGEST &dst); /** @return true on conversion error (overflow etc.) */ bool toInteger(signed PTS_CFG_LONGEST &dst); #endif /* Zero-initialize to pacify gcc-4.2.1 by giving initial value */ inline bool toInteger(unsigned short &i) { unsigned long l = 0; bool b=toInteger(l); i=l; return b; } inline bool toInteger( signed short &i) { signed long l = 0; bool b=toInteger(l); i=l; return b; } inline bool toInteger(unsigned int &i) { unsigned long l = 0; bool b=toInteger(l); i=l; return b; } inline bool toInteger( signed int &i) { signed long l = 0; bool b=toInteger(l); i=l; return b; } /** Allocates a fresh new, null-terminated string. @return true */ bool toCString(char *&dst); /** @return negative iff (this)s2 */ virtual int cmp(GenBuffer const& s2) const; /** @return negative iff (this)s2 */ virtual int cmp(char const* s2, slen_t len) const; /** Null-terminated, calls cmp(char const* s2, slen_t len). */ int cmp(char const* s2) const; friend bool operator==(const GenBuffer& s1, const GenBuffer& s2); friend bool operator==(const char *s1, const GenBuffer& s2); friend bool operator==(const GenBuffer& s1, const char *s2); /* vvv G++ 2.91 doesn't autodetect these 15 operators :-( */ friend bool operator!=(const GenBuffer& s1, const GenBuffer& s2); friend bool operator!=(const char *s1, const GenBuffer& s2); friend bool operator!=(const GenBuffer& s1, const char *s2); friend bool operator<=(const GenBuffer& s1, const GenBuffer& s2); friend bool operator<=(const char *s1, const GenBuffer& s2); friend bool operator<=(const GenBuffer& s1, const char *s2); friend bool operator<(const GenBuffer& s1, const GenBuffer& s2); friend bool operator<(const char *s1, const GenBuffer& s2); friend bool operator<(const GenBuffer& s1, const char *s2); friend bool operator>=(const GenBuffer& s1, const GenBuffer& s2); friend bool operator>=(const char *s1, const GenBuffer& s2); friend bool operator>=(const GenBuffer& s1, const char *s2); friend bool operator>(const GenBuffer& s1, const GenBuffer& s2); friend bool operator>(const char *s1, const GenBuffer& s2); friend bool operator>(const GenBuffer& s1, const char *s2); /** A very generic, abstract char (pure 8-bit octet) output (encoding * stream, filter) class. Writing always succeeds, all data gets written. * No attributes. */ class Writable { public: virtual void vi_write(char const*, slen_t) =0; virtual void vi_putcc(char) =0; inline Writable &operator <<(GenBuffer const& b) { b.each_sub(iter_write_sub, this); return*this; } inline Writable &operator <<(char c) { vi_putcc(c); return*this; } /** Outputs a null-terminated, C string. Not `inline' because the use * of strlen(). */ virtual inline ~Writable() {} Writable& operator <<(char const*); Writable& operator <<(void const*); inline Writable& operator <<( signed short n) { write_num((signed long)n); return*this; } inline Writable& operator <<( signed int n) { write_num((signed long)n); return*this; } inline Writable& operator <<( signed long n) { write_num(n); return*this; } inline Writable& operator <<(unsigned short n) { write_num((unsigned long)n); return*this; } inline Writable& operator <<(unsigned int n) { write_num((unsigned long)n); return*this; } inline Writable& operator <<(unsigned long n) { write_num(n); return*this; } #if HAVE_LONG_LONG && NEED_LONG_LONG inline Writable &operator <<(signed long long n) { write_num(n); return*this; } inline Writable &operator <<(unsigned long long n) { write_num(n); return*this; } #endif inline Writable& operator <<(bool b) { if (b) vi_write("true", 4); else vi_write("false", 5); return*this; } /** appends at most `n' chars; uses SimBuffer::B::vformat as temp */ virtual Writable& vformat(slen_t n, char const *fmt, va_list ap); /** appends; uses SimBuffer::B::vformat as temp */ virtual Writable& vformat(char const *fmt, va_list ap); /** appends; calls vformat */ Writable& format(slen_t n, char const *fmt, ...); /** appends; calls vformat */ Writable& format(char const *fmt, ...); void write_num(signed long n); void write_num(unsigned long n); #if HAVE_LONG_LONG && NEED_LONG_LONG void write_num(signed PTS_CFG_LONGEST n); void write_num(unsigned PTS_CFG_LONGEST n); #endif /** @param zdigits specifies the exact number of digits to be appended. * Zeroes are prepended if necessary. */ void write_num(unsigned long n, unsigned zdigits); #if HAVE_LONG_LONG && NEED_LONG_LONG void write_num(unsigned PTS_CFG_LONGEST n, unsigned zdigits); #endif protected: static void iter_write_sub(char const*beg, slen_t len, void *data); }; /** Interface for a stream of characters. Similar to ISimplyiChar in * CHsplit. No attributes. */ class Readable { public: /** @return -1 on EOF/error, a char (0..255) otherwise. */ virtual int vi_getcc() =0; /** Does a single blocking read. Default functionality: calls vi_getcc() * repeatedly. * @return 0 on EOF/error, positive otherwise: number of characters * successfully read. */ virtual slen_t vi_read(char *to_buf, slen_t max); /** Does multiple blocking reads, tries to fill `to_buf'. Calls vi_read() * repeatedly. */ int readFill(char *to_buf, slen_t max); /** Returns a number not larger than the bytes available _altogether_ * from this stream. The default implementation returns 0, which is * always safe. For regular files, the method should return the size * of the file (unless the size is too large to be represented as an * slen_t), for pipes and sockets, the method should return 0. */ inline virtual slen_t vi_availh() { return 0; } inline bool equal_content(Readable &other); /** Does nothing or rewinds the stream to the beginning, so it can be * read again. The default implementation does nothing. */ inline virtual void vi_rewind() {} virtual inline ~Readable() {} }; protected: static void iter_char_sub(char const*beg, slen_t len, void *data); }; // vvv Doesn't work in gcc 2.95 since we have abstract methods :-(. Must be // declared inside class { ... }; ///GenBuffer::Writable &operator <<(GenBuffer::Writable a, GenBuffer b); /** Collection of some simplistic GenBuffer implementations. */ class SimBuffer { public: class B; /** A flat buffer, i.e occupying consecutive bytes in memory. This class is * useless by itself since memory management (allocation and deletion of the * memory area) isn't implemented. Example of virtual inheritance: needed * because of SimBuffer::B. */ class Flat: virtual public GenBuffer { protected: friend class /*SimBuffer::*/B; /* can read `beg' and `len' */ const char *beg; slen_t len; public: inline virtual slen_t getLength() const { return len; } virtual void each_sub(block_sub_t block, void *data) const { if (len!=0) block(beg,len,data); block(0,0,data); } inline virtual void first_sub(Sub &sub) const { sub.beg=beg; sub.len=len; }; inline virtual void next_sub(Sub &sub) const { sub.len=0; } inline char const*getCString() const { return beg; } inline char const*operator()() const { return beg; } inline char const*begin_() const { return beg; } inline char const*end_() const { return beg+len; } // inline operator char const*() const { return beg; } /* would kill void* */ /** @param idx would cause overload conflict if declared len_t. No range check */ inline char const&operator[](slendiff_t idx) const { return beg[idx]; } /** @return true iff not empty */ inline virtual operator void*() const { return (void*)(len!=0); } // inline operator bool() const { return len!=0; } /** @return true iff empty */ inline virtual bool operator!() const { return len==0; } /** * This is deliberatly not an `operator char' * to avoid the ambiguity of implicit auto-conversion. * @return 1st char or 0. */ inline void toChar(char &ret) const { ret= len==0 ? 0 : *beg; } /** Overridden. */ virtual slen_t copyRange(char *to, slen_t cfrom, slen_t clen) const; /** @return getLength() if not found, offset otherwise */ slen_t findLast(char const c) const; /** @return getLength() if not found, offset otherwise */ slen_t findFirst(char const c) const; /** @return getLength() if not found, offset otherwise */ slen_t findFirst(char const* s, slen_t slen) const; virtual int cmp(Flat const& s2) const; virtual int cmp(char const* s2, slen_t len) const; /** @param fallback default: '\0' * @return if idx is too large: `fallback', otherwise: the asked char */ virtual inline char getAt0(slen_t idx, char fallback='\0') { return idx>=len ? fallback : beg[idx]; } /* Dat: pacify VC6.0: use of undefined type 'SimBuffer' */ friend /*SimBuffer::*/B operator+(const /*SimBuffer::*/Flat& s1, const /*SimBuffer::*/Flat& s2); friend /*SimBuffer::*/B operator+(const char *s1, const /*SimBuffer::*/Flat& s2); friend /*SimBuffer::*/B operator+(const /*SimBuffer::*/Flat& s1, const char *s2); }; /** A statically allocated, read-only char buffer, probably inside the TEXT * section (program code). Needs no delete()ing. `Does' memory management by * not doing anything: statically allocated memory belongs to whole lifetime * of the process, so it doesn't have to be freed. */ class Static: public Flat { public: Static(char const*); Static(char const*beg_,slen_t len_) { beg=beg_; len=len_; } }; /** A flat buffer of fixed length. Not particularly useful, try * SimBuffer::B instead. */ class Fixed: public Flat { public: inline Fixed(slen_t len_) { beg=new char[len_]; len=len_; } virtual inline ~Fixed() { delete [] const_cast(beg); /* Dat: const_cast: pacify VC6.0 */ } private: /** Disable this. */ inline Fixed& operator=(Fixed const&) {return*this;} }; #if 0 /** Fixed-length, writable */ class FixWrite: public GenBuffer { public: }; #endif /** Abstract class. Example of virtual inheritance, needed because of * SimBuffer::B. */ class Appendable: virtual public GenBuffer, public GenBuffer::Writable { public: /** Makes room for `len' more chars at the end of the string, and returns * a pointer to the beginning of that location. Should be efficient. */ virtual char *vi_mkend(slen_t) =0; /** Makes room for `len' more chars at the end of the string, and returns * a pointer to the beginning of that location. May be inefficient. */ virtual char *vi_mkbeg(slen_t) =0; /** Use this instead of append(...). */ virtual void vi_write(char const*, slen_t); inline virtual void vi_putcc(char c) { vi_mkend(1)[0]=c; } /** There is no append(...) method. Use vi_write() instead. */ void prepend(char const*, slen_t); }; /** A one-way linked list of flat strings. Quickest for long memory appends. * Does memory management. */ class Linked: public Appendable { public: struct Node { char *beg; slen_t len; /** May be NULL. */ Node *next; }; Node *first, *last; inline Linked(): first(0), last(0) {} virtual ~Linked(); Linked(GenBuffer const& other); Linked(char const*); Linked& operator=(GenBuffer const& other); Linked& operator=(Linked const& other); virtual slen_t getLength() const; virtual void each_sub(block_sub_t block, void *data) const; virtual void first_sub(Sub &sub) const; virtual void next_sub(Sub &sub) const; virtual char *vi_mkend(slen_t len); virtual char *vi_mkbeg(slen_t len); }; /* Abstract class. */ class Resizable: public Appendable { public: /** Grows the string by the specified `left' and `right' amount on the * sides. The amounts may be positive, zero or negative. For a negative * amount, the `?beg' will be rendered invalid. For a nonnegative amount, * `?beg' will point to the beginning of the new, uninitialized part of the * buffer. */ virtual void vi_grow2(slendiff_t left, slendiff_t right, char **lbeg, char **rbeg) =0; Resizable& operator=(GenBuffer const& other); inline void clearFree() { vi_grow2(0, -(slendiff_t)getLength(), 0, 0); } inline void forgetAll() { vi_grow2(0, -(slendiff_t)getLength(), 0, 0); } /** If howmuch>getLength(), then clears the string. */ inline void forgetLast(slen_t howmuch) { vi_grow2(0, -(slendiff_t)howmuch, 0, 0); } inline void forgetFirst(slen_t howmuch) { vi_grow2(-(slendiff_t)howmuch, 0, 0, 0); } void keepLeft(slen_t howmuch); void keepRight(slen_t howmuch); void keepSubstr(slen_t from_offset, slen_t slen); inline virtual char *vi_mkend(slen_t howmuch) { char *s; vi_grow2(0, howmuch, 0, &s); return s; } inline virtual char *vi_mkbeg(slen_t howmuch) { char *s; vi_grow2(howmuch, 0, &s, 0); return s; } }; /** A simple, non-shared, writable, flat memory buffer of bytes. Supports * fast appends (with rare memory-rallocations) by pre-allocating at most * twice as much memory. Prepends are * slow, because they always include memory allocation and copying. * Does memory management. * Imp: check when `len' overflows (i.e 2*alloced etc.) */ class B: public Resizable, public Flat { /* BUGFIX at Tue Sep 3 18:04:34 CEST 2002: * original order was: public Flat, public Resizable, but I got the * error message from gcc-3.2: gensi.hpp:398: sorry, not implemented: adjusting pointers for covariant returns */ protected: /** Number of bytes preallocated. */ slen_t alloced; char small[8]; public: /** Overridden. */ virtual void vi_grow2(slendiff_t left, slendiff_t right, char **lbeg, char **rbeg); /** Destructor: must be virtual since we have virtual methods. */ virtual ~B() { if (beg!=small) delete [] const_cast(beg); /* ^^^ Dat: const_cast: pacify VC6.0 */ } /** Constructor: the empty buffer. */ inline B(): alloced(sizeof(small)) { beg=small; len=0; } /** Constructor: copy data from a null-terminated C string. */ B(char const*); /** Constructor: copy data from a memory buffer. */ B(char const*,slen_t); /** Constructor: copy-constructor */ B(B const&); /** Constructor: copy data from a Flat buffer. */ B(Flat const&); /** Constructor: copy data from a Flat buffer, term0(). */ B(Flat const&,int); /** Constructor: copy data from a GenBuffer. */ B(GenBuffer const&); /** Constructor: copy (consume) data from a readable stream. */ B(GenBuffer::Readable &); /** Constructor: concatenate two (2) memory buffers. */ B(char const*,slen_t, char const*,slen_t); /** Constructor: concatenate two (2) memory buffers, term0(). */ B(char const*,slen_t, char const*,slen_t,int); /** Constructor: concatenate two GenBuffers. */ B(GenBuffer const&, GenBuffer const&); /** Constructor: concatenate three (3) memory buffers. */ B(char const*,slen_t, char const*,slen_t, char const*,slen_t); /** Constructor: concatenate three (3) GenBuffers. */ B(GenBuffer const&, GenBuffer const&, GenBuffer const&); /** Constructor: concatenate a flat buffer and a C string */ B(Flat const&, char const*); /** Constructor: concatenate three ... */ B(char const*, Flat const&, char const*); /** Constructor: a substring of a Flat buffer */ B(Flat const&, slen_t from_offset, slen_t slen); /** Works even when other==&(this). @return (this) */ B& operator=(/*SimBuffer::*/Flat const& other); /** C++ SUXX: type conversion (Flat& -> B&) doesn't work as expected. * Works even when other==&(this). @return (this) */ B& operator=(/*SimBuffer::*/B const& other); /** @return (this) */ B& operator=(char const*); /** Reads (consumes) the whole `stream', and appends the bytes to (this). * @return (this) declaring `operator<<' inside would ruin inherited `operator<<'s */ /* GenBuffer::Writable& operator<<(GenBuffer::Readable &stream); */ /** Pacify VC6.0 multiple inheritance*/ inline virtual operator void*() const { return (void*)(len!=0); } /** Pacify VC6.0 multiple inheritance */ inline virtual bool operator!() const { return len==0; } friend /*SimBuffer::*/B& operator<<(/*SimBuffer::*/B& self, GenBuffer::Readable &stream); /** Specific operators for faster implementation */ B& operator<<(char c); B& operator<<(char const* s); /** Works even when other==&(this). @return (this) */ B& operator<<(Flat const&); /* C++ inheritance SUXXXX: now I have to re-define _every_ operator<< in GenBuffer::Writable... */ B& operator <<(void const*); inline B& operator <<( signed short n) { write_num((signed long)n); return*this; } inline B& operator <<( signed int n) { write_num((signed long)n); return*this; } inline B& operator <<( signed long n) { write_num(n); return*this; } inline B& operator <<(unsigned short n) { write_num((unsigned long)n); return*this; } inline B& operator <<(unsigned int n) { write_num((unsigned long)n); return*this; } inline B& operator <<(unsigned long n) { write_num(n); return*this; } #if HAVE_LONG_LONG && NEED_LONG_LONG inline B &operator <<(signed long long n) { write_num(n); return*this; } inline B &operator <<(unsigned long long n) { write_num(n); return*this; } #endif inline B& operator <<(bool b) { GenBuffer::Writable::operator<<(b); return*this; } #if 0 friend SimBuffer::B& operator<<(SimBuffer::B& self, char const*s); friend SimBuffer::B& operator<<(SimBuffer::B& self, char c); #endif inline char *begin_() const { return const_cast(beg); } inline char *end_ () const { return const_cast(beg)+len; } inline bool isFull() const { return len==alloced; } /** Ensures beg[len]=='\0'. @return (this) */ B& term0(); /** @param idx would cause overload conflict if declared len_t. No range check */ inline char &operator[](slendiff_t idx) const { return const_cast(beg)[idx]; } /** @param lendiff if negative, then makes the buffer shorter */ void grow_set0_by(slendiff_t lendiff); /** Grows the buffer if necessary, fills with '\0' */ char getAt(slen_t idx); /** Doesn't free unnecessary memory. */ inline void clear() { len=0; } /** Removes oldmuch chars from index first, and makes place for newmuch * chars there. Returns the beginning of the new place. Calls memmove(). * Tue Jun 11 15:33:33 CEST 2002 */ char *substr_grow(slen_t first, slen_t oldmuch, slen_t newmuch); B substr(slen_t first, slen_t howmuch) const; B substr(slen_t first) const; B right(slen_t howmuch) const; B left(slen_t howmuch) const; static void space_pad_cpy(char *dst, char const*src, slen_t pad); /* vi_write() doesn't work if s is inside (this). * There is no append(...) method. Use vi_write() instead. */ // void append(char const*s, const slen_t len_); virtual void vi_write(char const*, slen_t); /* Original: B& vformat(slen_t n, char const *fmt, va_list ap); * Pacify VC6.0: error C2555: 'SimBuffer::B::vformat' : overriding virtual function differs from 'GenBuffer::Writable::vformat' only by return type or calling convention */ /** appends at most `n' chars, no trailing '\0'. This is different from * ANSI (old and C99) stdio.h, because those insert at most `n-1' chars * (not counting the '\0'), _and_ a trailing '\0'. Truncates the output * to `n' chars if it would be longer. (Truncation semantics changed at * Tue Jun 11 14:27:12 CEST 2002. Old: truncate to no chars if longer) */ GenBuffer::Writable& vformat(slen_t n, char const *fmt, va_list ap); /** appends as many chars as requrested */ GenBuffer::Writable& vformat(char const *fmt, va_list ap); /** appends; calls vformat(n); mandatorly non-inline because of ... */ GenBuffer::Writable& format(slen_t n, char const *fmt, ...); /** appends; calls vformat(); mandatorly non-inline because of ... */ GenBuffer::Writable& format(char const *fmt, ...); /* * Name: NonPathMeta * Input: any binary * Output: non-path characters pre-backslashed * Description: Places backslashes in front of non-path characters: * [^-_./a-zA-Z0-9]. * Compatibility: UNIX shells: sh (Bourne Shell), bash, ksh, zsh. Use this in * a shell script to protect a string from word splitting, variable * substitution and everything else. Note that there will be problems * only with \0 (depends on the shell) and \n (will be simply removed by * the shell!). See also Quote::QShell for full shell compatility. * Valid input type: binary * Valid input: any binary * On invalid input: impossible * Inverse of valid: lossy: Quote::UnMeta * Validity indicator: implemented * Output type: some binary * Direction: encode * Method: each_byte * Dependencies: - */ B& appendNpmq(const Flat &other, bool dq=false); /** Quotes a filename (actually a pathname since it may include * (sub)directories) specified in param `other' to be passed to the * most common shell of the host operating system (/bin/sh, COMMAND.COM, * CMD.EXE etc.) as a separate command line argument for a command * invoked from the shell. * * Under UNIX, this differs from appendNpmq only when treating [\n\0]. * Under Win32, the filename is surrounded by double quotes. Double quotes * inside the filename are skipped. Other systems than Win32 are treated * like UNIX. * @param preminus prefix filenames starting with `-' with `./' ? */ B& appendFnq(const Flat &other, bool preminus=false); /** * Name: Quote::NonPathOctal; from quote.rb * Input: any binary * Output: non-path characters converted to octal * Description: Converts non-path characters ([^-_./a-zA-Z0-9]) in * a string to their prebackslashed, 3-digit octal representation (i.e * \123). * Compatibility: Ruby, ANSI C, K&R C, C++, Java (without \u....), * TCL double quotes (without \u....), TCL unquoted strings (without * \u....), Perl5, Pike, AWK, PostScript Level 1, bc. See also * Quote::*Octal. * Valid input type: binary * Valid input: any binary * On invalid input: impossible * Inverse of valid: lossy: Quote::UnSlash * Validity indicator: implemented * Output type: \A[-\\._/a-zA-Z0-9]*\z * Direction: encode * Method: each_byte * Dependencies: - */ B& appendDump(const Flat &other, bool dq=false); B& appendDump(const char c, bool dq=false); /** * Name: Quote::Unslash * Input: a double-quoted (backslashed) version of a string without * the double quotes themselves * Output: the original, unquoted (possibly binary) string * Description: Converts a string expressed inside double quotes of some * programming language (e.g Ruby, C, Java, Perl, Ruby) to its original, * unquoted state. Transformation is done only after backslashes. The * following `common' transformations are supported: \0, \00, \000 * (octal), \a (alarm bell), \b (backslash), \e (escape), \f (form feed), * \n (newline), \r (carriage return), \t (horizontal tab), \v (verical * tab) \x61, \c[, \l (lowercase), \u (upper case), \NL (skip this), * \", \\, \... . * Compatibility: Ruby, ANSI C, C++, Java (without \u....), TCL double * quotes (without \u....), TCL unquoted strings, Perl5, Pike, AWK, * PostScript Level 1, bc, PHP. * See also Quote::UnSlashPHPC for full PHP:StripCSlashes() compatibility. * See also Quote::UnSlashKnr. Compatible with PHP stripcslashes(). * See also Quote::UnSlashKnr. Differs from Quote::UnslashMiddle by not * removing the double quotes from string edges. * Valid input type: binary * Valid input: any binary * On invalid input: impossible * Inverse of valid: lossy: Quote::NonPathOctal * Validity indicator: implemented * Output type: any binary * Direction: decode * Method: gsub * Dependencies: - * * @param iniq the char that surrounds the quoted param `other' * @param other a quoted string * @return an empty string if iniq<256 and param `other' not delimited by iniq */ B& appendUnslash(const Flat &other, int iniq); /** Appends as a C (double-quoted) string. */ B& appendDumpC (const Flat &other, bool dq=false); /** Appends as a PostScript (paren-quoted) string. */ B& appendDumpPS (const Flat &other, bool dq=false); /** Make `other' upper case (English), plus change all non-alpha chars * to underscore. */ B& appendHppq(const Flat &other); protected: inline char *grow_by(slen_t howmuch) { char *s; vi_grow2(0, howmuch, 0, &s); return s; } /*SimBuffer::*/B& B_append(GenBuffer::Readable &stream); #if 0 SimBuffer::B& B_append(char c); SimBuffer::B& B_append(char const*s); #endif }; }; inline SimBuffer::B& operator<<(SimBuffer::B& self, GenBuffer::Readable &stream) { return self.B_append(stream); } #if 0 inline SimBuffer::B& operator<<(SimBuffer::B& self, char const*s) { return self.B_append(s); } inline SimBuffer::B& operator<<(SimBuffer::B& self, char c) { return self.B_append(c); } #endif /** Shorthand synonym */ typedef SimBuffer::B Buffer; inline bool operator ==(const GenBuffer& s1, const GenBuffer& s2) { return 0==s1.cmp(s2); } inline bool operator ==(const char *s1, const GenBuffer& s2) { return 0==s2.cmp(s1); } inline bool operator ==(const GenBuffer& s1, const char *s2) { return 0==s1.cmp(s2); } inline bool operator <(const GenBuffer& s1, const GenBuffer& s2) { return 0>s1.cmp(s2); } inline bool operator <(const char *s1, const GenBuffer& s2) { return 0s1.cmp(s2); } inline bool operator >(const GenBuffer& s1, const GenBuffer& s2) { return 0(const char *s1, const GenBuffer& s2) { return 0>s2.cmp(s1); } inline bool operator >(const GenBuffer& s1, const char *s2) { return 0=s1.cmp(s2); } inline bool operator <=(const char *s1, const GenBuffer& s2) { return 0<=s2.cmp(s1); } inline bool operator <=(const GenBuffer& s1, const char *s2) { return 0>=s1.cmp(s2); } inline bool operator >=(const GenBuffer& s1, const GenBuffer& s2) { return 0<=s1.cmp(s2); } inline bool operator >=(const char *s1, const GenBuffer& s2) { return 0>=s2.cmp(s1); } inline bool operator >=(const GenBuffer& s1, const char *s2) { return 0<=s1.cmp(s2); } inline bool operator !=(const GenBuffer& s1, const GenBuffer& s2) { return 0!=s1.cmp(s2); } inline bool operator !=(const char *s1, const GenBuffer& s2) { return 0!=s2.cmp(s1); } inline bool operator !=(const GenBuffer& s1, const char *s2) { return 0!=s1.cmp(s2); } #endif sam2p-0.49.2/gensio.hpp0000644000175100017510000003571512211371426013037 0ustar ptspts/* gensio.hpp -- generic char buffer and I/O facilities * by pts@fazekas.hu at Tue Feb 26 13:30:02 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef GENSIO_HPP #define GENSIO_HPP 1 #include "config2.h" #include /* va_list */ #include "gensi.hpp" #include /* Naming conventions: *Encode is a specific, well-known PostScript or PDF * encoding filter documented by Adobe, *Encoder is something more general. */ /** Writing 0 bytes for vi_write is interpreted as a close() operation. * Constructor must not write anything to the underlying (lower-level) * Encoder. Implementors must redefine vi_write(). Encoders may be stacked * atop of each other. */ class Encoder: public GenBuffer::Writable { public: /** Default: calls vi_write. */ virtual void vi_putcc(char c); /** vi_write() must be called with positive slen_t for normal writing, and * vi_write(?,0); must be called to signal EOF. After that, it is prohibited * to call vi_write() either way. */ virtual void vi_write(char const*buf, slen_t len) =0; /** Copies all data (till EOF) from stream `f' to (this). */ static void writeFrom(GenBuffer::Writable& out, FILE *f); /** Copies all data (till EOF) from stream `f' to (this). */ static void writeFrom(GenBuffer::Writable& out, GenBuffer::Readable &in); }; /* class Encoder */ /** Implementors must redefine vi_read(), and they may redefine vi_getcc(). * A .vi_read(?,0) has special meaning in a Decoder (but not in a normal * Readable). */ class Decoder: public GenBuffer::Readable { public: /** Calls vi_read(&ret,1). Note that this is the inverse of * GenBuffer::Readable, because there vi_read() calls vi_getcc(). Decoders * may be stacked atop of each other. */ virtual int vi_getcc(); /** vi_read() must be called with positive slen_t for normal reading, and * vi_read(?,0); must be called to signal that the caller would not read from * the Decoder again, so the decoder is allowed to release the resources * used. After that, it is prohibited to call vi_read() either way. */ virtual slen_t vi_read(char *to_buf, slen_t max) =0; }; /* class Decoder */ class DecoderTeller: public Decoder { public: /** Equivalent of ftell() */ virtual long vi_tell() const=0; }; class Filter { public: /** Starts a child process (with popen(pipe_tmpl,"wb")), pipes data to it, * writes output to a temporary file. After _everything_ is written, the * temporary file is read and fed to out_. */ class PipeE: public Encoder { public: PipeE(GenBuffer::Writable &out_, char const*pipe_tmpl, slendiff_t i=0); virtual ~PipeE(); virtual void vi_write(char const*buf, slen_t len); protected: FILE *p; SimBuffer::B tmpname; GenBuffer::Writable &out; SimBuffer::B tmpename, redir_cmd; /** Temporary source file name `%S', forces system() instead of popen() */ SimBuffer::B tmpsname; /** vi_check() is called by this->vi_write(...) (and also when Broken Pipe) * to check whether the encoding succeeded. vi_check() should raise an Error * if it detects failure or simply return if it detects success. Default * implementation: empty body which simly returns. */ virtual void vi_check(); protected: /** Copies the rest of (seekable) file `f' to `out' (subsequent filters). * `f' is initially positioned at the beginning. Must call fclose(f). * vi_copy() should raise Error::...s. The default implementation * just copies the data bytes verbatim. `out.vi_write(0,0);' will be called * by vi_write(). */ virtual void vi_copy(FILE *f); }; /** Gobbles all data written to it, just like /dev/null */ class NullE: public Encoder { public: inline NullE() {} inline virtual ~NullE() {} inline virtual void vi_putcc(char) {} inline virtual void vi_write(char const*, slen_t) {} }; class VerbatimE: public Encoder { public: inline VerbatimE(GenBuffer::Writable& out_): out(&out_) {} inline virtual void vi_write(char const*buf, slen_t len) { out->vi_write(buf,len); } inline void setOut(GenBuffer::Writable& out_) { out=&out_; } inline GenBuffer::Writable& getOut() const { return *out; } protected: GenBuffer::Writable* out; }; class VerbatimCountE: public Encoder { public: inline VerbatimCountE(GenBuffer::Writable& out_): out(&out_), count(0) {} inline virtual void vi_write(char const*buf, slen_t len) { out->vi_write(buf,len); count+=len; } inline void setOut(GenBuffer::Writable& out_) { out=&out_; } inline GenBuffer::Writable& getOut() const { return *out; } inline slen_t getCount() const { return count; } protected: GenBuffer::Writable* out; /** Number of bytes already written */ slen_t count; }; class FILEE: public Encoder { public: inline FILEE(FILE *f_,bool closep_): f(f_), closep(closep_) {} FILEE(char const* filename); inline virtual void vi_putcc(char c) { MACRO_PUTC(c,f); } virtual void vi_write(char const*buf, slen_t len); void close(); protected: FILE *f; bool closep; }; class PipeD: public Decoder { public: PipeD(GenBuffer::Readable &in_, char const*pipe_tmpl, slendiff_t i=0); virtual ~PipeD(); /** Equivalent to vi_read(&ret,1). */ virtual int vi_getcc(); /** Upon the first non-zero call, opens `p', calls vi_precopy() and * closes `in'. Upon all non-zero calls, * reads the temporary file with fread(). Upon vi_read(?,0), removes the * the temporary files. */ virtual slen_t vi_read(char *to_buf, slen_t max); protected: /** 0: never-read (initial state), 1: vi_precopy() already called, 2: EOF reached, `in' closed */ int state; /** opened with popen(?,"w") in state:0->1, then with fopen(?,"rb") in state==1 */ FILE *p; /** Temporary destination file name `%D' */ SimBuffer::B tmpname; GenBuffer::Readable ∈ SimBuffer::B tmpename, redir_cmd; /** Temporary source file name `%S', forces system() instead of popen() */ SimBuffer::B tmpsname; /** Copies the whole `in' to writable pipe `p'. `p' will be closed by the * caller; in.read(0,0) will be called by the caller. * vi_precopy() should raise Error::...s. The default implementation * just copies the data bytes verbatim. */ virtual void vi_precopy(); /** vi_check() is called by this->vi_write(...) (and also when Broken Pipe) * to check whether the encoding succeeded. vi_check() should raise an Error * if it detects failure or simply return if it detects success. Default * implementation: empty body which simly returns. */ virtual void vi_check(); private: void do_close(); }; class VerbatimD: public Decoder { public: inline VerbatimD(GenBuffer::Readable& in_): in(in_) {} /** Works fine even if len==0. */ inline virtual slen_t vi_read(char *buf, slen_t len) { return in.vi_read(buf,len); } protected: GenBuffer::Readable& in; }; class FILED: public DecoderTeller { public: inline FILED(FILE *f_,bool closep_): f(f_), closep(closep_) {} FILED(char const* filename); inline virtual ~FILED() { close(); } inline virtual int vi_getcc() { return MACRO_GETC(f); } virtual slen_t vi_read(char *buf, slen_t len); void close(); inline virtual long vi_tell() const { return ftell(f); } protected: FILE *f; bool closep; }; /** * Sat Apr 19 12:05:49 CEST 2003 * Always opens the file in binary mode. * First reads from the unget buffer, then reads from a FILE*. A typical * usage is: * { Filter::UngetFILED f("in.txt"); // fopen("in.txt","rb"), true); * f.getUnget() << "Prepend this in front of first line.\n"; * int c; * while ((c=f.vi_getcc()!=-1)) putchar(c); * } */ class UngetFILED: public DecoderTeller { public: GenBuffer::Writable& getUnget() { return unget; } BEGIN_STATIC_ENUM(unsigned char, closeMode_t) CM_closep=1, CM_unlinkp=2, CM_keep_stdinp=4, /* CM_unlinkp, but keep STDIN open */ CM_seekablep=8, /* it is sure that this->f is seekable */ CM_MAX=4 END_STATIC_ENUM() inline UngetFILED(FILE *f_, closeMode_t closep_): f(f_), closeMode(closep_), ftell_at(0), ofs(0) {} UngetFILED(char const* filename_, FILE* stdin_f=(FILE*)NULLP, closeMode_t closeMode_=CM_closep); inline virtual ~UngetFILED() { close(); } virtual int vi_getcc(); virtual slen_t vi_read(char *buf, slen_t len); /** Appends a line to buf, including delimiter unless EOF. * @param delimiter: a char or negative to read to EOF */ void appendLine(GenBuffer::Writable &buf, int delimiter='\n'); void close(); // void checkFILE(); inline virtual long vi_tell() const { return ftell_at; } // return ftell_add+ofs+(f!=NULLP ? ftell(f) : 0); } /** * @return equivalent to getc(f) if this->f is not seekable, but returns * -2 if this->f is seekable. */ int getc_seekable(); /** * Actively tests whether FILE* is seekable. Doesn't work for regular files * of 0 bytes. */ bool isSeekable(); /** Reading (this) and reading the returned FILE* will be equivalent * (unless this->getUnget() is used later). * Creates a temporary file if this->unget is not empty. * @param seekable_p if true, the returned FILE* must be seekable. Possibly * creates a temporary file. */ FILE* getFILE(bool seekable_p); /** Implies a getFILE() */ void seek(long abs_ofs); /** Tries to do an fseek(f, -slen, SEEK_CUR). On failure, appends to unget. * The user should only unread() data obtained from vi_read(). */ void unread(char const *s, slen_t slen); inline char const* getFilename() const { return filename; } inline char const* getFilenameDefault(char const *def) const { return filename==NULLP ? def : filename; } inline bool hadError() const { return f!=NULLP && ferror(f); } protected: FILE *f; unsigned char closeMode; slen_t ftell_at; slen_t ofs; SimBuffer::B unget; char const* filename; }; /** Reads from a memory of a GenBuffer via first_sub and next_sub. The * GenBuffer should not be changed during the read. The GenBuffer isn't * delete()d by (this) */ class BufR: public GenBuffer::Readable { public: BufR(GenBuffer const& buf_); virtual int vi_getcc(); virtual slen_t vi_read(char *to_buf, slen_t max); virtual void vi_rewind(); protected: GenBuffer const* bufp; GenBuffer::Sub sub; }; /** Reads from a consecutive memory area, which won't be * delete()d by (this) */ class FlatD: public DecoderTeller /*GenBuffer::Readable*/ { public: FlatD(char const* s_, slen_t slen_); FlatD(char const* s_); virtual int vi_getcc(); virtual slen_t vi_read(char *to_buf, slen_t max); virtual void vi_rewind(); inline int getcc() { return slen!=0 ? (slen--, *(unsigned char const*)s++) : -1; } inline virtual long vi_tell() const { return s-sbeg; } inline long tell() const { return s-sbeg; } protected: char const *s, *sbeg; slen_t slen; }; }; /* class Filter */ class Files { public: /** Formerly `class WritableFILE' */ class FILEW: public GenBuffer::Writable { public: inline FILEW(FILE *f_): f(f_) {} inline virtual void vi_putcc(char c) { MACRO_PUTC(c,f); } inline virtual void vi_write(char const*buf, slen_t len) { fwrite(buf, 1, len, f); } virtual GenBuffer::Writable& vformat(slen_t n, char const *fmt, va_list ap); /** appends; uses SimBuffer::B as temp */ virtual GenBuffer::Writable& vformat(char const *fmt, va_list ap); inline void close() { fclose(f); } inline void setF(FILE *f_) { f=f_; } private: FILE *f; }; /** Formerly `class ReadableFILE'. Doesn't close the its FILE* automatically. */ class FILER: public GenBuffer::Readable { public: inline FILER(FILE *f_): f(f_) {} inline virtual int vi_getcc() { return MACRO_GETC(f); } inline virtual slen_t vi_read(char *to_buf, slen_t max) { return fread(to_buf, 1, max, f); } inline void close() { fclose(f); } inline virtual void vi_rewind() { rewind(f); } private: FILE *f; }; /** @return the beginning of the last substring in param filename that does * not contain '/' (dir separator) */ static char const* only_fext(char const*filename); /** true iff temporary files should be removed at program finish end */ static bool tmpRemove; /** @param fname must start with '/' (dir separator) * @return true if file successfully created */ static FILE *try_dir(SimBuffer::B &dir, SimBuffer::B const&fname, char const*s1, char const*s2, char const*open_mode="wb"); /* The file will be opened for writing only. It won't be registered for * for automatic removal. * @param dir `dir' is empty: appends a unique filename for a temporary * file. Otherwise: returns a unique filename in the specified directory. * Creates the new file with 0 size. * @param extension NULLP or a string specifying the extension of the file * to create (should beginn with ".") * @param open_mode "w", "wb" or "wb+" * @return FILE* opened for writing for success, NULLP on failure * --return true on success, false on failure */ static FILE *open_tmpnam(SimBuffer::B &dir, char const*open_mode="wb", char const*extension=(char const*)NULLP); // static FILE *open_tmpnam(SimBuffer::B &dir, bool binary_p=true, char const*extension=(char const*)NULLP); static bool find_tmpnam(SimBuffer::B &dir); /** Calls lstat(). * @return (slen_t)-1 on error, the size otherwise */ static slen_t statSize(char const* filename); /** Ensures that file will be removed (if possible...) when the process * terminates. Copies the string filename. */ static void tmpRemoveCleanup(char const* filename); /** Ensures that file will be removed (if possible...) when the process * terminates. Copies the string filename. The file will be removed iff * (*p!=NULLP) when the cleanup handler runs. The cleanup handler fclose()s * the file before removing it. */ static void tmpRemoveCleanup(char const* filename, FILE**p); /** Removes the file/entity if exists. * @return 0 on success (file hadn't existed, a directory component * hadn't existed, or the file has been successfully removed), * 1 otherwise */ static int removeIf(char const *filename); /** Sat Sep 7 20:58:54 CEST 2002 */ static void doSignalCleanup(); /** Set the specified file descriptor to binary mode. Useful for stdin (0), * stdout (1), stderr (2) on Win32 and DOS systems. On these systems, this * call has the effect of `fopen(..., "rb");' On UNIX, file * descriptors are always binary. */ #if HAVE_DOS_BINARY static void set_binary_mode(int fd, bool binary); #else static inline void set_binary_mode(int,bool) {} #endif /** Like the system(3) call, but it is able to run a string containing * multiple lines of commands. On Win32, it creates a batch file if * necessary. */ static int system3(char const *commands); }; #endif sam2p-0.49.2/image.hpp0000644000175100017510000004003312211371426012622 0ustar ptspts/* image.hpp -- classes for sampled (indexed, gray and rgb) images * by pts@fazekas.hu Wed Feb 27 09:24:47 CET 2002 */ /* Imp: find memory leaks */ /* Imp: keep future transparency in toIndexed(...) */ #ifdef __GNUC__ #pragma interface #endif #ifndef SAMPLED_HPP #define SAMPLED_HPP 1 #include "config2.h" #include "gensi.hpp" class Image { public: class RGB; class Gray; class Indexed; /** Generic, sampled, rectangular image data. Abstract class. * Each sample is 1, 2, 4 or 8 bits. Regions: * beg..head-1: comment, ignored (e.g unused part of the indexed palette) * headp..rowbeg-1: header: not predicted or compressed (e.g the indexed palette) * rowbeg+0*rlen..rowbeg+0*rlen+rlen-1: sample data of the 0th row, compressed and predicted * rowbeg+1*rlen..rowbeg+1*rlen+rlen-1: sample data of the 1st row * rowbeg+2*rlen..rowbeg+2*rlen+rlen-1: sample data of the 1st row * ... * rowbeg+(h-1)*rlen..rowbeg+h*rlen-1: sample data of the last row * trail..beg+len: trailer, ignored. Its length must be >=bpc. */ class Sampled: public SimBuffer::Flat { public: /** Can hold 1 component of a sample of a single pixel. */ typedef unsigned char sample_t; /** Can hold a height or depth of the image */ typedef unsigned int dimen_t; /** Can hold a row length (in byte), which isn't greater than 3*(image width). */ typedef unsigned int rlen_t; /** RGB = (red<<16)+(green<<8)+(blue). red, green and blue are 0..255 */ #if SIZEOF_LONG>4 && SIZEOF_INT>=4 typedef unsigned int rgb_t; #else typedef unsigned long rgb_t; #endif BEGIN_STATIC_ENUM1(unsigned char) TY_INDEXED=1, TY_GRAY=2, TY_RGB=3, TY_OTHER=4, TY_BLACKBOX=5 END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned char) // static const unsigned char CS_UNKNOWN=0, /* error/unspecified */ CS_GRAYSCALE=1, /* monochrome */ CS_RGB=2, /* red/green/blue */ CS_YCbCr=3, /* Y/Cb/Cr (also known as YUV) */ CS_CMYK=4, /* C/M/Y/K */ CS_YCCK=5, /* Y/Cb/Cr/K */ CS_Indexed_RGB=12 END_STATIC_ENUM() static const unsigned char cs2cpp[6]; /** @return NULLP on error */ static char const *cs2devcs(unsigned char cs); protected: char *headp; char *rowbeg; char *trail; /** Extra offset */ slen_t xoffs; /** Length of one row, in bytes. Each row must begin on a byte boundary, so * extra bits are appended after the rightmost pixel. These bits are * arbitrary, and are ignored by the PostScript interpreter. */ rlen_t rlen; /** Image height, in pixels. */ dimen_t ht; /** Image width, in pixels. */ dimen_t wd; /** Color space. */ unsigned char cs; /** Components per pixel. (number of planes, image depth). 1 for indexed, * 1 for gray, 3 for RGB */ unsigned char cpp; /** BitsPerComponent: 1, 2, 4 or 8. PostScript allows 12 too. */ unsigned char bpc; /** Transparent color value. Imp: ... */ rgb_t transpc; /** Image type, TY_... */ unsigned char ty; /** Initializes various fields, allocates memory. Called from descendants' * constructors. */ void init(slen_t l_comment, slen_t l_header, dimen_t wd_, dimen_t ht_, unsigned char bpc_, unsigned char ty_, unsigned char cpp_); /** Convert samples, make bpc=8, multiplication. */ void to8mul(); /** Convert samples, make bpc=8, no multiplication. */ void to8nomul(); /** Calls copyRGBRow. * @return an Image::Indexed version of (this) iff the number of * colors<=256. Otherwise, returns NULLP. */ Indexed* toIndexed0()/* const*/; /** No averaging is done, only the red component is extracted */ Gray* toGray0(unsigned char bpc_); RGB * toRGB0(unsigned char bpc_); /** @return if any pixels are not gray: false. otherwise: true or false. */ public: inline bool hasTransp() const { return transpc!=0x1000000UL; } virtual bool canGray() const =0; /** @return an RGB BitsPerComponent number (1,2,4 or 8) to which the image * could be converted without any loss. The default implementation calls * copyRGBRow(). */ virtual unsigned char minRGBBpc() const; inline virtual ~Sampled() { delete [] const_cast(beg); } /** Copies whichrow as wd*3 bytes (R0,G0,B0,R1,G1,B1...) to `to' */ virtual void copyRGBRow(char *to, dimen_t whichrow) const =0; virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; inline char *getRowbeg() const { return rowbeg; } inline dimen_t getWd() const { return wd; } inline dimen_t getHt() const { return ht; } inline unsigned char getTy() const { return ty; } inline unsigned char getBpc() const { return bpc; } inline unsigned char getCpp() const { return cpp; } inline unsigned char getCs() const { return cs; } inline slen_t getXoffs() const { return xoffs; } inline rlen_t getRlen() const { return rlen; } inline rgb_t getTranspc() const { return transpc; } inline char *getHeadp() const { return headp; } /** Convert samples, make bpc=8. */ virtual void to8() =0; /** @return NULLP if too many colors for indexed; otherwise a new Image::Indexed. * The caller should `delete' (this) if toIndexed()==NULLP. */ virtual /*Image::*/Indexed* toIndexed() =0; virtual /*Image::*/RGB* toRGB(unsigned char bpc_) =0; virtual /*Image::*/Gray* toGray(unsigned char bpc_) =0; // virtual void setBpc(unsigned char bpc_) =0; friend GenBuffer::Writable& operator<<(GenBuffer::Writable&, /*Image::*/Sampled const&); /** @return address of static buffer: "#RRGGBB" */ static char *rgb2webhash(rgb_t); /** @return (this) or an image containing (this) composed with alpha * channel `al' */ virtual Sampled* addAlpha(/*Image::*/Gray *al) =0; /** assert(al.bpp=8) etc. Imp: document this */ static Indexed* addAlpha0(Sampled *img, Gray *al); }; class Indexed: public Sampled { public: /** @param ncols_ must be >= the colors used */ Indexed(dimen_t wd_, dimen_t ht_, unsigned short ncols_, unsigned char bpc_); /** This includes the transparent color as well. */ inline unsigned short getNcols() const { return (rowbeg-headp)/3; } /** Destroys the color table, and creates one with ncols_ colors. * @param ncols_ must be <= the ncols_ specified in the constructor */ void setNcols(unsigned short ncols_); /** Decreases the size of the palette (forgets last colors) to the * specified amount. */ void setNcolsMove(unsigned short ncols_); void setPal(unsigned char coloridx, rgb_t rgb); rgb_t getPal(unsigned char coloridx) const; /** @param coloridx must be >=0, transp must be -1 */ void setTransp(unsigned char coloridx); /** @return new hasTransp */ bool setTranspc(rgb_t color); virtual void copyRGBRow(char *to, dimen_t whichrow) const; /* virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; */ /** Packs (compresses) the palette so that it will be continuous in * 0..ncols-1, and each color will be used exactly once. The * transparent color (if present) will become black. As a side-effect, * packPal() may set (this)->bpc=8. */ void packPal(); virtual void to8(); virtual /*Image::*/Indexed* toIndexed(); virtual /*Image::*/RGB* toRGB(unsigned char bpc_); virtual /*Image::*/Gray* toGray(unsigned char bpc_); virtual bool canGray() const; inline signed short getTransp() const { return transp; } inline signed short getClearTransp() { signed short ret=transp; transp=-1; return ret; } /** if (transp>0) transp=0;, converts image data. Does not change bpc. */ void makeTranspZero(); virtual unsigned char minRGBBpc() const; /** Separates the current image into Indexed1 images. The caller is * recommended to call packPal() first to reduce the number of required * images. * As a side-effect, * separate() may set (this)->bpc=8. * @return the array of images after full color separation: that is * a dynamically allocated array of `getNcols()-(getTransp()!=-1)' * Indexed images: each image is Indexed1, color 0 is opaque (with the * color obtained from (this)), color 1 is transparent. The returned * array is NULLP-terminated. */ Indexed **separate(); /** Also calls packPal(). As a side effect, changes all transparent * pixels to color index 0. * @return NULLP if no transparent pixels. */ Indexed *calcAlpha(); /** Deletes all elements of p, but not p itself. * @param p a NULLP-terminated list of (Indexed*)s. */ static void delete_separated(Indexed **p); /** Reorganizes the image so it will have the specified bpc. Issues a * runtime error if the specified bpc cannot be achieved. * @param bpc_ the desired bpc, or 0: the best achievable. */ virtual void setBpc(unsigned char bpc_); void dumpDebug(GenBuffer::Writable& gw); protected: /* Index of the transparent color, or -1. */ signed short transp; virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al); /** Sorts the palette colors in lexicographic, stable order. * Called from packPal() to get a consistent palette. */ void sortPal(); }; class Gray: public Sampled { public: Gray(dimen_t wd_, dimen_t ht_, unsigned char bpc_); virtual void copyRGBRow(char *to, dimen_t whichrow) const; virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; virtual void to8(); virtual /*Image::*/Indexed* toIndexed(); virtual bool canGray() const; // virtual void setBpc(unsigned char bpc_); virtual /*Image::*/RGB * toRGB(unsigned char bpc_); virtual /*Image::*/Gray * toGray(unsigned char bpc_); virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al); /** Calls to8(). */ void calcExtrema(unsigned char &lightest, unsigned char &darkest); }; class RGB: public Sampled { public: RGB(dimen_t wd_, dimen_t ht_, unsigned char bpc_); virtual void copyRGBRow(char *to, dimen_t whichrow) const; /* virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; */ virtual void to8(); virtual /*Image::*/Indexed* toIndexed(); virtual bool canGray() const; // virtual void setBpc(unsigned char bpc_); virtual /*Image::*/RGB * toRGB(unsigned char bpc_); virtual /*Image::*/Gray * toGray(unsigned char bpc_); virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al); }; /** Avoid including */ typedef void *filep_t; /** Describes a driver that can load a specific image file format. */ struct Loader { /** Filter::UngetFILED */ class UFD; /** A function that can (allocate and) load a sampled image. Never * returns NULL. On error, it calls Error::.... The filep_t argument * should be really cast back to FILE*. The reader must fclose the FILE*. */ // typedef Sampled*(*reader_t)(filep_t, SimBuffer::Flat const& loadHints); typedef Sampled*(*reader_t)(UFD* ufd, SimBuffer::Flat const& loadHints); BEGIN_STATIC_ENUM1(unsigned) MAGIC_LEN=64 END_STATIC_ENUM() /** A function that checks the magic numbers at the beginning of a file * (already read into buf), and returns NULL if it cannot load an image * of that type, or a reader_t that will load the image. If (and only if!) * file is shorter than 64 bytes, the buf is padded with '\000' bytes. * @param f may read from freely if necessary (MAGIC_LEN is short), but * has to call rewind(f) before reading */ typedef reader_t(*checker_t)(char buf[MAGIC_LEN], char bufend[MAGIC_LEN], SimBuffer::Flat const& loadHints, UFD* ufd); /** A null-terminated, compact string describing (not defining!) the image * file format. * Examples: "GIF", "XPM", "PNM" */ char const*format; checker_t checker; /** Null or next loader. */ Loader *next; }; /** Registers a new type of image Loader, i.e a new image file format. The * new image format will be put in front of all others, and will be checked * first */ static void register0(Loader *); /** Loads the image contained in te file `filename'. * @param format NULLP is unknown (load any format) * or an Image::Loader::format already registered */ static Sampled* load(Loader::UFD* ufd, SimBuffer::Flat const& loadHints, char const* format); static Sampled* load(char const *filename, SimBuffer::Flat const& loadHints, filep_t stdin_f=(filep_t*)NULLP, char const* format=(char const*)NULLP); /* Prints the list of available Loaders (->format), separated by spaces. * Returns the number of available Loaders. Prepends a space if >= loaders. */ static unsigned printLoaders(GenBuffer::Writable &); /** SampleFormat constants */ BEGIN_STATIC_ENUM(unsigned, sf_t) SF_None=0, /* no specific sample format */ SF_Opaque=1, SF_Transparent=2, SF_Gray1=3, SF_Indexed1=4, SF_Mask=5, SF_Transparent2=6, SF_Gray2=7, SF_Indexed2=8, SF_Transparent4=9, SF_Rgb1=10, SF_Gray4=11, SF_Indexed4=12, SF_Transparent8=13, SF_Rgb2=14, SF_Gray8=15, SF_Indexed8=16, SF_Rgb4=17, SF_Rgb8=18, SF_Asis=19, SF_Bbox=20, SF_max=31 END_STATIC_ENUM() /** Contains (and memory-manages) an image, and optimization information * as a cache. * * A SampledInfo contains an image in a canonical format. That is, if two * images have the same RGB8 (identical width, height and pixels) or * blackbox (identical bytes) representation, and SampledInfo{} are * created for both of them, it is guaranteed that the two SampledInfo{}s * contain the same image data (width, height, canGray, minRGBBpc, * SampleFormat (except for bpc), pixel data, palette (same size, colors * and color order)). */ class SampledInfo { public: /** This constructor call takes ownership of the `img_' pointer: it either * reuses the original image (and will delete it in ~SampledInfo), or it * immediately deletes the image, and uses another image. */ SampledInfo(Sampled *img_); ~SampledInfo(); inline Sampled* getImage() const { return img; } /** * Source image, may be modified even if TryOnly==false. If * modified, the original will be freed. * @param sf desired sample format, see Image::SF_* constants * @param WarningOK if false: make the conversion fail if it would produces * a Warning * @param TryOnly if true: don't do the real conversion (but may do auxilary, * idempontent, helper conversion), assume it has succeeded * @param Transparent: as part of the conversion, try to make this RGB color * transparent * @return true iff the conversion succeeded. Note that img may be the same * pointer even when true is returned */ bool setSampleFormat(sf_t sf, bool WarningOK, bool TryOnly, Sampled::rgb_t Transparent); inline Indexed **getImgs() const { return imgs; } inline Sampled *getImg() const { return img; } inline unsigned getNncols() const { return nncols; } void separate(); inline bool canGrayy() const { return canGray; } inline unsigned char minRGBBpcc() const { return minRGBBpc; } inline bool hasTranspp() const { return hasTransp; } inline unsigned char minGrayBpcc() const { return canGray ? minRGBBpc : 0; } inline void clearTransp() { hasTransp=false; } protected: bool hasTransp; /** Number of non-transparent colors, or 257 if >=257. */ unsigned nncols; /** Has only gray colors. */ bool canGray; unsigned char minRGBBpc; Sampled *img; /** The array of images after full color separation. May be NULLP (default), * or a dynamically allocated array of `nncols' Indexed images: each * image is Indexed1, color 0 is opaque (with any value), color 1 * is transparent. */ Indexed **imgs; sf_t sf; }; }; /** Dumps this Image as a rawbits PPM file (plus a comment indicating transparency) * @return the Writable. */ GenBuffer::Writable& operator<<(GenBuffer::Writable&, Image::Sampled const&); #endif sam2p-0.49.2/gensi.cpp0000644000175100017510000010771012211371426012646 0ustar ptspts/* * gensi.cpp * by pts@fazekas.hu at Tue Feb 26 13:28:12 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "gensi.hpp" #include /* strlen() */ // #include /* va_list */ void GenBuffer::iter_char_sub(char const*beg, slen_t len, void *data) { while (len--!=0) (1[(block_char_t**)data][0])(*beg++, 0[(void**)data]); } struct copydata_t { char *to; slen_t cfrom; slen_t clen; slen_t sumlen; }; #define CD static_cast(data) static void iter_copy_sub(char const*beg, slen_t len, void *data) { slen_t i; CD->sumlen+=len; if (CD->clen==0) return; i=CD->cfrom; if (i>=len) { CD->cfrom-=len; return; } if (i>0) { CD->cfrom=0; beg+=i; len-=i; } if (len>=CD->clen) { memcpy(CD->to, beg, CD->clen); CD->clen=0; return; } memcpy(CD->to, beg, len); CD->to+=len; CD->clen-=len; } // #include slen_t GenBuffer::copyRange(char *to, slen_t cfrom, slen_t clen) const { if (clen==0) return getLength(); copydata_t cd= { to, cfrom, clen, 0 }; each_sub(iter_copy_sub, &cd); #if 1 while (cd.clen--!=0) *cd.to++='\0'; /* padding */ #else fprintf(stderr,"cd.clen=%d\n", cd.clen); while (cd.clen--!=0) { fprintf(stderr,"padded.\n"); *cd.to++='\0'; /* padding */ } #endif return cd.sumlen; } #if HAVE_LONG_LONG && NEED_LONG_LONG # define LONGEXT PTS_CFG_LONGEST #else # define LONGEXT long #endif /* Imp: ensure reentrace. Maybe vi_write wants to output a number which would * overwrite ours... */ static char numtmp[sizeof(LONGEXT)*3+2]; bool GenBuffer::toBool(bool &dst) { /* on 1 true yes ja igen igaz be oui vrai: 1tyjibov */ /* off 0 false no nein nem hamis ki non -- : 0fnhk */ slen_t len=copyRange(numtmp, 0, 3); numtmp[0]|=32; numtmp[1]|=32; numtmp[2]|=32; /* poor man's uppercase */ dst=true; if (len==0) return true; if ((numtmp[0]=='o' && numtmp[1]=='f' && numtmp[2]=='f') || numtmp[0]=='0' || numtmp[0]=='f' || numtmp[0]=='n' || numtmp[0]=='h' || numtmp[0]=='k') dst=false; else if ((numtmp[0]<'0' || numtmp[0]>'9') && (numtmp[0]<'a' || numtmp[0]>'z')) return true; return false; } // #include bool GenBuffer::toInteger(unsigned long &dst) { /* Imp: several bases (2, 8, 10 and 16), ignore _too_long_ */ /* Imp: check for overflow! */ slen_t len=copyRange(numtmp, 0, sizeof(numtmp)); // fprintf(stderr,"len=%d\n", len); if (len>=sizeof(numtmp)) return true; /* too long */ /* ASSERT(numtmp null-terminated) */ char *p=numtmp; if (*p=='+') p++; unsigned long i=0; while (1) { // fprintf(stderr,"toInteger'%c'\n", *p); if (*p<'0' || *p>'9') break; i=10*i+(*p-'0'); p++; } dst=i; return *p!='\0'; /* a non-digit arrived */ } bool GenBuffer::toInteger(signed long &dst) { /* Imp: several bases (2, 8, 10 and 16), ignore _too_long_ */ slen_t len=copyRange(numtmp, 0, sizeof(numtmp)); if (len>=sizeof(numtmp)) return true; /* too long */ /* ASSERT(numtmp null-terminated) */ char *p=numtmp; bool neg=false; if (*p=='+') p++; else if (*p=='-') { neg=true; p++; } unsigned long i=0; while (1) { if (*p<'0' || *p>'9') break; i=10*i+(*p-'0'); p++; } dst=neg?-(long)i:i; return *p!='\0'; /* a non-digit arrived */ } #if HAVE_LONG_LONG && NEED_LONG_LONG bool GenBuffer::toInteger(unsigned PTS_CFG_LONGEST &dst) { /* Imp: several bases (2, 8, 10 and 16), ignore _too_long_ */ slen_t len=copyRange(numtmp, 0, sizeof(numtmp)); if (len>=sizeof(numtmp)) return true; /* too long */ /* ASSERT(numtmp null-terminated) */ char *p=numtmp; if (*p=='+') p++; unsigned PTS_CFG_LONGEST i=0; while (1) { if (*p<'0' || *p>'9') break; i=10*i+(*p-'0'); p++; } dst=i; return *p!='\0'; /* a non-digit arrived */ } bool GenBuffer::toInteger(signed PTS_CFG_LONGEST &dst) { /* Imp: several bases (2, 8, 10 and 16), ignore _too_long_ */ slen_t len=copyRange(numtmp, 0, sizeof(numtmp)); if (len>=sizeof(numtmp)) return true; /* too long */ /* ASSERT(numtmp null-terminated) */ char *p=numtmp; bool neg=false; if (*p=='+') p++; else if (*p=='-') { neg=true; p++; } unsigned PTS_CFG_LONGEST i=0; while (1) { if (*p<'0' || *p>'9') break; i=10*i+(*p-'0'); p++; } dst=neg?-i:i; return *p!='\0'; /* a non-digit arrived */ } #endif bool GenBuffer::toCString(char *&dst) { slen_t len=getLength(); dst=new char[len+1]; copyRange(dst, 0, len+1); /* copies the terminating '\0' automatically. */ return false; } int GenBuffer::cmp(GenBuffer const& s2) const { Sub u1, u2; slen_t m; int i; first_sub(u1); s2.first_sub(u2); while (1) { if (u1.len==0 && u2.len==0) return 0; /* (*this) == s2 */ else if (u1.len==0) return -1; /* (*this) < s2 */ else if (u2.len==0) return 1; /* (*this) > s2 */ m=(u1.len s2 */ m=(u1.len0 && 0<(got=vi_read(to_buf, max))) { to_buf+=got; sum+=got; max-=got; } return sum; } /* --- */ void GenBuffer::Writable::iter_write_sub(char const*beg, slen_t len, void *data) { if (len!=0) static_cast(data)->vi_write(beg, len); } GenBuffer::Writable& GenBuffer::Writable::operator <<(char const*cstr) { assert(cstr!=0); vi_write(cstr, strlen(cstr)); return*this; } GenBuffer::Writable& GenBuffer::Writable::operator <<(void const*ptr) { if (ptr==0) vi_write("(null)", 6); else { vi_write("(0d", 3); /* Imp: hexadecimal pointer output */ *this << (PTS_INTP_T)ptr; vi_putcc(')'); } return*this; } void GenBuffer::Writable::write_num(unsigned long n, unsigned zdigits) { if (zdigits>=sizeof(numtmp)) { memset(numtmp,'0',sizeof(numtmp)); while (zdigits>2*sizeof(numtmp)) { vi_write(numtmp, sizeof(numtmp)); zdigits-=sizeof(numtmp); } vi_write(numtmp, zdigits-sizeof(numtmp)); zdigits=sizeof(numtmp); } char *j=numtmp+sizeof(numtmp), *jend=j-zdigits; while (j!=jend) { *--j='0'+n%10; n/=10; } vi_write(j, zdigits); } #if HAVE_LONG_LONG && NEED_LONG_LONG void GenBuffer::Writable::write_num(unsigned PTS_CFG_LONGEST n, unsigned zdigits) { if (zdigits>=sizeof(numtmp)) { memset(numtmp,'0',sizeof(numtmp)); while (zdigits>2*sizeof(numtmp)) { vi_write(numtmp, sizeof(numtmp)); zdigits-=sizeof(numtmp); } vi_write(numtmp, zdigits-sizeof(numtmp)); zdigits=sizeof(numtmp); } char *j=numtmp+sizeof(numtmp), *jend=j-zdigits; while (j!=jend) { *--j='0'+n%10; n/=10; } vi_write(j, zdigits); } #endif void GenBuffer::Writable::write_num(unsigned long n) { char *j=numtmp+sizeof(numtmp); do *--j='0'+n%10; while ((n/=10)!=0); vi_write(j, numtmp+sizeof(numtmp)-j); } void GenBuffer::Writable::write_num(signed long nn) { register unsigned long n; char *j=numtmp+sizeof(numtmp); if (nn<0) { n=-nn; do *--j='0'+n%10; while ((n/=10)!=0); *--j='-'; } else { n=nn; do *--j='0'+n%10; while ((n/=10)!=0); } vi_write(j, numtmp+sizeof(numtmp)-j); } #if HAVE_LONG_LONG && NEED_LONG_LONG void GenBuffer::Writable::write_num(unsigned PTS_CFG_LONGEST n) { char *j=numtmp+sizeof(numtmp); do *--j='0'+n%10; while ((n/=10)!=0); vi_write(j, numtmp+sizeof(numtmp)-j); } void GenBuffer::Writable::write_num(signed PTS_CFG_LONGEST nn) { register unsigned PTS_CFG_LONGEST n; char *j=numtmp+sizeof(numtmp); if (nn<0) { n=-nn; do *--j='0'+n%10; while ((n/=10)!=0); *--j='-'; } else { n=nn; do *--j='0'+n%10; while ((n/=10)!=0); } vi_write(j, numtmp+sizeof(numtmp)-j); } #endif GenBuffer::Writable& GenBuffer::Writable::vformat(slen_t n, char const *fmt, va_list ap) { SimBuffer::B buf; buf.vformat(n, fmt, ap); vi_write(buf(), buf.getLength()); return*this; } GenBuffer::Writable& GenBuffer::Writable::vformat(char const *fmt, va_list ap) { SimBuffer::B buf; buf.vformat(fmt, ap); vi_write(buf(), buf.getLength()); return*this; } GenBuffer::Writable& GenBuffer::Writable::format(slen_t n, char const *fmt, ...) { va_list ap; PTS_va_start(ap, fmt); vformat(n, fmt, ap); va_end(ap); return *this; } GenBuffer::Writable& GenBuffer::Writable::format(char const *fmt, ...) { va_list ap; PTS_va_start(ap, fmt); vformat(fmt, ap); va_end(ap); return *this; } /* --- */ slen_t SimBuffer::Flat::copyRange(char *to, slen_t cfrom, slen_t clen) const { if (cfromlen ? len-cfrom : clen); to+=dlen; } while (clen--!=0) *to++='\0'; /* padding */ return len; } slen_t SimBuffer::Flat::findLast(char const c) const { char const*p; for (p=beg+len;p>=beg;p--) if (*p==c) return p-beg; return len; } slen_t SimBuffer::Flat::findFirst(char const c) const { char const*p, *end=beg+len; for (p=beg;p!=end;p++) if (*p==c) return p-beg; return len; } slen_t SimBuffer::Flat::findFirst(char const* s, slen_t slen) const { if (slen==0) return 0; /* found */ if (slen>len) return len; /* not found */ char const c=*s; char const*p=beg, *end=beg+len-slen+1; if (slen==1) { for (;p!=end;p++) if (*p==c) return p-beg; } else { for (;p!=end;p++) if (*p==c && 0==memcmp(p,s,slen)) return p-beg; } return len; } int SimBuffer::Flat::cmp(SimBuffer::Flat const& s2) const { return memcmp(beg, s2.beg, lens2.len)-(lens2len)-(len0) { char *p=vi_mkend(slen); memcpy(p, str, slen); } } void SimBuffer::Appendable::prepend(char const*str, slen_t slen) { if (slen>0) { char *p=vi_mkbeg(slen); memcpy(p, str, slen); } } /* inlined. void SimBuffer::Appendable::vi_putcc(char c) { vi_mkend(1)[0]=c; }*/ /* --- */ SimBuffer::Linked::~Linked() { Node *n; while (first!=0) { if (first->beg!=(char*)(first+1)) delete [] first->beg; n=first->next; delete [] first; first=n; } } slen_t SimBuffer::Linked::getLength() const { slen_t len=0; Node *n=first; while (n!=0) { len+=n->len; n=n->next; } return len; } SimBuffer::Linked::Linked(GenBuffer const& other) { slen_t len=other.getLength(); Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); other.copyRange(n->beg, 0, len); n->len=len; n->next=0; first=last=n; } SimBuffer::Linked::Linked(char const*str) { slen_t len=strlen(str); Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); memcpy(n->beg, str, len); n->len=len; n->next=0; first=last=n; } SimBuffer::Linked& SimBuffer::Linked::operator=(GenBuffer const& other) { slen_t len=other.getLength(); Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); other.copyRange(n->beg, 0, len); n->len=len; n->next=0; first=last=n; return *this; } SimBuffer::Linked& SimBuffer::Linked::operator=(SimBuffer::Linked const& other) { /* Imp: avoid code repeat */ slen_t len=other.getLength(); Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); other.copyRange(n->beg, 0, len); n->len=len; n->next=0; first=last=n; return *this; } void SimBuffer::Linked::each_sub(GenBuffer::block_sub_t block, void *data) const { Node *n=first; while (n!=0) { block(n->beg, n->len, data); n=n->next; } } void SimBuffer::Linked::first_sub(Sub &sub) const { if (first!=0) { sub.data=first->next; sub.beg=first->beg; sub.len=first->len; } else sub.len=0; } void SimBuffer::Linked::next_sub(Sub &sub) const { if (sub.data!=0) { sub.beg=static_cast(sub.data)->beg; sub.len=static_cast(sub.data)->len; sub.data=static_cast(sub.data)->next; } else sub.len=0; } char *SimBuffer::Linked::vi_mkend(slen_t len) { Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); n->len=len; n->next=0; if (last==0) first=last=n; else { last->next=n; last=n; } return n->beg; } char *SimBuffer::Linked::vi_mkbeg(slen_t len) { Node *n=static_cast(static_cast(new char[sizeof(Node)+len])); n->beg=(char*)(n+1); n->len=len; n->next=first; first=n; if (last==0) last=n; return n->beg; } /* --- */ SimBuffer::Resizable& SimBuffer::Resizable::operator=(GenBuffer const& s2) { vi_grow2(0, s2.getLength()-getLength(), 0, 0); assert(getLength()==s2.getLength()); Sub u1, u2; slen_t m; first_sub(u1); s2.first_sub(u2); assert(!((u1.len==0) ^ (u2.len==0))); /* s1 and s2 end in the same time */ while (u1.len!=0) { m=(u1.len(u1.beg), u2.beg, m); if (0==(u1.len-=m)) next_sub(u1); else u1.beg+=m; if (0==(u2.len-=m)) s2.next_sub(u2); else u2.beg+=m; assert(!((u1.len==0) ^ (u2.len==0))); /* s1 and s2 end in the same time */ } return*this; } //void SimBuffer::Resizable::clear() { /* Inlined. */ // vi_grow2(0, -getLength(), 0, 0); //} void SimBuffer::Resizable::keepLeft(slen_t howmuch) { slen_t len=getLength(); vi_grow2(0, len>howmuch?0-len+howmuch:-(slendiff_t)len, 0, 0); /* ^^^ BUGFIX at Tue Jun 11 19:57:03 CEST 2002 */ } void SimBuffer::Resizable::keepRight(slen_t howmuch) { slen_t len=getLength(); vi_grow2(len>howmuch?0-len+howmuch:-(slendiff_t)len, 0, 0, 0); /* ^^^ BUGFIX at Tue Jun 11 19:57:03 CEST 2002 */ } void SimBuffer::Resizable::keepSubstr(slen_t from_offset, slen_t slen) { slen_t len=getLength(); if (from_offset>=len) vi_grow2(0, -(slendiff_t)len, 0, 0); else if (from_offset+slen>=len) vi_grow2(-(slendiff_t)from_offset, 0, 0, 0); else vi_grow2(-(slendiff_t)from_offset, len-from_offset-slen, 0, 0); } /* --- */ void SimBuffer::B::vi_grow2(slendiff_t left, slendiff_t right, char **lbeg, char **rbeg) { assert(alloced>=len); char *origbeg=const_cast(beg); if (left<0) { if (len<=(slen_t)-left) len=0; else beg-=left; left=0; } /* ! */ if (right<0) { if (len<=(slen_t)-right)len=0; else len+=right;right=0; } /* ^^^ BUGFIX at Tue Jun 11 16:07:56 CEST 2002 */ assert(left>=0); assert(right>=0); slen_t newlen=left+right+len; assert(newlen>=len); char *newbeg; assert(alloced>=sizeof(small)/1); if (beg==small) { assert(alloced==sizeof(small)); if (newlen>sizeof(small)) { assert(newlen>len); newbeg=new char[alloced=2*newlen]; memcpy(newbeg+left, beg, len); beg=newbeg; } } else { /* beg!=small */ // assert(len>=alloced/2); /* -- may not always be true, especially not after appending a `long' */ if (newlensizeof(small)) { newbeg=new char[alloced=newlen]; memcpy(newbeg+left, beg, len); } else { memcpy((newbeg=small)+left, beg, len); delete [] origbeg; alloced=sizeof(small); } beg=newbeg; } else if (newlen>alloced) { /* grow */ assert(newlen>sizeof(small)); assert(newlen>len); newbeg=new char[alloced=2*newlen]; memcpy(newbeg+left, beg, len); delete [] origbeg; beg=newbeg; } else if (beg!=origbeg) { /* called with negative `left' @param */ assert(left==0); memmove(origbeg, beg, len); /* Slow, may move the whole buffer. */ } } // fprintf(stderr, "newlen=%u\n", newlen); len=newlen; if (lbeg) *lbeg=const_cast(beg); if (rbeg) *rbeg=const_cast(beg+newlen-right); assert(alloced==sizeof(small) || (alloced>sizeof(small) && len>=alloced/2)); assert(alloced>=len); } SimBuffer::B::B(char const* cstr): alloced(sizeof(small)) { beg=small; slen_t len_=strlen(cstr); if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), cstr, len); } SimBuffer::B::B(char const* str, slen_t len_): alloced(sizeof(small)) { beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), str, len); } SimBuffer::B::B(SimBuffer::B const& other): GenBuffer(), SimBuffer::Resizable(), SimBuffer::Flat(), alloced(sizeof(small)) { beg=small; if (other.len>sizeof(small)) { len=0; vi_grow2(0, other.len, 0, 0); } else len=other.len; assert(len==other.len); memcpy(const_cast(beg), other.beg, len); } SimBuffer::B::B(SimBuffer::Flat const& other): alloced(sizeof(small)) { beg=small; if (other.len>sizeof(small)) { len=0; vi_grow2(0, other.len, 0, 0); } else len=other.len; assert(len==other.len); memcpy(const_cast(beg), other.beg, len); } SimBuffer::B::B(SimBuffer::Flat const& other,int): alloced(sizeof(small)) { beg=small; if (other.len>=sizeof(small)) { len=0; vi_grow2(0, other.len+1, 0, 0); len--; } else len=other.len; assert(len==other.len); memcpy(const_cast(beg), other.beg, len); const_cast(beg)[len]='\0'; } SimBuffer::B::B(SimBuffer::Flat const& other, slen_t from_offset, slen_t len_): alloced(sizeof(small)) { /* substr */ beg=small; if (from_offsetother.len) len_=other.len-from_offset; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), other.beg+from_offset, len); } else len=0; } SimBuffer::B::B(GenBuffer const& other): alloced(sizeof(small)) { slen_t len_=other.getLength(); beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); other.copyRange(const_cast(beg), 0, len_); } /** Constructor: copy (consume) data from a readable stream. */ SimBuffer::B::B(GenBuffer::Readable &other): alloced(sizeof(small)) { beg=small; len=0; #if 000 operator <<(other); #else B_append(other); #endif } SimBuffer::B::B(char const* as,slen_t al, char const* bs,slen_t bl): alloced(sizeof(small)) { slen_t len_=al+bl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), as, al); memcpy(const_cast(beg)+al, bs, bl); } SimBuffer::B::B(char const* as,slen_t al, char const* bs,slen_t bl,int): alloced(sizeof(small)) { slen_t len_=al+bl; beg=small; if (len_>=sizeof(small)) { len=0; vi_grow2(0, len_+1, 0, 0); len--; } else len=len_; assert(len==len_); memcpy(const_cast(beg), as, al); memcpy(const_cast(beg)+al, bs, bl); const_cast(beg)[al+bl]='\0'; } SimBuffer::B::B(GenBuffer const& a, GenBuffer const& b): alloced(sizeof(small)) { slen_t al=a.getLength(); slen_t bl=b.getLength(); slen_t len_=al+bl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); a.copyRange(const_cast(beg), 0, al); b.copyRange(const_cast(beg)+al, 0, bl); } SimBuffer::B::B(GenBuffer const& a, GenBuffer const& b, GenBuffer const& c): alloced(sizeof(small)) { slen_t al=a.getLength(); slen_t bl=b.getLength(); slen_t cl=c.getLength(); slen_t len_=al+bl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); a.copyRange(const_cast(beg), 0, al); b.copyRange(const_cast(beg)+al, 0, bl); c.copyRange(const_cast(beg)+al+bl, 0, cl); } SimBuffer::B::B(char const* as,slen_t al, char const* bs,slen_t bl, char const* cs,slen_t cl): alloced(sizeof(small)) { slen_t len_=al+bl+cl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), as, al); memcpy(const_cast(beg)+al, bs, bl); memcpy(const_cast(beg)+al+bl, cs, cl); } SimBuffer::B::B(Flat const&b, char const*cs): alloced(sizeof(small)) { slen_t cl=strlen(cs); slen_t len_=b.len+cl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), b.beg, b.len); memcpy(const_cast(beg)+b.len, cs, cl); } SimBuffer::B::B(char const*as, Flat const&b, char const*cs): alloced(sizeof(small)) { slen_t al=strlen(as); slen_t cl=strlen(cs); slen_t len_=al+b.len+cl; beg=small; if (len_>sizeof(small)) { len=0; vi_grow2(0, len_, 0, 0); } else len=len_; assert(len==len_); memcpy(const_cast(beg), as, al); memcpy(const_cast(beg)+al, b.beg, b.len); memcpy(const_cast(beg)+al+b.len, cs, cl); } /* SimBuffer::B& operator<<(SimBuffer::B& self, GenBuffer::Readable &stream); */ SimBuffer::B& SimBuffer::B::B_append(GenBuffer::Readable &stream) { assert(alloced>=len); slen_t oldlen, ask; ask=stream.vi_availh(); if (ask>0) { oldlen=len; vi_grow2(0, ask+1, 0, 0); len=oldlen; } if (alloced!=len) len+=stream.readFill(const_cast(beg+len), alloced-len); while (alloced==len) { /* more data to be read */ oldlen=len; vi_grow2(0, alloced, 0, 0); len=oldlen; stream.readFill(const_cast(beg+len), alloced-len); } return *this; } SimBuffer::B& SimBuffer::B::term0() { if (len==alloced) { vi_grow2(0,1,0,0); len--; } const_cast(beg)[len]='\0'; return *this; } void SimBuffer::B::grow_set0_by(slendiff_t lendiff) { char *rbeg; vi_grow2(0, lendiff, 0, &rbeg); if (lendiff>0) memset(rbeg, '\0', lendiff); } char SimBuffer::B::getAt(slen_t idx) { if (idx(beg), other.beg, len); } return*this; } SimBuffer::B& SimBuffer::B::operator=(SimBuffer::B const& other) { if (&other!=this) { len=0; vi_grow2(0, other.len, 0, 0); memcpy(const_cast(beg), other.beg, len); } return*this; } SimBuffer::B& SimBuffer::B::operator=(char const* cstr) { slen_t slen=strlen(cstr); len=0; vi_grow2(0, slen, 0, 0); memcpy(const_cast(beg), cstr, slen); return*this; } SimBuffer::B SimBuffer::B::substr(slen_t first, slen_t howmuch) const { return SimBuffer::B(*this, first, howmuch); } SimBuffer::B SimBuffer::B::substr(slen_t first) const { /* Actually, this will probably be shorter than end-begin */ return SimBuffer::B(*this, first, len); } SimBuffer::B SimBuffer::B::right(slen_t howmuch) const { return SimBuffer::B(*this, len<=howmuch?0:len-howmuch, howmuch); } SimBuffer::B SimBuffer::B::left(slen_t howmuch) const { return SimBuffer::B(*this, 0, howmuch); } #if 0 void SimBuffer::B::append(char const*s, const slen_t len_) { char *rbeg; vi_grow2(0, len_, 0, &rbeg); memcpy(rbeg, s, len_); } #endif SimBuffer::B operator+(const SimBuffer::Flat& s1, const SimBuffer::Flat& s2) { return SimBuffer::B(s1.beg, s1.len, s2.beg, s2.len); } SimBuffer::B operator+(const char *s1, const SimBuffer::Flat& s2) { return SimBuffer::B(s1, strlen(s1), s2.beg, s2.len); } SimBuffer::B operator+(const SimBuffer::Flat& s1, const char *s2) { return SimBuffer::B(s1.beg, s1.len, s2, strlen(s2)); } SimBuffer::B& SimBuffer::B::operator<<(SimBuffer::Flat const& other) { char *d; vi_grow2(0, other.len, 0, &d); memcpy(d,other.beg,other.len); return*this; } SimBuffer::B& SimBuffer::B::operator<<(char c) { if (len==alloced) { vi_grow2(0, 1, 0, 0); const_cast(beg)[len-1]=c; } else const_cast(beg)[len++]=c; return*this; } SimBuffer::B& SimBuffer::B::operator<<(char const *s) { char *d; slen_t slen=strlen(s); vi_grow2(0, slen, 0, &d); memcpy(d,s,slen); return*this; } void SimBuffer::B::vi_write(char const*str, slen_t slen) { if (slen>0) { char *p; vi_grow2(0, slen, 0, &p); memcpy(p, str, slen); } } #define USGE(a,b) ((unsigned char)(a))>=((unsigned char)(b)) static inline bool is_path(char const c) { return c=='-' || c=='.' || c=='_' || c=='/' || USGE('z'-'a',c-'a') || USGE('Z'-'A',c-'A') || USGE('9'-'0',c-'0'); } static inline bool is_safe_c(char const c) { return c!='\\' && c!='\'' && c!='\"' && USGE('~'-' ',c-' '); } static inline bool is_safe_ps(char const c) { return c!='\\' && c!='(' && c!=')' && USGE('~'-' ',c-' '); } SimBuffer::B& SimBuffer::B::appendDump(const char c, bool dq) { char t[7]; register char *p=t; if (dq) *p++='\''; if (is_path(c)) { *p++=c; } else { *p++='\\'; *p++=('0'+((c>>6)&3)); *p++=('0'+((c>>3)&7)); *p++=('0'+(c&7)); } if (dq) *p++='\''; vi_write(t, p-t); return*this; } SimBuffer::B& SimBuffer::B::appendDump(const SimBuffer::Flat &other, bool dq) { slen_t rlen=dq?2:0; register char c; register char const*p; char const *pend; char *dst; for (p=other.beg,pend=p+other.len; p!=pend; p++) rlen+=is_path(*p)?1:4; vi_grow2(0, rlen, 0, &dst); if (dq) *dst++='"'; for (p=other.beg,pend=p+other.len; p!=pend; p++) { if (is_path(c=*p)) { *dst++=c; } else { *dst++='\\'; *dst++=('0'+((c>>6)&3)); *dst++=('0'+((c>>3)&7)); *dst++=('0'+(c&7)); } } if (dq) *dst++='"'; assert(dst==end_()); return*this; } SimBuffer::B& SimBuffer::B::appendNpmq(const SimBuffer::Flat &other, bool dq) { slen_t rlen=dq?2:0; register char c; register char const*p; char const *pend; char *dst; for (p=other.beg,pend=p+other.len; p!=pend; p++) rlen+=is_path(*p)?1:2; vi_grow2(0, rlen, 0, &dst); if (dq) *dst++='"'; for (p=other.beg,pend=p+other.len; p!=pend; p++) { if (is_path(c=*p)) { *dst++=c; } else { *dst++='\\'; *dst++=c; } } if (dq) *dst++='"'; assert(dst==end_()); return*this; } SimBuffer::B& SimBuffer::B::appendDumpC (const SimBuffer::Flat &other, bool dq) { slen_t rlen=dq?2:0; register char c; register char const*p; char const *pend; char *dst; for (p=other.beg,pend=p+other.len; p!=pend; p++) rlen+=is_safe_c(*p)?1:4; vi_grow2(0, rlen, 0, &dst); if (dq) *dst++='"'; for (p=other.beg,pend=p+other.len; p!=pend; p++) { if (is_safe_c(c=*p)) { *dst++=c; } else { *dst++='\\'; *dst++=('0'+((c>>6)&3)); *dst++=('0'+((c>>3)&7)); *dst++=('0'+(c&7)); } } if (dq) *dst++='"'; assert(dst==end_()); return*this; } SimBuffer::B& SimBuffer::B::appendFnq(const SimBuffer::Flat &other, bool preminus) { slen_t rlen=0; register char c; register char const*p; char const *pend; char *dst; if (OS_COTY==COTY_WINNT || OS_COTY==COTY_WIN9X) { for (p=other.beg,pend=p+other.len; p!=pend; p++) { if ('\0'==(c=*p) || c=='"') break; rlen++; } if (preminus && rlen!=0 && other.beg[0]=='-') rlen+=2; /* .\ */ vi_grow2(0, rlen+2, 0, &dst); *dst++='"'; /* Dat: "ab"c" ""def" is perfectly legal and parses to: `abc def' */ p=other.beg; if (preminus && other.beg[0]=='-') { *dst++='.'; *dst++='\\'; } for (p=other.beg,pend=p+other.len; p!=pend; p++) { if ('\0'==(c=*p) || c=='"') break; *dst++=c; } *dst++='"'; } else { /* Everything else is treated as UNIX */ for (p=other.beg,pend=p+other.len; p!=pend; p++) { if ('\0'==(c=*p)) break; rlen+=is_path(c)?1: c=='\n'?3:2; } if (preminus && rlen!=0 && other.beg[0]=='-') rlen+=2; /* ./ */ vi_grow2(0, rlen, 0, &dst); if (preminus && other.beg[0]=='-') { *dst++='.'; *dst++='/'; } for (p=other.beg,pend=p+other.len; p!=pend; p++) { if ('\0'==(c=*p)) break; if (is_path(c)) *dst++=c; else if (c=='\n') { *dst++='"'; *dst++='\n'; *dst++='"'; } else { *dst++='\\'; *dst++=c; } } } /* IF OS_COTY... */ assert(dst==end_()); return*this; } SimBuffer::B& SimBuffer::B::appendDumpPS (const SimBuffer::Flat &other, bool dq) { slen_t rlen=dq?2:0; register char c; register char const*p; char const *pend; for (p=other.beg,pend=p+other.len; p!=pend; p++) rlen+=is_safe_ps(*p)?1:4; char *dst; vi_grow2(0, rlen, 0, &dst); if (dq) *dst++='('; for (p=other.beg,pend=p+other.len; p!=pend; p++) { if (is_safe_ps(c=*p)) { *dst++=c; } else { *dst++='\\'; *dst++=('0'+((c>>6)&3)); *dst++=('0'+((c>>3)&7)); *dst++=('0'+(c&7)); } } if (dq) *dst++=')'; assert(dst==end_()); return*this; } SimBuffer::B& SimBuffer::B::appendHppq(const SimBuffer::Flat &other) { vi_grow2(0, other.len, 0, 0); char *pend=const_cast(beg)+len; register char c, *p=pend-other.len; memcpy(p, other.beg, other.len); for (;p!=pend;pend++) { c=*p; *p++=( (c>='a' && c<='z') ? (char)(c-'a'+'A') : (c>='A' && c<='Z') ? c : '_' ); } return *this; } SimBuffer::B& SimBuffer::B::appendUnslash(const SimBuffer::Flat &other, int iniq) { slen_t rlen=0; slen_t left=other.len; register char c; register char const*p=other.beg; if (iniq<=256) { if (left<2 || *p!=iniq || p[left-1]!=iniq) return*this; /* ^^^ return empty string */ p++; left-=2; } while (0!=left) { /* Calculate lengths */ c=*p++; if (c!='\\' || left==1) { rlen++; left--; continue; } c=*p++; if (c>='0' && c<='7') { rlen++; if (left>=3 && p[0]>='0' && p[0]<='7') { if (left>=4 && p[1]>='0' && p[1]<='7') { p+=2; left-=4; } else { p+=1; left-=3; } } else left-=2; } else if ((c=='x' || c=='X') && left>=3 && 16!=(hexc2n(p[0]))) { rlen++; if (left>=4 && 16!=(hexc2n(p[1]))) { p+=2; left-=4; } else { p+=1; left-=2; } } else if ((c=='c' || c=='C') && left>=4 && (p[0]=='-' || p[0]=='[')) { rlen++; left-=4; p+=2; } else if (c=='l' && left>=3) { rlen++; left-=3; p++; } else if (c=='u' && left>=3) { rlen++; left-=3; p++; } else if (c=='\n') { left-=2; } else { /* backslash is used for escaping a single char */ rlen++; left-=2; } } char *dst; vi_grow2(0, rlen, 0, &dst); unsigned tmp1, tmp2; left=other.len; p=other.beg; if (iniq<=256) { assert(!(left<2 || *p!=iniq || p[left-1]!=iniq)); p++; left-=2; } while (0!=left) { c=*p++; if (c!='\\' || left==1) { *dst++=(c); left--; continue; } c=*p++; if (c>='0' && c<='7') { if (left>=3 && p[0]>='0' && p[0]<='7') { if (left>=4 && p[1]>='0' && p[1]<='7') { *dst++=((char)((c<<6)+(p[0]<<3)+p[1]-'0'*73)); p+=2; left-=4; } else { *dst++=((char)((c<<3)+p[0]-'0'*9)); p+=1; left-=3; } } else { *dst++=((char)(c-'0')); left-=2; } } else if ((c=='x' || c=='X') && left>=3 && 16!=(tmp1=hexc2n(p[0]))) { if (left>=4 && 16!=(tmp2=hexc2n(p[1]))) { *dst++=((char)((tmp1<<4)+tmp2)); p+=2; left-=4; } else { *dst++=((char)tmp1); p+=1; left-=2; } } else if ((c=='c' || c=='C') && left>=4 && (p[0]=='-' || p[0]=='[')) { *dst++=((char)(p[1]>='a' && p[1]<='z' ? (p[1]+'A'-'a')^64 : p[1]^64)); left-=4; p+=2; } else if (c=='l' && left>=3) { *dst++=((char)(p[0]>='A' && p[0]<='Z' ? p[0]+'a'-'A' : p[0])); left-=3; p++; } else if (c=='u' && left>=3) { *dst++=((char)(p[0]>='a' && p[0]<='z' ? p[0]+'A'-'a' : p[0])); left-=3; p++; } else if (c=='\n') { left-=2; } else { /* backslash is used for escaping a single char */ if (c=='a') c=007; // \x07 (alarm bell) else if (c=='b') c=010; // \x08 (backspace) (_not_ alarm bell) else if (c=='e') c=033; // \x1B (escape) else if (c=='f') c=014; // \x0C (form feed) else if (c=='n') c=012; // \x0A (newline, line feed) else if (c=='r') c=015; // \x0D (carriage return) else if (c=='t') c=011; // \x09 (horizontal tab) else if (c=='v') c=013; // \x0B (vertical tab) *dst++=(c); left-=2; // if (0!=left--) { *dst++=(*p++); left--; } /* already escaped 1 */ } } return*this; } void SimBuffer::B::space_pad_cpy(char *dst, char const*src, slen_t pad) { while (pad!=0 && src[0]!='\0') { *dst++=*src++; pad--; } while (pad--!=0) *dst++=' '; } // #include char *SimBuffer::B::substr_grow(slen_t first, slen_t oldmuch, slen_t newmuch) { slen_t idx=first; if (firstlen) oldmuch=len-first; if (newmucholdmuch) { first+=oldmuch; newmuch-=oldmuch; oldmuch=0; } else return const_cast(beg)+first; } else { len=first=idx=oldmuch=0; if (newmuch==0) { vi_grow2(0,0,0,0); return const_cast(beg); } } // fprintf(stderr, "newmuch=%u oldmuch=%u len=%u\n", newmuch, oldmuch, len); if (newmuch>0) { vi_grow2(0,newmuch,0,0); char *p=const_cast(beg)+first; /* after vi_grow2() */ memmove(p+newmuch, p, len-first-newmuch); } else if (oldmuch>0) { char *p=const_cast(beg)+first; /* before vi_grow2() */ memmove(p, p+oldmuch, len-first-oldmuch); vi_grow2(0,-(slendiff_t)oldmuch,0,0); } else assert(0); // fprintf(stderr, "len=%u oldmuch=%u\n", len, oldmuch); return const_cast(beg)+idx; } /* --- Tue Jul 2 10:47:14 CEST 2002 */ void GenBuffer::tolower_memcpy(char *dst, char const*s, slen_t slen) { while (slen--!=0) *dst++=USGE('Z'-'A',*s-'A') ? *s+++'a'-'A' : *s++; } void GenBuffer::toupper_memcpy(char *dst, char const*s, slen_t slen) { while (slen--!=0) *dst++=USGE('z'-'a',*s-'a') ? *s+++'A'-'a' : *s++; } int GenBuffer::nocase_memcmp(char const*a, char const *s, slen_t slen) { int i; while (slen--!=0) { i=(USGE('Z'-'A',*a-'A') ? *a+++'a'-'A' : *a++) -(USGE('Z'-'A',*s-'A') ? *s+++'a'-'A' : *s++); if (i>0) return 1; if (i<0) return -1; } return 0; } int GenBuffer::nocase_strcmp(char const*a, char const*b) { slen_t alen=strlen(a), blen=strlen(b), min=alen$@ sam2p_main.o: sam2p_version.h xpmc.h: cols2.pl perl -x cols2.pl >xpmc.h #HQ=perl -e'$$_=join"",; s@([^\w\.\/\-])@sprintf"\\%03o",ord$$1@ge; print "\"$$_\"\n"' HQ=perl -x hq.pl #%.tth: %.tte # <$< >$@ $(HQ) #%.tth: %.ttm # <$< >$@ $(HQ) %.tth: %.ttt $(HQ) <$< >$@ # Sun Sep 22 01:16:20 CEST 2002 L1_LIST=l1g8z.pst l1ghz.pst l1gbz.pst \ l1g8l.pst l1ghl.pst l1gbl.pst PREPROC_STRIP=perl -ne's@/\s+(?=\w)@/@g;print if!/^\#/&&!/^\s*\Z/' L1_FLAGS=-DCFG_FMT_ZLIB_ONLY=1 -DNDEBUG=1 \ -DCFG_NO_VAR_S=1 -DUSE_NO_BIND=1 -DUSE_SHORT_NAMES=1 \ -DUSE_CURRENTFILE=1 -DUSE_NO_EOF=1 \ -DUSE_UNITLENGTH_8 -DUSE_EARLYCHANGE_1 -DUSE_LOWBITFIRST_FALSE \ -DUSE_NO_NULLDEF=1 -DUSE_PIN=1 # TTT_QUOTE=perl -e '$$s=$$_=join"",; s@%.*@@g; s@[(][^()]*[)]@@g; die if /[()\\]/ or $$ARGV[0]!~/^(\w+)/; print "\n% TTT_QUOTE\n/$$1 ($$s)\n\n"' -- TTT_QUOTE=perl -e '$$s=$$_=join"",; $$s=~s@([()\\])@\\$$1@g; die if $$ARGV[0]!~/^(\w+)/; print "\n% TTT_QUOTE\n/$$1 ($$s)\n\n"' -- # vvv Dat: input file for `g++ -E' must have .h extension l1g8z.pst: l1zip.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_A85D=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ l1ghz.pst: l1zip.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_HEXD=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ l1gbz.pst: l1zip.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_BINARY=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ l1g8l.pst: l1lzw.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_A85D=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ l1ghl.pst: l1lzw.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_HEXD=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ l1gbl.pst: l1lzw.psm psmlib.psm ps_tiny <$< >$@.tmp.h perl -pe0 $(CXX) -E $(L1_FLAGS) -DUSE_BINARY=1 $@.tmp.h >$@.tmp.i <$@.tmp.i >$@.tmp.pin $(PREPROC_STRIP) <$@.tmp.pin >$@.tmp.ps0 ./ps_tiny <$@.tmp.ps0 >$@.tmp.pst $(TTT_QUOTE) $@ mv -f $@.tmp.pst $@ # vvv copy the .ttt, not the .tth # The perl program down there is a portable cat(1) implementation. bts1.ttt: bts.ttt $(L1_LIST) perl -pe0 $^ >$@ bts2.ttt: bts1.ttt ps_tiny ./ps_tiny --copy <$< >$@ clean: rm -f *~ a.out DEADJOE core *.o *.tth .rgd *.rgd *.tmp.pin *.tmp.i *.tmp.ps0 *.tmp.h *.tmp.pst autom4te.cache/* sam2p_version.h rm -f debian/changelog.dch debian/*~ rm -f $(ALL) $(ALL:=.yes) $(ALL:=.no) $(ALL:=.assert) $(ALL:=.checker) test ! -d autom4te.cache || rmdir autom4te.cache allclean: clean rm -f configure config.h Makehelp config.cache config.log \ config.status test.eps test.pdf build build-stamp distclean: allclean -autoconf dist: distclean dist-noautoconf dist-noautoconf: chmod 755 configure $(BASH) ./mkdist.sh # vvv Create a distribution with more files to aid compilation dist-more: bts2.tth $(BASH) ./mkdist.sh sam2p-more bts2.tth dist-install: dist-noautoconf chmod 600 ../sam2p-*.tar.gz scp ../sam2p-*.tar.gz kozma:public_html # Mac OS/X cp doesn't have -a, so we don't use it install: sam2p -mkdir -p '$(bindir)' cp sam2p '$(bindir)' chmod 755 '$(bindir)'/sam2p # __END__ of Makefile sam2p-0.49.2/rule.hpp0000644000175100017510000002524412211371426012516 0ustar ptspts/* rule.hpp -- Output rules * by pts@fazekas.hu Fri Mar 15 15:11:38 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef RULE_HPP #define RULE_HPP 1 #include "config2.h" #include "gensio.hpp" #include "image.hpp" #include "minips.hpp" /** a namespace */ class Rule { public: struct Cache { bool WarningOK; BEGIN_STATIC_ENUM(unsigned char,ff_t) FF_default=0, /* only for one-liner */ FF_eps=71, /* only for one-liner, temporary */ FF_pdf=72, /* only for one-liner, temporary */ FF_pdfb=73, /* only for one-liner, temporary */ FF_PSL1=110, FF_PSLC=115, FF_PSL2=120, FF_PSL3=130, FF_PDFB10=90, FF_PDFB12=92, FF_PDF10=80, FF_PDF12=82, FF_GIF89a=1, FF_PNM=2, FF_PAM=3, FF_PIP=4, /* Portable Indexed file format by pts */ FF_Empty=5, FF_Meta=6, FF_JPEG=7, FF_TIFF=8, FF_PNG=9, FF_XPM=10, FF_BMP=11, FF_XWD=12, FF_X11=13 /* Don't add a comma, gcc-4.8.1. can't compile it that way. */ END_STATIC_ENUM() ff_t FileFormat; Image::sf_t SampleFormat; /** Used only in appliers.cpp when _check_rule() changes SampleFormat so * setSampleFormat() called before _work() would set that dummy * SampleFormat. */ Image::sf_t origSampleFormat; BEGIN_STATIC_ENUM(unsigned char,te_t) TE_default=0, /* only for one-liner */ TE_Binary=1, TE_ASCII=2, TE_Hex=3, TE_A85=4, TE_MSBfirst=5, TE_LSBfirst=6 END_STATIC_ENUM() te_t TransferEncoding; BEGIN_STATIC_ENUM(unsigned char,co_t) CO_default=0, /* only for one-liner */ CO_None=1, CO_LZW=2, CO_ZIP=3, CO_RLE=4, CO_Fax=5, CO_DCT=6, CO_IJG=7, CO_JAI=8, CO_max=8 END_STATIC_ENUM() co_t Compression; BEGIN_STATIC_ENUM(unsigned char,pr_t) PR_None=1, PR_TIFF2=2, PR_PNGNone=10, PR_PNG=10, PR_PNGSub=11, PR_PNGUP=12, PR_PNGAverage=13, PR_PNGPaeth=14, PR_PNGAuto=15, PR_PNGAutoMaybe=25, PR_PNGAutoBadUnsigned=45, PR_PNGAutoBadSigned=55 END_STATIC_ENUM() pr_t Predictor; Image::Sampled::rgb_t Transparent; bool isOneBit() const; bool isPDF() const; bool isPDFB() const; bool isPS() const; bool isPSL2() const; bool isPSL3() const; bool hasPredictor() const; bool isIndexed() const; bool isTransparentM() const; bool isGray() const; bool isRGB() const; bool isDCTE() const; bool isBinSB() const; /** /Compression/ZIP not OK with /PSL1, /PSLC, /PSL2, /PDF10, /PDFB10 */ bool isZIPOK() const; // bool is8() const; /** @param s is case insensitive, leading `/' is optional. * @return SF_max if not found, or a valid SF_... constant */ static Image::sf_t parseSampleFormat(char const*s, slen_t slen); static char const* dumpFileFormat(ff_t FileFormat, co_t Compression=CO_default); static char const* dumpTransferEncoding(te_t TransferEncoding); static char const* dumpSampleFormat(Image::sf_t SampleFormat); static char const* dumpCompression(co_t Compression); }; struct CacheHints { BEGIN_STATIC_ENUM(unsigned char,sc_t) /* Fri Aug 16 16:33:47 CEST 2002 */ SC_default=0, SC_None=1, SC_OK=2, SC_RotateOK=3 END_STATIC_ENUM() sc_t Scale; /* Image dimensions for encoding filters (may be different from real * image dimensions, but _really_ disrecommended). * slen_t important becasuse of separate(). */ slen_t EncoderColumns, EncoderBPL, EncoderRows; /** Number of color components (channels) per pixel. */ unsigned char EncoderColors; slen_t PredictorColumns; unsigned char PredictorBPC, PredictorColors; unsigned ColorTransform; signed Effort; slen_t RecordSize; slendiff_t K; /* JPEG quality for the IJG encoding filter */ unsigned char Quality; unsigned TransferCPL; MiniPS::String *Comment, *Title, *Subject, *Author, *Creator, *Producer; MiniPS::String *Created, *Produced; MiniPS::Dict *DCT; /** MiniPS::Real* or integer */ MiniPS::VALUE TopMargin, BottomMargin, LeftMargin, RightMargin; /** MiniPS::Real* or integer. Specifies the dimension the image should * be lowered below the baseline for (PostScript or PDF) output with * /Scale/None. Default to 0. */ MiniPS::VALUE LowerMargin; /** 72 by default. */ MiniPS::VALUE ImageDPI; static char const* dumpScale(sc_t Scale); }; struct OutputRule { Cache cache; CacheHints cacheHints; MiniPS::Dict* dict; /* /Hints entry in dict */ MiniPS::Dict* dictHints; /* Number of this output rule, as appeared in .job. Imp: name */ unsigned c; inline bool isEOL() const { return dictHints==NULLP; } /** In: dict, dictHints, cache and cacheHints is uninitialized. Out: they * get inititalized from param. Errors might occur and error messages * might get printed. */ void fromDict(MiniPS::VALUE); /** Calls info->setSampleFormat(), and sets cacheHints.PredictorColumns * and some other fields if they are zero (unspecified in the .job file) */ void doSampleFormat(Image::SampledInfo *info, bool separate=false); /** Appends "" when CO_None, * "<>/CCITTFaxDecode filter" when CO_Fax * "/...Decode filter" otherwise * Calls appendPredictorSpec() if necessary. * For PDF (not PS!), implies appendTransferSpec(). */ void appendDecoderSpec(GenBuffer::Writable &out) const; /** Appends "" when PR_None or * appends "<>" or * appends "<>" * appends "<>" */ void appendPredictorSpec(GenBuffer::Writable &out) const; /** Appends "" or "/ASCII85Decode filter" or "/ASCIIHexDecode filter" */ void appendTransferSpec(GenBuffer::Writable &out) const; bool hasPredictorSpec() const; }; struct Applier { BEGIN_STATIC_ENUM(unsigned,cons_t) DONT_KNOW=0, BAD=1, MAYBE=2, OK=3 END_STATIC_ENUM() /** Checks the specified OutputRule for internal consistency, updates * the `or->cache', emits warnings, and returns consistency status * information. * * -- If (this) Applier doesn't know how to handle the OutputRule, returns * DONT_KNOW immediately. * -- If (this) Applier knows that the OutputRule is internally * inconsistent or proved to be unsupported (i.e printing JPEG images * on PostScript Level1 printers), regardless of the image itself, it * returns BAD immediately and emits a warning about the reason. * -- If (this) Applier knows that the OutputRule may or may not be * processed, depending on the actual image, then MAYBE is returned. * -- If (this) Applier knows that the OutputRule can be processed on * any image, then OK is returned. */ typedef cons_t(*check_rule_t)(OutputRule* or_); /** Outputs (writes) the PostScript or PDF presentation of the image * specified in param `sf' to the output stream in param `out', using * the Output Rule specified in param `or'. * @return DONT_KNOW if doesn't know how to handle the OutputRule; * BAD if it is sure that the image cannot be written with the * specified OutputRule; * OK if writing was successful */ typedef cons_t(*work_t)(GenBuffer::Writable& out, OutputRule*or_, Image::SampledInfo *sf); /** A short, informal description of this Applier. */ char const*format; check_rule_t check_rule; /** May be NULLP if `check_rule' never returns OK or MAYBE */ work_t work; /** Null or next Applier to probe. Filled by register0(); */ Applier *next; }; /* Registers a new type of output Applier, i.e a new output file * format/method. The new output format will be put in front of all others, * and will be checked first by apply_best(). */ static void register0(Applier*); /* Loads the image contained in te file `filename'. */ /** Builds the list of available profiles from the Profile element read * from a .job file. To do the task, calls check_rule() of all registered (!) * Appliers. Also calls OutputRule::fromDict for each profile element. * All returned OutputRules have an Applier which returned OK or MAYBE. * @return a dict==NULLP-terminated list of OutputRules */ static OutputRule* buildProfile(MiniPS::VALUE Profile, bool quiet=false); /** Applies the Profile specified in param `rule_list' to the image * specified in param `sf', and writes the output to param `out'. */ static void applyProfile(GenBuffer::Writable& out, OutputRule*rule_list, Image::SampledInfo *sf); /** Frees memory associated with a profile returned by buildProfile() */ static void deleteProfile(OutputRule*); static unsigned printAppliers(GenBuffer::Writable &out); typedef void (*stream_writer_t)(GenBuffer::Writable&out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); /** Writes a PS/PDF file to `out' according to `template_': substitutes * actual image (pixel) data from `sf->getImg()', and substitutes image * metadata from `sf'. `outstream' should be a prepared stream (top of chain * of Encode filters). * See a .tte file for an example template. */ static void writeTTE( GenBuffer::Writable& out, GenBuffer::Writable& outpal, GenBuffer::Writable& outstream, char const*template_, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings=(char**)NULLP); /** Doesn't invoke MiniPS::delete0(chunkArray); */ static void writeTTM( Filter::VerbatimE &outve, GenBuffer::Writable&outpal, GenBuffer::Writable&outstream, MiniPS::Array *chunkArray, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings=(char**)NULLP); /** Used by writeTTT() to find template specification by name */ static MiniPS::Dict* Templates; /** @param out must be of type Filter::VerbatimE if the template is a TTM * array. * @param template_key a key in file bts.ttt */ static void writeTTT( GenBuffer::Writable&out, GenBuffer::Writable&outpal, GenBuffer::Writable&outstream, char const *template_key, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings=(char**)NULLP); static void writeData(GenBuffer::Writable& out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); static void writePalData(GenBuffer::Writable& out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); }; #endif sam2p-0.49.2/gensio.cpp0000644000175100017510000007751312211371426013034 0ustar ptspts/* * gensio.cpp -- IO-specific methods * by pts@fazekas.hu at Tue Feb 26 13:28:12 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #if 0 extern "C" int errno; /* OK: autodetect with autoconf */ extern "C" int _l_stat(const char *file_name, struct stat *buf); /* OK: Imp: not in ANSI C, but we cannot emulate it! */ extern "C" int _v_s_n_printf ( char *str, size_t n, const char *format, va_list ap ); #else #undef __STRICT_ANSI__ /* for __MINGW32__ */ #define _BSD_SOURCE 1 /* vsnprintf(); may be emulated with fixup_vsnprintf() */ #ifndef __APPLE__ /* SUXX: Max OS X has #ifndef _POSIX_SOURCE around lstat() :-( */ #define _POSIX_SOURCE 1 /* also popen() */ #endif #define _POSIX_C_SOURCE 2 /* also popen() */ #define _XOPEN_SOURCE_EXTENDED 1 /* Digital UNIX lstat */ #ifndef _XPG4_2 #define _XPG4_2 1 /* SunOS 5.7 lstat() */ #endif #undef _XOPEN_SOURCE /* pacify gcc-3.1 */ #define _XOPEN_SOURCE 1 /* popen() on Digital UNIX */ #endif #include "gensio.hpp" #include "error.hpp" #include /* strlen() */ #include /* va_list */ #if _MSC_VER > 1000 // extern "C" int getpid(void); # include #else # include /* getpid() */ #endif #include /* struct stat */ #include /* getenv() */ #include #include /* signal() */ /* Imp: use sigaction */ #if HAVE_DOS_BINARY #undef __STRICT_ANSI__ #include /* O_BINARY */ #include /* setmode() */ #endif #define USGE(a,b) ((unsigned char)(a))>=((unsigned char)(b)) #if HAVE_PTS_VSNPRINTF /* Both old and c99 work OK */ # define VSNPRINTF vsnprintf #else # if OBJDEP # warning REQUIRES: snprintf.o # endif # include "snprintf.h" # define VSNPRINTF fixup_vsnprintf /* Tested, C99. */ #endif static void cleanup(int) { Error::cexit(Error::runCleanups(126)); } void Files::doSignalCleanup() { signal(SIGINT, cleanup); signal(SIGTERM, cleanup); #ifdef SIGHUP signal(SIGHUP, SIG_IGN); #endif /* Dat: don't do cleanup for SIGQUIT */ } GenBuffer::Writable& SimBuffer::B::vformat(slen_t n, char const *fmt, va_list ap) { /* Imp: test this code in various systems and architectures. */ /* Dat: vsnprintf semantics are verified in configure AC_PTS_HAVE_VSNPRINTF, * and a replacement vsnprintf is provided in case of problems. We don't * depend on HAVE_PTS_VSNPRINTF_C99, because C99-vsnprintf is a run-time * property. * * C99 vsnprintf semantics: vsnprintf() always returns a non-negative value: * the number of characters (trailing \0 not included) that would have been * printed if there were enough space. Only the first maxlen (@param) * characters may be modified. The output is terminated by \0 iff maxlen!=0. * NULL @param dststr is OK iff maxlen==0. Since glibc 2.1. * old vsnprintf semantics: vsnprintf() returns a non-negative value or -1: * 0 if maxlen==0, otherwise: -1 if maxlen is shorter than all the characters * plus the trailing \0, otherwise: the number of characters (trailing \0 not * included) that were printed. Only the first maxlen (@param) * characters may be modified. The output is terminated by \0 iff maxlen!=0. * NULL @param dststr is OK iff maxlen==0. */ if (n>0) { /* avoid problems with old-style vsnprintf */ char *s; vi_grow2(0, n+1, 0, &s); len-=n+1; /* +1: sprintf appends '\0' */ const_cast(beg)[len]='\0'; /* failsafe sentinel */ slen_t did=VSNPRINTF(s, n+1, fmt, ap); if (did>n) did=n; /* ^^^ Dat: always true: (unsigned)-1>n, so this works with both old and c99 */ /* Now: did contains the # chars to append, without trailing '\0' */ /* Dat: we cannot check for -1, because `did' is unsigned */ /* Dat: trailer '\0' doesn't count into `did' */ len+=did; } return *this; } GenBuffer::Writable& SimBuffer::B::vformat(char const *fmt, va_list ap) { char dummy, *s; slen_t did=VSNPRINTF(&dummy, 1, fmt, ap), n; if (did>0) { /* skip if nothing to be appended */ /* vvv Dat: we cannot check for -1, because `did' is unsigned */ if ((did+1)!=(slen_t)0) { /* C99 semantics; quick shortcut */ vi_grow2(0, (n=did)+1, 0, &s); len-=n+1; ASSERT_SIDE2(VSNPRINTF(s, n+1, fmt, ap), * 1U==did); } else { /* old semantics: grow the buffer incrementally */ if ((n=strlen(fmt))<16) n=16; /* initial guess */ while (1) { vi_grow2(0, n+1, 0, &s); len-=n+1; /* +1: sprintf appends '\0' */ const_cast(beg)[len]='\0'; /* failsafe sentinel */ did=VSNPRINTF(s, n+1, fmt, ap); if ((did+1)!=(slen_t)0) { assert(did!=0); /* 0 is caught early in this function */ assert(did<=n); /* non-C99 semantics */ break; } n<<=1; } } len+=did; } return *this; } GenBuffer::Writable& SimBuffer::B::format(slen_t n, char const *fmt, ...) { va_list ap; PTS_va_start(ap, fmt); vformat(n, fmt, ap); va_end(ap); return *this; } GenBuffer::Writable& SimBuffer::B::format(char const *fmt, ...) { va_list ap; PTS_va_start(ap, fmt); vformat(fmt, ap); va_end(ap); return *this; } /* --- */ GenBuffer::Writable& Files::FILEW::vformat(slen_t n, char const *fmt, va_list ap) { /* Dat: no vfnprintf :-( */ SimBuffer::B buf; buf.vformat(n, fmt, ap); fwrite(buf(), 1, buf.getLength(), f); return*this; } GenBuffer::Writable& Files::FILEW::vformat(char const *fmt, va_list ap) { vfprintf(f, fmt, ap); return*this; } /* --- */ /** Must be <=32767. Should be a power of two. */ static const slen_t BUFLEN=4096; void Encoder::vi_putcc(char c) { vi_write(&c, 1); } int Decoder::vi_getcc() { char ret; return vi_read(&ret, 1)==1 ? (unsigned char)ret : -1; } void Encoder::writeFrom(GenBuffer::Writable& out, FILE *f) { char *buf=new char[BUFLEN]; int wr; while (1) { if ((wr=fread(buf, 1, BUFLEN, f))<1) break; out.vi_write(buf, wr); } delete [] buf; } void Encoder::writeFrom(GenBuffer::Writable& out, GenBuffer::Readable& in) { char *buf=new char[BUFLEN]; int wr; while (1) { if ((wr=in.vi_read(buf, BUFLEN))<1) break; out.vi_write(buf, wr); } delete [] buf; } /* --- */ Filter::FILEE::FILEE(char const* filename) { if (NULLP==(f=fopen(filename,"wb"))) Error::sev(Error::EERROR) << "Filter::FILEE: error open4write: " << FNQ2(filename,strlen(filename)) << (Error*)0; closep=true; } void Filter::FILEE::vi_write(char const*buf, slen_t len) { if (len==0) close(); else fwrite(buf, 1, len, f); } void Filter::FILEE::close() { if (closep) { fclose(f); f=(FILE*)NULLP; closep=false; } } /* --- */ static FILE* fopenErr(char const* filename, char const* errhead) { FILE *f; if (NULLP==(f=fopen(filename,"rb"))) Error::sev(Error::EERROR) << errhead << ": error open4read: " << FNQ2(filename,strlen(filename)) << (Error*)0; return f; } Filter::FILED::FILED(char const* filename) { f=fopenErr(filename, "Filter::FileD"); closep=true; } slen_t Filter::FILED::vi_read(char *buf, slen_t len) { if (len==0) { close(); return 0; } return fread(buf, 1, len, f); } void Filter::FILED::close() { if (closep) { fclose(f); f=(FILE*)NULLP; closep=false; } } /* --- */ Filter::UngetFILED::UngetFILED(char const* filename_, FILE *stdin_f, closeMode_t closeMode_) { if (stdin_f!=NULLP && (filename_==NULLP || (filename_[0]=='-' && filename_[1]=='\0'))) { f=stdin_f; Files::set_binary_mode(fileno(f), true); closeMode_&=~CM_unlinkp; if (0!=(closeMode_&CM_keep_stdinp)) closeMode_&=~CM_closep; filename_=(char const*)NULLP; /* BUGFIX at Tue Jan 4 23:45:31 CET 2005 */ } else { f=fopenErr(filename_, "Filter::UngetFileD"); } if (filename_!=NULLP) strcpy(const_cast(filename=new char[strlen(filename_)+1]), filename_); else filename=(char*)NULLP; /* fprintf(stderr,"filename:%s\n",filename); */ closeMode=closeMode_; ftell_at=0; ofs=0; } // Filter::UngetFILED::checkFILE() { } slen_t Filter::UngetFILED::vi_read(char *buf, slen_t len) { slen_t delta; if (len==0) { close(); return 0; } else if (unget.getLength()==0) { delta=0; do_read_f: delta+=(f==NULLP ? 0 : fread(buf, 1, len, f)); ftell_at+=delta; return delta; // delta+=fread(buf, 1, len, f); // write(1, buf, delta); // return delta; } else if (ofs+len<=unget.getLength()) { // printf("\nul=%d ft=%ld\n", unget.getLength(), ftell(f)); fflush(stdout); memcpy(buf, unget()+ofs, len); /* Dat: don't remove from unget yet */ ftell_at+=len; // write(1, buf, len); if ((ofs+=len)==unget.getLength()) { unget.forgetAll(); ofs=0; } return len; } else { // printf("\num=%d ft=%d\n", unget.getLength(), ftell(f)); fflush(stdout); delta=unget.getLength()-ofs; /* BUGFIX at Sat Apr 19 17:15:50 CEST 2003 */ memcpy(buf, unget()+ofs, delta); // write(1, buf, delta); unget.forgetAll(); ofs=0; buf+=delta; len-=delta; goto do_read_f; } } void Filter::UngetFILED::close() { if (0!=(closeMode&CM_closep)) { fclose(f); f=(FILE*)NULLP; closeMode&=~CM_closep; } unget.forgetAll(); ofs=0; if (filename!=NULLP) { if (0!=(closeMode&CM_unlinkp)) { remove(filename); } delete [] filename; } } int Filter::UngetFILED::vi_getcc() { if (unget.getLength()==0) { do_getc: int i=-1; if (f!=NULLP && (i=MACRO_GETC(f))!=-1) ftell_at++; return i; } if (ofs==unget.getLength()) { ofs=0; unget.forgetAll(); goto do_getc; } ftell_at++; return unget[ofs++]; } int Filter::UngetFILED::getc_seekable() { /* Glibc stdio doesn't allow fseek() even if the seek would go into the * read buffer, and fseek(f, 0, SEEK_CUR) fails for unseekable files. Fine. */ int c=MACRO_GETC(f); return 0==fseek(f, -1L, SEEK_CUR) ? -2 : c; } bool Filter::UngetFILED::isSeekable() { long pos, posend; if (f==NULLP || 0!=(closeMode&CM_seekablep)) return true; // return false; clearerr(f); /* clears both the EOF and error indicators */ if (-1L==(pos=ftell(f)) /* sanity checks on ftell() and fseek() */ || 0!=fseek(f, 0L, SEEK_CUR) || pos!=ftell(f) || 0!=fseek(f, 0L, SEEK_END) || (posend=ftell(f))==0 || posend(filename=new char[tmpnam.getLength()+1]), tmpnam()); Files::tmpRemoveCleanup(filename); if (unget.getLength()-ofs==fwrite(unget()+ofs, 1, unget.getLength()-ofs, tf)) { static const slen_t BUFSIZE=4096; /* BUGFIX at Sat Apr 19 15:43:59 CEST 2003 */ char *buf=new char[BUFSIZE]; unsigned got; // fprintf(stderr, "ftf=%ld ofs=%d\n", ftell(f), ofs); while ((0<(got=fread(buf, 1, BUFSIZE, f))) && got==fwrite(buf, 1, got, tf)) {} // fprintf(stderr,"got=%d ftell=%d\n", got, ftell(tf)); delete [] buf; } unget.forgetAll(); ofs=0; fflush(tf); rewind(tf); if (ferror(tf) || ferror(f)) Error::sev(Error::EERROR) << "Filter::UngetFILED" << ": cannot write temp file" << (Error*)0; if (0!=(closeMode&CM_closep)) fclose(f); closeMode|=CM_closep|CM_unlinkp; /* close and unlink the temporary file */ /* ^^^ Imp: verify VC++ compilation, +others */ f=tf; } else if (f==NULLP) { /* no real file open */ #if OS_COTY==COTY_UNIX tf=fopen("/dev/null","rb"); #else #if OS_COPTY==COTY_WIN9X || OS_COTY==COTY_WINNT tf=fopen("nul","rb"); #else tf=(FILE*)NULLP; #endif #endif if (tf==NULLP) goto do_temp; /* perhaps inside chroot() */ close(); closeMode|=CM_closep|CM_unlinkp; /* close and unlink the temporary file */ f=tf; } closeMode|=CM_seekablep; return f; } void Filter::UngetFILED::seek(long abs_ofs) { if (abs_ofs==vi_tell()) return; (void) getFILE(true); /* ensure seekability */ if (0!=fseek(f, abs_ofs, SEEK_SET)) Error::sev(Error::EERROR) << "Filter::UngetFILED" << ": cannot seek" << (Error*)0; assert(unget.isEmpty()); assert(ofs==0); ftell_at=abs_ofs; } void Filter::UngetFILED::unread(char const *s, slen_t slen) { ftell_at-=slen; if (slen==0) { } else if (slen<=ofs) { memcpy(const_cast(unget()+(ofs-=slen)), s, slen); } else { slen-=ofs; ofs=0; if (!unget.isEmpty() || 0!=fseek(f, -slen, SEEK_CUR)) { assert(unget.isEmpty()); // !! unget.vi_write(s, slen); /* complete garbage unless unget was empty */ assert(unget.getLength()); } } // fprintf(stderr, "%d..\n", unget.getLength()); } void Filter::UngetFILED::appendLine(GenBuffer::Writable &buf, int delimiter) { // fprintf(stderr, "this=%p %d (%p)\n", this, unget.getLength(), unget()); unget.term0(); if (delimiter<0) { char rbuf[4096]; slen_t got; /* vvv Imp: less memory copying, less stack usage? */ while (0!=(got=vi_read(rbuf, sizeof(rbuf)))) buf.vi_write(rbuf, got); } else if (unget.getLength()==0) { do_getc: int i; if (f!=NULLP) { while ((i=MACRO_GETC(f))>=0 && i!=delimiter) { buf.vi_putcc(i); ftell_at++; } if (i>=0) buf.vi_putcc(i); } } else { char const *p=unget()+ofs, *p0=p, *pend=unget.end_(); assert(ofs<=unget.getLength()); while (p!=pend && *p!=delimiter) p++; ftell_at+=p-p0; if (p==pend) { buf.vi_write(p0, p-p0); ofs=0; unget.forgetAll(); goto do_getc; } ftell_at++; p++; /* found delimiter in `unget' */ buf.vi_write(p0, p-p0); ofs+=p-p0; } } /* --- */ Filter::PipeE::PipeE(GenBuffer::Writable &out_, char const*pipe_tmpl, slendiff_t i): tmpname(), out(out_), tmpename() { /* */ param_assert(pipe_tmpl!=(char const*)NULLP); SimBuffer::B *pp; char const*s=pipe_tmpl; lex: while (s[0]!='\0') { /* Interate throuh the template, substitute temporary filenames */ if (*s++=='%') switch (*s++) { case '\0': case '%': redir_cmd << '%'; break; case 'i': /* the optional integer passed in param `i' */ redir_cmd << i; break; case '*': /* the optional unsafe string passed in param `i' */ redir_cmd << (char const*)i; break; case 'd': case 'D': /* temporary file for encoded data output */ pp=&tmpname; put: // if (*pp) Error::sev(Error::EERROR) << "Filter::PipeE" << ": multiple %escape" << (Error*)0; /* ^^^ multiple %escape is now a supported feature */ // fprintf(stderr, "tmpl=(%s) s=(%s)\n", pipe_tmpl, s); if (!*pp && !Files::find_tmpnam(*pp)) Error::sev(Error::EERROR) << "Filter::PipeE" << ": tmpnam() failed" << (Error*)0; assert(! !*pp); /* pacify VC6.0 */ // *pp << ext; pp->term0(); if ((unsigned char)(s[-1]-'A')<(unsigned char)('Z'-'A')) redir_cmd.appendFnq(*pp, /*preminus:*/ true); /* Capital letter: quote from the shell */ else redir_cmd << *pp; break; case 'e': case 'E': /* temporary file for error messages */ pp=&tmpename; goto put; case 's': case 'S': /* temporary source file */ /* !! if the input is a regular, seekable file, don't copy to a temporary file */ pp=&tmpsname; goto put; default: Error::sev(Error::EERROR) << "Filter::PipeE" << ": invalid %escape in pipe_tmpl" << (Error*)0; } else redir_cmd << s[-1]; } #if 0 if (!tmpname) Error::sev(Error::EERROR) << "Filter::PipeE" << ": no outname (%D) in cmd: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; #else /* Append quoted file redirect to command, if missing */ if (!tmpname) { s=" >%D"; goto lex; } #endif #if !HAVE_PTS_POPEN if (!tmpsname) { s=" <%S"; goto lex; } #endif // tmpname="tmp.name"; redir_cmd.term0(); if (tmpname) { Files::tmpRemoveCleanup(tmpname()); remove(tmpname()); } /* already term0() */ /* ^^^ Dat: remove() here introduces a race condition, but helps early error detection */ if (tmpename) Files::tmpRemoveCleanup(tmpename()); /* already term0() */ if (tmpsname) Files::tmpRemoveCleanup(tmpsname()); /* already term0() */ /* */ // fprintf(stderr, "rc: (%s)\n", redir_cmd()); #if HAVE_PTS_POPEN if (!tmpsname) { if (NULLP==(p=popen(redir_cmd(), "w"CFG_PTS_POPEN_B))) Error::sev(Error::EERROR) << "Filter::PipeE" << ": popen() failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; signal(SIGPIPE, SIG_IGN); /* Don't abort process with SIGPIPE signals if child cannot read our data */ } else { #else if (1) { #endif #if !HAVE_system_in_stdlib Error::sev(Error::EERROR) << "Filter::PipeE" << ": no system() on this system" << (Error*)0; #else if (NULLP==(p=fopen(tmpsname(), "wb"))) Error::sev(Error::EERROR) << "Filter::PipeD" << ": fopen(w) failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; #endif } } void Filter::PipeE::vi_copy(FILE *f) { writeFrom(out, f); if (ferror(f)) Error::sev(Error::EERROR) << "Filter::PipeE: vi_copy() failed" << (Error*)0; fclose(f); } void Filter::PipeE::vi_write(char const*buf, slen_t len) { assert(p!=NULLP); int wr; if (len==0) { /* EOF */ if (tmpsname) { #if HAVE_system_in_stdlib fclose(p); if (0!=(Files::system3(redir_cmd()))) Error::sev(Error::EERROR) << "Filter::PipeE" << ": system() failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; remove(tmpsname()); #endif /* Dat: else is not required; would be unreachable code. */ } else { #if HAVE_PTS_POPEN if (0!=pclose(p)) Error::sev(Error::EERROR) << "Filter::PipeE" << ": pclose() failed; error in external prg" << (Error*)0; #endif } vi_check(); p=(FILE*)NULLP; FILE *f=fopen(tmpname(),"rb"); if (NULLP==f) Error::sev(Error::EERROR) << "Filter::PipeE" <<": fopen() after pclose() failed: " << redir_cmd << ": " << tmpname << (Error*)0; vi_copy(f); // if (ferror(f)) Error::sev(Error::EERROR) << "Filter::Pipe: fread() tmpfile failed" << (Error*)0; // fclose(f); /* ^^^ interacts badly when Image::load() is called inside vi_copy(), * Image::load() calls fclose() */ if (tmpname ) remove(tmpname ()); if (tmpename) remove(tmpename()); if (tmpsname) remove(tmpsname()); out.vi_write(0,0); /* Signal EOF to subsequent filters. */ } else { while (len!=0) { wr=fwrite(buf, 1, len>0x4000?0x4000:len, p); // assert(!ferror(p)); if (ferror(p)) { vi_check(); /* Give a chance to report a better error message when Broken File. */ Error::sev(Error::EERROR) << "Filter::PipeE" << ": pipe write failed" << (Error*)0; } buf+=wr; len-=wr; } } } Filter::PipeE::~PipeE() {} void Filter::PipeE::vi_check() {} /* --- */ Filter::PipeD::PipeD(GenBuffer::Readable &in_, char const*pipe_tmpl, slendiff_t i): state(0), in(in_) { /* */ param_assert(pipe_tmpl!=(char const*)NULLP); SimBuffer::B *pp=(SimBuffer::B*)NULLP; char const*s=pipe_tmpl; lex: while (s[0]!='\0') { /* Interate throuh the template, substitute temporary filenames */ if (*s++=='%') switch (*s++) { case '\0': case '%': redir_cmd << '%'; break; case 'i': /* the optional integer passed in param `i' */ redir_cmd << i; break; case '*': /* the optional unsafe string passed in param `i' */ redir_cmd << (char const*)i; break; case 'd': case 'D': /* temporary file for encoded data output */ pp=&tmpname; put: // if (*pp) Error::sev(Error::EERROR) << "Filter::PipeD: multiple %escape" << (Error*)0; /* ^^^ multiple %escape is now a supported feature */ if (!*pp && !Files::find_tmpnam(*pp)) Error::sev(Error::EERROR) << "Filter::PipeD" << ": tmpnam() failed" << (Error*)0; assert(*pp); pp->term0(); if ((unsigned char)(s[-1]-'A')<(unsigned char)('Z'-'A')) redir_cmd.appendFnq(*pp); /* Capital letter: quote from the shell */ else redir_cmd << *pp; break; case 'e': case 'E': /* temporary file for error messages */ pp=&tmpename; goto put; case 's': case 'S': /* temporary source file */ pp=&tmpsname; goto put; /* OK: implement temporary file for input, option to suppress popen() */ default: Error::sev(Error::EERROR) << "Filter::PipeD: invalid %escape in pipe_tmpl" << (Error*)0; } else redir_cmd << s[-1]; } #if 0 if (!tmpname) Error::sev(Error::EERROR) << "Filter::PipeD" << ": no outname (%D) in cmd: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; #else /* Append quoted file redirect to command, if missing */ if (!tmpname) { s=" >%D"; goto lex; } #endif #if !HAVE_PTS_POPEN if (!tmpsname) { s=" <%S"; goto lex; } #endif // tmpname="tmp.name"; redir_cmd.term0(); if (tmpname) Files::tmpRemoveCleanup(tmpname ()); /* already term0() */ if (tmpename) Files::tmpRemoveCleanup(tmpename()); /* already term0() */ if (tmpsname) { Files::tmpRemoveCleanup(tmpsname()); remove(tmpsname()); } /* already term0() */ /* ^^^ Dat: remove() here introduces a race condition, but helps early error detection */ /* */ } slen_t Filter::PipeD::vi_read(char *tobuf, slen_t tolen) { assert(!(tolen!=0 && state==2)); if (state==2) return 0; /* Should really never happen. */ /* Normal read operation with tolen>0; OR tolen==0 */ if (state==0) { /* Read the whole stream from `in', write it to `tmpsname' */ #if HAVE_PTS_POPEN if (!tmpsname) { if (NULLP==(p=popen(redir_cmd(), "w"CFG_PTS_POPEN_B))) Error::sev(Error::EERROR) << "Filter::PipeD" << ": popen() failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; signal(SIGPIPE, SIG_IGN); /* Don't abort process with SIGPIPE signals if child cannot read our data */ vi_precopy(); in.vi_read(0,0); if (0!=pclose(p)) Error::sev(Error::EERROR) << "Filter::PipeD" << ": pclose() failed; error in external prg" << (Error*)0; } else { #else if (1) { #endif #if !HAVE_system_in_stdlib Error::sev(Error::EERROR) << "Filter::PipeD" << ": no system() on this system" << (Error*)0; #else if (NULLP==(p=fopen(tmpsname(), "wb"))) Error::sev(Error::EERROR) << "Filter::PipeD" << ": fopen(w) failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; vi_precopy(); in.vi_read(0,0); fclose(p); if (0!=(Files::system3(redir_cmd()))) Error::sev(Error::EERROR) << "Filter::PipeD" << ": system() failed: " << (SimBuffer::B().appendDumpC(redir_cmd)) << (Error*)0; remove(tmpsname()); #endif } vi_check(); if (NULLP==(p=fopen(tmpname(),"rb"))) Error::sev(Error::EERROR) << "Filter::PipeD" << ": fopen() after pclose() failed: " << tmpname << (Error*)0; state=1; } /* IF state==0 */ assert(state==1); if (tolen==0 || 0==(tolen=fread(tobuf, 1, tolen, p))) do_close(); // putchar('{'); fwrite(tobuf, 1, tolen, stdout); putchar('}'); return tolen; } void Filter::PipeD::do_close() { fclose(p); p=(FILE*)NULLP; if (tmpname ) remove(tmpname ()); if (tmpename) remove(tmpename()); if (tmpsname) remove(tmpsname()); state=2; } void Filter::PipeD::vi_precopy() { char *buf0=new char[BUFLEN], *buf; slen_t len, wr; while (0!=(len=in.vi_read(buf0, BUFLEN))) { // printf("[%s]\n", buf0); for (buf=buf0; len!=0; buf+=wr, len-=wr) { wr=fwrite(buf, 1, len>0x4000?0x4000:len, p); if (ferror(p)) { vi_check(); /* Give a chance to report a better error message when Broken File. */ Error::sev(Error::EERROR) << "Filter::PipeD" << ": pipe write failed" << (Error*)0; } } } delete [] buf0; } int Filter::PipeD::vi_getcc() { char ret; int i; // fprintf(stderr,"state=%u\n", state); switch (state) { case 0: return vi_read(&ret, 1)==1 ? (unsigned char)ret : -1; case 1: if (-1==(i=MACRO_GETC(p))) do_close(); return i; /* case: 2: fall-through */ } return -1; } void Filter::PipeD::vi_check() {} Filter::PipeD::~PipeD() { if (state!=2) vi_read(0,0); } Filter::BufR::BufR(GenBuffer const& buf_): bufp(&buf_) { buf_.first_sub(sub); } int Filter::BufR::vi_getcc() { if (bufp==(GenBuffer const*)NULLP) return -1; /* cast: pacify VC6.0 */ if (sub.len==0) { bufp->next_sub(sub); if (sub.len==0) { bufp=(GenBuffer const*)NULLP; return -1; } } sub.len--; return *sub.beg++; } slen_t Filter::BufR::vi_read(char *to_buf, slen_t max) { if (max==0 || bufp==(GenBuffer const*)NULLP) return 0; if (sub.len==0) { bufp->next_sub(sub); if (sub.len==0) { bufp=(GenBuffer const*)NULLP; return 0; } } if (maxfirst_sub(sub); } Filter::FlatD::FlatD(char const* s_, slen_t slen_): s(s_), sbeg(s_), slen(slen_) {} Filter::FlatD::FlatD(char const* s_): s(s_), sbeg(s_), slen(strlen(s_)) {} void Filter::FlatD::vi_rewind() { s=sbeg; } int Filter::FlatD::vi_getcc() { if (slen==0) return -1; slen--; return *(unsigned char const*)s++; } slen_t Filter::FlatD::vi_read(char *to_buf, slen_t max) { if (max>slen) max=slen; memcpy(to_buf, s, max); s+=max; slen-=max; return max; } /* --- */ #if HAVE_lstat_in_sys_stat # define PTS_lstat lstat #else # define PTS_lstat stat #endif /** @param fname must start with '/' (dir separator) * @return true if file successfully created */ FILE *Files::try_dir(SimBuffer::B &dir, SimBuffer::B const&fname, char const*s1, char const*s2, char const*open_mode) { if (dir.isEmpty() && s1==(char const*)NULLP) return (FILE*)NULLP; SimBuffer::B full(s1!=(char const*)NULLP?s1:dir(), s1!=(char const*)NULLP?strlen(s1):dir.getLength(), s2!=(char const*)NULLP?s2:"", s2!=(char const*)NULLP?strlen(s2):0, fname(), fname.getLength()); full.term0(); struct stat st; FILE *f; /* Imp: avoid race conditions with other processes pretending to be us... */ if (-1!=PTS_lstat(full(), &st) || (0==(f=fopen(full(), open_mode))) || ferror(f) ) return (FILE*)NULLP; dir=full; return f; } #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT # define DIR_SEP "\\" #else # define DIR_SEP "/" #endif FILE *Files::open_tmpnam(SimBuffer::B &dir, char const*open_mode, char const*extension) { /* Imp: verify / on Win32... */ /* Imp: ensure uniqueness on NFS */ /* Imp: short file names */ static unsigned PTS_INT32_T counter=0; assert(Error::tmpargv0!=(char const*)NULLP); SimBuffer::B fname(DIR_SEP "tmp_", 5, Error::tmpargv0,strlen(Error::tmpargv0)); /* ^^^ Dat: we need DIR_SEP here, because the name of the tmp file may be * passed to Win32 COMMAND.COM, which interprets "/" as a switch */ long pid=getpid(); if (pid<0 && pid>-(1<<24)) pid=-pid; fname << '_' << pid << '_' << counter++; if (extension) fname << extension; fname.term0(); FILE *f=(FILE*)NULLP; // char const* open_mode=binary_p ? "wb" : "w"; /* Dat: "bw" is bad */ (void)( ((FILE*)NULLP!=(f=try_dir(dir, fname, 0, 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, getenv("TMPDIR"), 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, getenv("TMP"), 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, getenv("TEMP"), 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, PTS_CFG_P_TMPDIR, 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "/tmp", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, getenv("WINBOOTDIR"), "//temp", open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, getenv("WINDIR"), "//temp", open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "c:/temp", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "c:/windows/temp", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "c:/winnt/temp", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "c:/tmp", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, ".", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "..", 0, open_mode))) || ((FILE*)NULLP!=(f=try_dir(dir, fname, "../..", 0, open_mode))) ); return f; } bool Files::find_tmpnam(SimBuffer::B &dir) { FILE *f=open_tmpnam(dir); if (f!=NULL) { fclose(f); return true; } return false; } bool Files::tmpRemove=true; static int cleanup_remove(Error::Cleanup *cleanup) { if (Files::tmpRemove) { int err = Files::removeIf(cleanup->getBuf()); if (err) Error::sev(Error::ERROR_CONT) << "could not remove tmp file: " << cleanup->getBuf() << (Error*)0; return err; } Error::sev(Error::WARNING) << "keeping tmp file: " << cleanup->getBuf() << (Error*)0; return 0; } void Files::tmpRemoveCleanup(char const* filename) { Error::newCleanup(cleanup_remove, 0, filename); } static int cleanup_remove_cond(Error::Cleanup *cleanup) { if (*(FILE**)cleanup->data!=NULLP) { fclose(*(FILE**)cleanup->data); return cleanup_remove(cleanup); } return 0; } void Files::tmpRemoveCleanup(char const* filename, FILE**p) { param_assert(p!=NULLP); Error::newCleanup(cleanup_remove_cond, (void*)p, filename); } int Files::removeIf(char const* filename) { if (0==remove(filename) || errno==ENOENT) return 0; return 1; } slen_t Files::statSize(char const* filename) { struct stat st; if (-1==PTS_lstat(filename, &st)) return (slen_t)-1; return st.st_size; } /* Tue Jul 2 10:57:21 CEST 2002 */ char const* Files::only_fext(char const*filename) { char const *ret; if (OS_COTY==COTY_WINNT || OS_COTY==COTY_WIN9X) { if ((USGE('z'-'a',filename[0]-'a') || USGE('Z'-'A',filename[0]-'A')) && filename[1]==':' ) filename+=2; /* strip drive letter */ ret=filename; while (*filename!='\0') { if (*filename=='/' || *filename=='\\') ret=++filename; else filename++; } } else { /* Everything else is treated as UNIX */ ret=filename; while (filename[0]!='\0') if (*filename++=='/') ret=filename; } return ret; } #if HAVE_DOS_BINARY void Files::set_binary_mode(int fd, bool binary) { /* Wed Dec 11 18:17:30 CET 2002 */ setmode(fd, binary ? O_BINARY : O_TEXT); } #endif int Files::system3(char const *commands) { #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT char const *p; p=commands; while (*p!='\0' && *p!='\n') p++; if (*p=='\0') return system(commands); /* no newline -- simple run */ SimBuffer::B tmpnam; FILE *f=Files::open_tmpnam(tmpnam, /*binary_p:*/false, ".bat"); tmpnam.term0(); Files::tmpRemoveCleanup(tmpnam()); fprintf(f, "@echo off\n%s\n", commands); if (ferror(f)) Error::sev(Error::EERROR) << "system3: write to tmp .bat file: " << tmpnam << (Error*)NULLP; fclose(f); // printf("(%s)\n", tmpnam()); system("bash"); // int ret=system(("sh "+tmpnam)()); int ret=system(tmpnam()); remove(tmpnam()); return ret; #else return system(commands); #endif } /* __END__ */ sam2p-0.49.2/minips.hpp0000644000175100017510000003151012211371426013037 0ustar ptspts/* minips.hpp -- mini-PostScript parser and structure builder * by pts@fazekas.hu at Sat Mar 9 21:33:04 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef MINIPS_HPP #define MINIPS_HPP 1 #include "config2.h" #include "gensi.hpp" #include "error.hpp" class MiniPS { public: #if SIZEOF_VOID_P <= SIZEOF_INT typedef signed int ii_t; #elif SIZEOF_VOID_P <= SIZEOF_LONG typedef signed long ii_t; #elif SIZEOF_VOID_P <= SIZEOF_CFG_LONGEST typedef signed PTS_CFG_LONGEST ii_t; #else #error No integral data type to hold a ptr. #endif class Real; /*union*/ struct TokVal { SimBuffer::B *bb; ii_t i; /* double d; */ /*MiniPS::*/Real *r; }; /** minips tokenizer */ class Tokenizer { public: BEGIN_STATIC_ENUM1(int) EOFF=-1, NO_UNGOT=-2 END_STATIC_ENUM() Tokenizer(GenBuffer::Readable& in_); /** Reads and returns next token. * Token types are named for their first character: * '1': integertype: 31 bits signed (-1073741824 .. 1073741823) is * guaranteed. VALUED * '.': realtype (NOT implemented), double guaranteed. VALUED * 'E': Ename (name without a slash). VALUED * '/': Sname (name beginning with a slash). VALUED * '(': stringtype (also with `') VALUED * '[': beginning-of-array (also with `{') * ']': end-of-array (also with '}') * '<': beginning-of-dict (`<<') * '>': end-of-dict (`>>') * -1: EOF */ int yylex(); inline TokVal const& lastTokVal() const { return tv; } protected: /** Data for last token read. */ TokVal tv; SimBuffer::B b; GenBuffer::Readable& in; /* NO_UNGOT for nothing, EOFF for EOF, 0..255 otherwise */ int ungot; }; /* This is somewhat similar to Ruby */ typedef ii_t VALUE; /** Qundef is the undefined hash key or array elements. It is an _invalid_ VALUE! */ BEGIN_STATIC_ENUM1(VALUE) Qfalse=0, Qtrue=2, Qnull=4, Qundef=6, Qpop=8, Qerror=10, Qmax_=10 END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned) T_NULL=1, T_BOOLEAN=2, T_INTEGER=3, T_REAL=4, T_STRING=5, T_ARRAY=6, T_DICT=7, T_SNAME=8, T_ENAME=9, T_VOID=10, S_SENUM=20, /* must be a dict-member; meta-type used by scanf_dict() */ S_FUNC=21, /* call a function to determine; meta-type used by scanf_dict() */ S_UINTEGER=22, /* non-negative integer; meta-type used by scanf_dict() */ S_ANY=23, /* anything; meta-type used by scanf_dict() */ S_PINTEGER=24, /* positive integer; meta-type used by scanf_dict() */ S_RGBSTR=25, /* an optional 3-byte string, representing an RGB color triplet */ S_NUMBER=26, /* real or integer */ S_PNUMBER=27 /* positive real or integer */ END_STATIC_ENUM() /** No virtual methods because of special types. MiniPS composite values * really _contain_ their components; one Value has exactly one reference: * its container component. */ class Value { public: inline ii_t getLength() const { return len; } inline ii_t getType() const { return ty; } inline bool hasPtr() const { return ptr!=NULLP; } inline bool isDumping() const { return dumping; } inline char const* getCstr() const { return (char const*)ptr; } inline char* begin_() const { return (char*)ptr; } inline char const* operator()() const { return (char const*)ptr; } protected: ii_t len; void *ptr; unsigned char ty; bool dumping; }; /** ptr contains a `void*'. Won't be freed. */ class Void: public Value { public: inline Void(void *ptr_) { ptr=ptr_; ty=T_VOID; } inline void *getPtr() const { return ptr; } }; /** Always null-terminated. */ class String: public Value { public: /** Copies from ptr_ */ String(char const*ptr_, ii_t len_); /** Replaces (this) with a copy of (a).(b) */ void replace(char const*ap, slen_t alen, char const*bp, slen_t blen); }; class Sname: public Value { public: /** ptr_ must begin with '/' */ Sname(char const*ptr_, ii_t len_); bool equals(Sname const&other); bool equals(char const*other); }; class Ename: public Value { public: Ename(char const*ptr_, ii_t len_); bool equals(Ename const&other); bool equals(char const*other); bool equals(char const*other, slen_t otherlen); }; class Real: public Value { public: typedef unsigned char metric_t; inline Real(double d_): d(d_), metric(0), dumpPS(false) { ty=T_REAL; ptr=(char*)NULLP; } /** Also supply a string representation of the value (to avoid possible * loss of precision when converting string -> double -> string). */ Real(double d_, char const*ptr_, ii_t len_); // inline bool isZero() const { return d==0.0; } inline double getBp() const { return d*me_factor[metric]; } inline void setDumpPS(bool g) { dumpPS=g; } inline void setMetric(metric_t metric_) { metric=metric_; } /** Return true iff the specified null-terminated string is a valid * dimen. */ static bool isDimen(char const *); void dump(GenBuffer::Writable &out_, bool dumpPS_force=false); /** @return ME_count on invalid */ static metric_t str2metric(char const str[2]); BEGIN_STATIC_ENUM1(metric_t) ME_bp=0, /* 1 bp = 1 bp (big point) */ ME_in=1, /* 1 in = 72 bp (inch) */ ME_pt=2, /* 1 pt = 72/72.27 bp (point) */ ME_pc=3, /* 1 pc = 12*72/72.27 bp (pica) */ ME_dd=4, /* 1 dd = 1238/1157*72/72.27 bp (didot point) [about 1.06601110141206 bp] */ ME_cc=5, /* 1 cc = 12*1238/1157*72/72.27 bp (cicero) */ ME_sp=6, /* 1 sp = 72/72.27/65536 bp (scaled point) */ ME_cm=7, /* 1 cm = 72/2.54 bp (centimeter) */ ME_mm=8, /* 1 mm = 7.2/2.54 bp (millimeter) */ ME_COUNT=9 END_STATIC_ENUM() protected: double d; /* vvv metric added at Sat Sep 7 12:26:08 CEST 2002 */ metric_t metric; /** Allow PostScript operators such as `div' to appear in the dump */ bool dumpPS; /** Factor to convert to bp */ static const double me_factor[ME_COUNT]; /** PostScript code to do multiplication by me_factor */ static char const* const me_psfactor[ME_COUNT]; }; class Array: public Value { public: Array(); void free(); void dump(GenBuffer::Writable &out_, unsigned indent); void push(VALUE v); VALUE get(ii_t index); /** Cannot extend. Calls delete0() when overwriting an element */ void set(ii_t index, VALUE val); /** val: out */ void getFirst(VALUE *&val); /** val: in_out */ void getNext(VALUE *&val); protected: ii_t alloced; void extend(ii_t newlen); }; /** Keys must be Snames here! (i.e no integer keys allowed). The current * implementation does a linear string search :-(. Dat: might not work * on extremely long keys if slen_t can hold a larger integer than * ii_t. */ class Dict: public Value { public: Dict(); void free(); void dump(GenBuffer::Writable &out_, unsigned indent, bool dump_delimiters=true); /** @return val or Qundef */ VALUE get(char const*key, slen_t keylen); /** A hack: get and touch. */ VALUE get1(char const*key, slen_t keylen); void untouch(char const*key, slen_t keylen); /** Can extend. */ void put(char const*key, VALUE val); /** Calls delete0() when overwriting an element */ void put(char const*key, slen_t keylen, VALUE val); /** @return old value for key `key', or Qundef */ VALUE push(char const*key, slen_t keylen, VALUE val); /** key: out, val: out */ void getFirst(char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched); /** key: in_out, val: in_out */ void getNext (char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched); // void getFirst(VALUE *&key, VALUE *&val); // void getNext(VALUE *&key, VALUE *&val); protected: ii_t alloced; void extend(ii_t newlen); }; static inline Value* RVALUE(VALUE v) { return static_cast((void*)v); } static inline Void* RVOID(VALUE v) { return static_cast((void*)v); } static inline Array* RARRAY(VALUE v) { return static_cast((void*)v); } static inline String* RSTRING(VALUE v){ return static_cast((void*)v); } static inline Dict* RDICT(VALUE v) { return static_cast((void*)v); } static inline Real* RREAL(VALUE v) { return static_cast((void*)v); } static inline Sname* RSNAME(VALUE v) { return static_cast((void*)v); } static inline Ename* RENAME(VALUE v) { return static_cast((void*)v); } static inline bool isDirect(VALUE v) { return (v&1)!=0 || v<=Qmax_; } /** T_NULL .. T_DICT */ static unsigned getType(VALUE v); /** "null" .. "dict", "name" (T_SNAME), "ename" (T_ENAME, non-std-PS) */ static char const* getTypeStr(unsigned u); static void delete0(VALUE v); /** The current implementation dumps dict keys in order of insertion, but * this is very likely to change soon to an _arbitrary_ order. */ static void dump(GenBuffer::Writable& out_, VALUE v, unsigned indent=0); static void dump(VALUE v, unsigned indent=0); static inline VALUE Qinteger(ii_t v) { return (v<<1)+1; } static inline ii_t int2ii(VALUE v) { return v>>1; } /** Fortunate coincidence that 2x+1>0 <=> x>0 */ static inline bool isPositive(VALUE v) { return v>0; } static inline VALUE undef2null(VALUE v) { return v==Qundef ? Qnull : v; } // static SimBuffer::B scale72(VALUE v, double d); class Parser { /** Define this to avoid including */ typedef class _anon_filet_ {} *FILEP; public: BEGIN_STATIC_ENUM1(int) EOF_ALLOWED=Tokenizer::EOFF, EOF_ILLEGAL=-2, EOF_ILLEGAL_POP=-3 END_STATIC_ENUM() /** Maximum depth of `run' file inclusions. */ BEGIN_STATIC_ENUM1(unsigned) MAX_DEPTH=17 END_STATIC_ENUM() Parser(char const *filename_); /** The caller is responsible for closing the FILE* */ Parser(FILEP f_); Parser(GenBuffer::Readable *rd_); Parser(Tokenizer *tok_); ~Parser(); /** Allocates and returns. Qundef is returned on EOF * @param closer: EOF_ILLEGAL, EOF_ALLOWED, '>' or ']' */ VALUE parse1(int closer=EOF_ILLEGAL, int sev=Error::EERROR); void setDepth(unsigned depth_); /** Sets special filename for the `run' operator. `run' will read that * special file from param `rd_', and then it will call rd_->vi_rewind(). * Example usage: .addSpecRun("%stdin", new Files::FileR(stdin)); */ void addSpecRun(char const* filename_, GenBuffer::Readable *rd_); /*MiniPS::*/Dict *getSpecRuns() const { return specRuns; } /** Does not copy the dict, but sets the pointer. */ void setSpecRuns(/*MiniPS::*/Dict *); protected: Parser(Parser *master_); // VALUE parse1_real(int closer); /* 0=nothing, 1=master 2=tok, 3=tok+rd, 4=tok+rd+f */ unsigned free_level; Parser *master; Tokenizer *tok; GenBuffer::Readable *rd; FILEP f; int unread; unsigned depth; /*MiniPS::*/Dict *specRuns; /** Should MiniPS::delete0() be called on specRuns upon destruction of * (this)? */ bool specRunsDelete; }; /** Assumes that param `job' is a dict, extracts its elements into ..., * emits errors for elements (not found and having default==Qundef), emits * warnings for elements found in `job', but undescribed in `...' (only * if show_warnings==true). Example: * * MiniPS::scanf_dict(job, true, * "InputFile", MiniPS::T_STRING, MiniPS::Qundef, &InputFile, * "OutputFile", MiniPS::T_STRING, MiniPS::Qundef, &OutputFile, * "Profiles", MiniPS::T_ARRAY, MiniPS::Qundef, &Profiles * NULLP * ); */ static void scanf_dict(VALUE job, bool show_warnings, ...); static void setDumpPS(VALUE v, bool g); /** @param v must be T_REAL or T_INTEGER */ static bool isZero(VALUE v); /** @param v must be T_REAL or T_INTEGER * @return true iff v==i */ static bool isEq(VALUE v, double d); /** Dumps the human-readable real or integer value of the sum * (mscale/72)*a+b+c-sub to `out'. * @param rounding 0: nothing. 1: round the sum _up_ to integers. 2: * round the sum _up_ to non-negative integers * @param m must be T_REAL or T_INTEGER. mscale = m/72 if m is positive, * or 72/m if m is negative. * @param a must be T_REAL or T_INTEGER * @param b must be T_REAL or T_INTEGER * @param c must be T_REAL or T_INTEGER * @param sub must be T_REAL or T_INTEGER */ static void dumpAdd3(GenBuffer::Writable &out, VALUE m, VALUE a, VALUE b, VALUE c, VALUE sub, unsigned rounding=0); static void dumpScale(GenBuffer::Writable &out, VALUE v); }; /* Fri Aug 16 17:07:14 CEST 2002 */ #if 0 /* doesn't work because MiniPS::VALUE is really an `int', so there will be an ambiguous overload */ inline GenBuffer::Writable& operator<<(GenBuffer::Writable& out_, MiniPS::VALUE v) { MiniPS::dump(out_, v); return out_; } #endif inline GenBuffer::Writable& operator<<(GenBuffer::Writable& out_, MiniPS::Value *v) { MiniPS::dump(out_, (MiniPS::VALUE)v); return out_; } // GenBuffer::Writable& operator<<(GenBuffer::Writable& out_, MiniPS::Value *v) { #endif sam2p-0.49.2/cgif.c0000644000175100017510000014441112212351433012105 0ustar ptspts/* cgif.c -- a merge of some GIF-decoding files from giflib by E.S.Raymond * by pts@fazekas.hu at Wed Feb 27 13:18:04 CET 2002 The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*The creators of the GIF format require the following acknowledgement: The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated. */ #ifdef __GNUC__ #pragma implementation #endif /**** pts: not an ANSI C function */ #undef EXTERN_C #ifdef __cplusplus #define EXTERN_C extern "C" #define CGIFFF CGIF:: #else #define EXTERN_C extern #define CGIFFF #endif #if OBJDEP # warning PROVIDES: cgif #endif #if 0 EXTERN_C FILE *fdopen (int fildes, const char *mode); /* GCC 3.0 SUXX */ #else #undef _POSIX_SOURCE #define _POSIX_SOURCE 1 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 2 #endif /* --- gifalloc.c */ /***************************************************************************** * "Gif-Lib" - Yet another gif library. * * * * Written by: Gershon Elber Ver 0.1, Jun. 1989 * * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 * ****************************************************************************** * GIF construction tools * ****************************************************************************** * History: * * 15 Sep 92 - Version 1.0 by Eric Raymond. * *****************************************************************************/ // #undef __STRICT_ANSI__ /* for MINGW32 open() !! */ #include #include "cgif.h" /**** pts ****/ #include /* malloc(), calloc(), free(), realloc() */ #include /* memset() */ //#include #if USE_CGIF_FDOPEN #include /* open() */ #include #include # if defined(__MINGW32__) || defined(__CYGWIN__) || defined(_MSC_VER) # undef __STRICT_ANSI__ # include /*#define open _open*/ # endif #endif /* --- gif_err.c */ /***************************************************************************** * "Gif-Lib" - Yet another gif library. * * * * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * ****************************************************************************** * Handle error reporting for the GIF library. * ****************************************************************************** * History: * * 17 Jun 89 - Version 1.0 by Gershon Elber. * *****************************************************************************/ /* #include already */ /* #include "gif_lib.h" already */ /* --- dgif_lib.c */ /****************************************************************************** * "Gif-Lib" - Yet another gif library. * * * * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 * ******************************************************************************* * The kernel of the GIF Decoding process can be found here. * ******************************************************************************* * History: * * 16 Jun 89 - Version 1.0 by Gershon Elber. * * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). * ******************************************************************************/ #ifdef __MSDOS__ #include #include #include #include #else #include #include #endif /* __MSDOS__ */ #include /* #include already */ /* #include already */ /* #include "gif_lib.h" already */ /* #include already */ /* malloc(), free() */ #include /* ---- */ /* --- gif_err.c */ /* #define PROGRAM_NAME "GIF_LIBRARY" */ int CGIFFF _GifError = 0; /***************************************************************************** * Return the last GIF error (0 if none) and reset the error. * *****************************************************************************/ int CGIFFF GifLastError(void) { int i = _GifError; _GifError = 0; return i; } /**** pts ****/ /** May return NULL. */ PTS_const char *CGIFFF GetGifError(void) { PTS_const char *Err; switch(_GifError) { #if 0 /**** pts ****/ case E_GIF_ERR_OPEN_FAILED: Err = "Failed to open given file"; break; case E_GIF_ERR_WRITE_FAILED: Err = "Failed to Write to given file"; break; case E_GIF_ERR_HAS_SCRN_DSCR: Err = "Screen Descriptor already been set"; break; case E_GIF_ERR_HAS_IMAG_DSCR: Err = "Image Descriptor is still active"; break; case E_GIF_ERR_NO_COLOR_MAP: Err = "Neither Global Nor Local color map"; break; case E_GIF_ERR_DATA_TOO_BIG: Err = "#Pixels bigger than Width * Height"; break; case E_GIF_ERR_NOT_ENOUGH_MEM: Err = "Fail to allocate required memory"; break; case E_GIF_ERR_DISK_IS_FULL: Err = "Write failed (disk full?)"; break; case E_GIF_ERR_CLOSE_FAILED: Err = "Failed to close given file"; break; case E_GIF_ERR_NOT_WRITEABLE: Err = "Given file was not opened for write"; break; #endif case D_GIF_ERR_OPEN_FAILED: Err = "Failed to open given file"; break; case D_GIF_ERR_READ_FAILED: Err = "Failed to Read from given file"; break; case D_GIF_ERR_NOT_GIF_FILE: Err = "Given file is NOT GIF file"; break; case D_GIF_ERR_NO_SCRN_DSCR: Err = "No Screen Descriptor detected"; break; case D_GIF_ERR_NO_IMAG_DSCR: Err = "No Image Descriptor detected"; break; case D_GIF_ERR_NO_COLOR_MAP: Err = "Neither Global Nor Local color map"; break; case D_GIF_ERR_WRONG_RECORD: Err = "Wrong record type detected"; break; case D_GIF_ERR_DATA_TOO_BIG: Err = "#Pixels bigger than Width * Height"; break; case D_GIF_ERR_NOT_ENOUGH_MEM: Err = "Fail to allocate required memory"; break; case D_GIF_ERR_CLOSE_FAILED: Err = "Failed to close given file"; break; case D_GIF_ERR_NOT_READABLE: Err = "Given file was not opened for read"; break; case D_GIF_ERR_IMAGE_DEFECT: Err = "Image is defective, decoding aborted"; break; case D_GIF_ERR_EOF_TOO_SOON: Err = "Image EOF detected, before image complete"; break; default: Err = NULL; break; } return Err; } /***************************************************************************** * Print the last GIF error to stderr. * *****************************************************************************/ void CGIFFF PrintGifError(void) { PTS_const char *Err=GetGifError(); if (Err != NULL) fprintf(stderr, "\nGIF-LIB error: %s.\n", Err); else fprintf(stderr, "\nGIF-LIB undefined error %d.\n", _GifError); } /* --- gifalloc.c */ #define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** * Miscellaneous utility functions * ******************************************************************************/ static int BitSize(int n) /* return smallest bitfield size n will fit in */ { register int i; for (i = 1; i <= 8; i++) if ((1 << i) >= n) break; return(i); } /****************************************************************************** * Color map object functions * ******************************************************************************/ CGIFFF ColorMapObject *CGIFFF MakeMapObject(int ColorCount, GifColorType *ColorMap) /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ { ColorMapObject *Object; if (ColorCount != (1 << BitSize(ColorCount))) return((ColorMapObject *)NULL); Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); if (Object == (ColorMapObject *)NULL) return((ColorMapObject *)NULL); Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType)); if (Object->Colors == (GifColorType *)NULL) return((ColorMapObject *)NULL); Object->ColorCount = ColorCount; Object->BitsPerPixel = BitSize(ColorCount); if (ColorMap) memcpy((char *)Object->Colors, (char *)ColorMap, ColorCount * sizeof(GifColorType)); return(Object); } void CGIFFF FreeMapObject(CGIFFF ColorMapObject *Object) /* * Free a color map object */ { free(Object->Colors); free(Object); } #if 0 void DumpColorMap(ColorMapObject *Object, FILE *fp) { if (Object) { int i, j, Len = Object->ColorCount; for (i = 0; i < Len; i+=4) { for (j = 0; j < 4 && j < Len; j++) { fprintf(fp, "%3d: %02x %02x %02x ", i + j, Object->Colors[i + j].Red, Object->Colors[i + j].Green, Object->Colors[i + j].Blue); } fprintf(fp, "\n"); } } } #endif /* DEBUG */ #if 0 ColorMapObject *CGIFFF UnionColorMap( ColorMapObject *ColorIn1, ColorMapObject *ColorIn2, GifPixelType ColorTransIn2[]) /* * Compute the union of two given color maps and return it. If result can't * fit into 256 colors, NULL is returned, the allocated union otherwise. * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are * copied iff they didn't exist before. ColorTransIn2 maps the old * ColorIn2 into ColorUnion color map table. */ { int i, j, CrntSlot, RoundUpTo, NewBitSize; ColorMapObject *ColorUnion; /* * Allocate table which will hold the result for sure. */ ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount,ColorIn2->ColorCount)*2,NULL); if (ColorUnion == NULL) return(NULL); /* Copy ColorIn1 to ColorUnionSize; */ for (i = 0; i < ColorIn1->ColorCount; i++) ColorUnion->Colors[i] = ColorIn1->Colors[i]; CrntSlot = ColorIn1->ColorCount; /* * Potentially obnoxious hack: * * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end * of table 1. This is very useful if your display is limited to * 16 colors. */ while (ColorIn1->Colors[CrntSlot-1].Red == 0 && ColorIn1->Colors[CrntSlot-1].Green == 0 && ColorIn1->Colors[CrntSlot-1].Red == 0) CrntSlot--; /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */ for (i = 0; i < ColorIn2->ColorCount && CrntSlot<=256; i++) { /* Let's see if this color already exists: */ for (j = 0; j < ColorIn1->ColorCount; j++) if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0) break; if (j < ColorIn1->ColorCount) ColorTransIn2[i] = j; /* color exists in Color1 */ else { /* Color is new - copy it to a new slot: */ ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i]; ColorTransIn2[i] = CrntSlot++; } } if (CrntSlot > 256) { FreeMapObject(ColorUnion); return((ColorMapObject *)NULL); } NewBitSize = BitSize(CrntSlot); RoundUpTo = (1 << NewBitSize); if (RoundUpTo != ColorUnion->ColorCount) { register GifColorType *Map = ColorUnion->Colors; /* * Zero out slots up to next power of 2. * We know these slots exist because of the way ColorUnion's * start dimension was computed. */ for (j = CrntSlot; j < RoundUpTo; j++) Map[j].Red = Map[j].Green = Map[j].Blue = 0; /* perhaps we can shrink the map? */ if (RoundUpTo < ColorUnion->ColorCount) ColorUnion->Colors = (GifColorType *)realloc(Map, sizeof(GifColorType)*RoundUpTo); } ColorUnion->ColorCount = RoundUpTo; ColorUnion->BitsPerPixel = NewBitSize; return(ColorUnion); } void ApplyTranslation(SavedImage *Image, GifPixelType Translation[]) /* * Apply a given color translation to the raster bits of an image */ { register int i; register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; for (i = 0; i < RasterSize; i++) Image->RasterBits[i] = Translation[Image->RasterBits[i]]; } #endif /****************************************************************************** * Extension record functions * ******************************************************************************/ #if 0 /**** pts ****/ void MakeExtension(SavedImage *New, int Function) { New->Function = Function; /* * Someday we might have to deal with multiple extensions. */ } #endif int CGIFFF AddExtensionBlock(CGIFFF SavedImage *New, int Len, CGIFFF GifByteType ExtData[]) { ExtensionBlock *ep; if (New->ExtensionBlocks == NULL) New->ExtensionBlocks = (ExtensionBlock *)malloc(sizeof(ExtensionBlock)); else New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks, sizeof(ExtensionBlock) * (New->ExtensionBlockCount + 1)); if (New->ExtensionBlocks == NULL) return(GIF_ERROR); ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; if ((ep->Bytes = (GifByteType *)malloc(ep->ByteCount = Len)) == NULL) return(GIF_ERROR); if (ExtData) memcpy(ep->Bytes, ExtData, Len); return(GIF_OK); } void CGIFFF FreeExtension(CGIFFF SavedImage *Image) { ExtensionBlock *ep; for (ep = Image->ExtensionBlocks; ep < Image->ExtensionBlocks + Image->ExtensionBlockCount; ep++) (void) free((char *)ep->Bytes); free((char *)Image->ExtensionBlocks); Image->ExtensionBlocks = NULL; } /****************************************************************************** * Image block allocation functions * ******************************************************************************/ CGIFFF SavedImage *CGIFFF MakeSavedImage(CGIFFF GifFileType *GifFile, CGIFFF SavedImage *CopyFrom) /* * Append an image block to the SavedImages array */ { SavedImage *sp; if (GifFile->SavedImages == NULL) GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); else GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount+1)); if (GifFile->SavedImages == NULL) return((SavedImage *)NULL); else { sp = &GifFile->SavedImages[GifFile->ImageCount++]; memset((char *)sp, '\0', sizeof(SavedImage)); if (CopyFrom) { memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); /* * Make our own allocated copies of the heap fields in the * copied record. This guards against potential aliasing * problems. */ /* first, the local color map */ if (sp->ImageDesc.ColorMap) sp->ImageDesc.ColorMap = MakeMapObject(CopyFrom->ImageDesc.ColorMap->ColorCount, CopyFrom->ImageDesc.ColorMap->Colors); /* next, the raster */ sp->RasterBits = (GifPixelType *)malloc(sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width); memcpy(sp->RasterBits, CopyFrom->RasterBits, sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width); /* finally, the extension blocks */ if (sp->ExtensionBlocks) { sp->ExtensionBlocks = (ExtensionBlock*)malloc(sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); /* * For the moment, the actual blocks can take their * chances with free(). We'll fix this later. */ } } return(sp); } } void CGIFFF FreeSavedImages(CGIFFF GifFileType *GifFile) { SavedImage *sp; for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { if (sp->ImageDesc.ColorMap) FreeMapObject(sp->ImageDesc.ColorMap); if (sp->RasterBits) free((char *)sp->RasterBits); if (sp->ExtensionBlocks) FreeExtension(sp); } free((char *) GifFile->SavedImages); } /* --- dgif_lib.c */ #define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */ /* #define PROGRAM_NAME "GIFLIB" */ #define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for comment. */ #define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ #define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 #define GIF_VERSION_POS 3 /* Version first character in stamp. */ #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ #define LZ_BITS 12 #define FILE_STATE_READ 0x01/* 1 write, 0 read - EGIF_LIB compatible.*/ #define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */ #define FIRST_CODE 4097 /* Impossible code, to signal first. */ #define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */ #define IS_READABLE(Private) (!(Private->FileState & FILE_STATE_READ)) typedef struct GifFilePrivateType { int FileState, /*FileHandle,*/ /* Where all this data goes to! */ BitsPerPixel, /* Bits per pixel (Codes uses at list this + 1). */ ClearCode, /* The CLEAR LZ code. */ EOFCode, /* The EOF LZ code. */ RunningCode, /* The next code algorithm can generate. */ RunningBits,/* The number of bits required to represent RunningCode. */ MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */ LastCode, /* The code before the current code. */ CrntCode, /* Current algorithm code. */ StackPtr, /* For character stack (see below). */ CrntShiftState; /* Number of bits in CrntShiftDWord. */ unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */ unsigned long PixelCount; /* Number of pixels in image. */ FILE *File; /* File as stream. */ CGIFFF GifByteType Buf[256]; /* Compressed input is buffered here. */ CGIFFF GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */ CGIFFF GifByteType Suffix[LZ_MAX_CODE+1]; /* So we can trace the codes. */ unsigned int Prefix[LZ_MAX_CODE+1]; } GifFilePrivateType; /* extern int _GifError; */ static int DGifGetWord(FILE *File, int *Word); static int DGifSetupDecompress(CGIFFF GifFileType *GifFile); static int DGifDecompressLine(CGIFFF GifFileType *GifFile, CGIFFF GifPixelType *Line, int LineLen); static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode); static int DGifDecompressInput(GifFilePrivateType *Private, int *Code); static int DGifBufferedInput(FILE *File, CGIFFF GifByteType *Buf, CGIFFF GifByteType *NextByte); /****************************************************************************** * Open a new gif file for read, given by its name. * * Returns GifFileType pointer dynamically allocated which serves as the gif * * info record. _GifError is cleared if succesfull. * ******************************************************************************/ CGIFFF GifFileType *CGIFFF DGifOpenFileName(const char *FileName) { #if 0 /**** pts ****/ CGIFFF GifFileType *CGIFFF DGifOpenFileName(const char *FileName) { int FileHandle; if ((FileHandle = open(FileName, O_RDONLY #ifdef __MSDOS__ | O_BINARY #endif /* __MSDOS__ */ )) == -1) { _GifError = D_GIF_ERR_OPEN_FAILED; return NULL; } return DGifOpenFileHandle(FileHandle); #else FILE *f; if (NULL==(f=fopen(FileName,"rb"))) { _GifError=D_GIF_ERR_OPEN_FAILED; return NULL; } return DGifOpenFILE(f); #endif } #if USE_CGIF_FDOPEN /****************************************************************************** * Update a new gif file, given its file handle. * * Returns GifFileType pointer dynamically allocated which serves as the gif * * info record. _GifError is cleared if succesfull. * ******************************************************************************/ CGIFFF GifFileType *CGIFFF DGifOpenFileHandle(int FileHandle) { FILE *f; #ifdef __MSDOS__ setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);/* And inc. stream buffer.*/ #else f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ #endif /* __MSDOS__ */ return DGifOpenFILE(f); } #endif /**** pts ****/ CGIFFF GifFileType *CGIFFF DGifOpenFILE(void/*FILE*/ *f) { char Buf[GIF_STAMP_LEN+1]; GifFileType *GifFile; GifFilePrivateType *Private; if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); if ((Private = (GifFilePrivateType *) malloc(sizeof(GifFilePrivateType))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; free((char *) GifFile); return NULL; } GifFile->Private = (VoidPtr) Private; /* Private->FileHandle = FileHandle; */ Private->File = (FILE*)f; Private->FileState = 0; /* Make sure bit 0 = 0 (File open for read). */ /* Let's see if this is a GIF file: */ if (fread(Buf, 1, GIF_STAMP_LEN, Private->File) != GIF_STAMP_LEN) { _GifError = D_GIF_ERR_READ_FAILED; free((char *) Private); free((char *) GifFile); return NULL; } /* The GIF Version number is ignored at this time. Maybe we should do */ /* something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; free((char *) Private); free((char *) GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *) Private); free((char *) GifFile); return NULL; } _GifError = 0; return GifFile; } /****************************************************************************** * This routine should be called before any other DGif calls. Note that * * this routine is called automatically from DGif file open routines. * ******************************************************************************/ int CGIFFF DGifGetScreenDesc(CGIFFF GifFileType *GifFile) { int i, BitsPerPixel; GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } /* Put the screen descriptor into the file: */ if (DGifGetWord(Private->File, &GifFile->SWidth) == GIF_ERROR || DGifGetWord(Private->File, &GifFile->SHeight) == GIF_ERROR) return GIF_ERROR; if (fread(Buf, 1, 3, Private->File) != 3) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; BitsPerPixel = (Buf[0] & 0x07) + 1; GifFile->SBackGroundColor = Buf[1]; // fprintf(stderr, "colres=%d bpp=%d bgcol=%d\n", GifFile->SColorResolution, BitsPerPixel, GifFile->SBackGroundColor); if (Buf[0] & 0x80) { /* Do we have global color map? */ // fprintf(stderr, "have gcolormap\n"); GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); /* Get the global color map: */ for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { if (fread(Buf, 1, 3, Private->File) != 3) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } GifFile->SColorMap->Colors[i].Red = Buf[0]; GifFile->SColorMap->Colors[i].Green = Buf[1]; GifFile->SColorMap->Colors[i].Blue = Buf[2]; } } return GIF_OK; } /****************************************************************************** * This routine should be called before any attemp to read an image. * ******************************************************************************/ int CGIFFF DGifGetRecordType(CGIFFF GifFileType *GifFile, CGIFFF GifRecordType *Type) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (fread(&Buf, 1, 1, Private->File) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } // fprintf(stderr, "record %d at offset %ld\n", Buf&255, ftell(Private->File)); switch (Buf) { case ',': *Type = IMAGE_DESC_RECORD_TYPE; break; case '!': *Type = EXTENSION_RECORD_TYPE; break; case ';': *Type = TERMINATE_RECORD_TYPE; break; default: *Type = UNDEFINED_RECORD_TYPE; // fprintf(stderr, "wrong record %d at offset %ld\n", Buf&255, ftell(Private->File)); _GifError = D_GIF_ERR_WRONG_RECORD; return GIF_ERROR; } return GIF_OK; } /****************************************************************************** * This routine should be called before any attemp to read an image. * * Note it is assumed the Image desc. header (',') has been read. * ******************************************************************************/ int CGIFFF DGifGetImageDesc(CGIFFF GifFileType *GifFile) { int i, BitsPerPixel; GifByteType Buf[3]; GifImageDesc Image; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; memset(&Image, 0, sizeof(Image)); if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (DGifGetWord(Private->File, &Image.Left) == GIF_ERROR || DGifGetWord(Private->File, &Image.Top) == GIF_ERROR || DGifGetWord(Private->File, &Image.Width) == GIF_ERROR || DGifGetWord(Private->File, &Image.Height) == GIF_ERROR) return GIF_ERROR; if (fread(Buf, 1, 1, Private->File) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } BitsPerPixel = (Buf[0] & 0x07) + 1; Image.Interlace = (Buf[0] & 0x40); if (Buf[0] & 0x80) { /* Does this image have local color map? */ if (Image.ColorMap && GifFile->SavedImages == NULL) FreeMapObject(Image.ColorMap); Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); /* Get the image local color map: */ for (i = 0; i < Image.ColorMap->ColorCount; i++) { if (fread(Buf, 1, 3, Private->File) != 3) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } Image.ColorMap->Colors[i].Red = Buf[0]; Image.ColorMap->Colors[i].Green = Buf[1]; Image.ColorMap->Colors[i].Blue = Buf[2]; } } /**** pts ****/ if (NULL!=GifFile->SavedImages) { GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1)); } else { assert(GifFile->ImageCount==0); GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); } if (NULL==GifFile->SavedImages) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } { SavedImage *sp; sp = &GifFile->SavedImages[GifFile->ImageCount]; memcpy(&sp->ImageDesc, &Image, sizeof(GifImageDesc)); sp->RasterBits = (GifPixelType *)NULL; sp->ExtensionBlockCount = 0; sp->ExtensionBlocks = (ExtensionBlock *)NULL; sp->delay=0; sp->dispose=0; sp->iter=1; sp->transp=(-1); } GifFile->ImageCount++; Private->PixelCount = (long) Image.Width * (long) Image.Height; DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ return GIF_OK; } /****************************************************************************** * Get one full scanned line (Line) of length LineLen from GIF file. * ******************************************************************************/ int CGIFFF DGifGetLine(CGIFFF GifFileType *GifFile, CGIFFF GifPixelType *Line, int LineLen) { GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } /**** pts ****/ /* if (!LineLen) LineLen = GifFile->Image.Width; */ #if defined(__MSDOS__) || defined(__GNUC__) if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { #else if ((Private->PixelCount -= LineLen) > 0xffff0000) { #endif /* __MSDOS__ */ _GifError = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { if (Private->PixelCount == 0) { /* We probably would not be called any more, so lets clean */ /* everything before we return: need to flush out all rest of */ /* image until empty block (size 0) detected. We use GetCodeNext.*/ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; while (Dummy != NULL); } return GIF_OK; } else return GIF_ERROR; } /****************************************************************************** * Put one pixel (Pixel) into GIF file. * ******************************************************************************/ int CGIFFF DGifGetPixel(CGIFFF GifFileType *GifFile, CGIFFF GifPixelType Pixel) { GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } #if defined(__MSDOS__) || defined(__GNUC__) if (--Private->PixelCount > 0xffff0000UL) #else if (--Private->PixelCount > 0xffff0000) #endif /* __MSDOS__ */ { _GifError = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { if (Private->PixelCount == 0) { /* We probably would not be called any more, so lets clean */ /* everything before we return: need to flush out all rest of */ /* image until empty block (size 0) detected. We use GetCodeNext.*/ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; while (Dummy != NULL); } return GIF_OK; } else return GIF_ERROR; } /****************************************************************************** * Get an extension block (see GIF manual) from gif file. This routine only * * returns the first data block, and DGifGetExtensionNext shouldbe called * * after this one until NULL extension is returned. * * The Extension should NOT be freed by the user (not dynamically allocated).* * Note it is assumed the Extension desc. header ('!') has been read. * ******************************************************************************/ int CGIFFF DGifGetExtension(CGIFFF GifFileType *GifFile, int *ExtCode, CGIFFF GifByteType **Extension) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (fread(&Buf, 1, 1, Private->File) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *ExtCode = Buf; return DGifGetExtensionNext(GifFile, Extension); } /****************************************************************************** * Get a following extension block (see GIF manual) from gif file. This * * routine sould be called until NULL Extension is returned. * * The Extension should NOT be freed by the user (not dynamically allocated).* ******************************************************************************/ int CGIFFF DGifGetExtensionNext(CGIFFF GifFileType *GifFile, CGIFFF GifByteType **Extension) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (fread(&Buf, 1, 1, Private->File) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (Buf > 0) { *Extension = Private->Buf; /* Use private unused buffer. */ (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ if (fread(&((*Extension)[1]), 1, Buf, Private->File) != Buf) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else *Extension = NULL; return GIF_OK; } /****************************************************************************** * This routine should be called last, to close the GIF file. * ******************************************************************************/ int CGIFFF DGifCloseFile(CGIFFF GifFileType *GifFile) { GifFilePrivateType *Private; if (GifFile == NULL) return GIF_ERROR; Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } #if 0 /**** pts ****/ if (GifFile->Image.ColorMap) FreeMapObject(GifFile->Image.ColorMap); #endif if (GifFile->SColorMap) FreeMapObject(GifFile->SColorMap); if (Private) free((char *) Private); if (GifFile->SavedImages) FreeSavedImages(GifFile); free(GifFile); #if 0 /**** pts ****/ if (fclose(File) != 0) { _GifError = D_GIF_ERR_CLOSE_FAILED; return GIF_ERROR; } #endif return GIF_OK; } /****************************************************************************** * Get 2 bytes (word) from the given file: * ******************************************************************************/ static int DGifGetWord(FILE *File, int *Word) { unsigned char c[2]; if (fread(c, 1, 2, File) != 2) { CGIFFF _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *Word = (((unsigned int) c[1]) << 8) + c[0]; return GIF_OK; } /****************************************************************************** * Get the image code in compressed form. his routine can be called if the * * information needed to be piped out as is. Obviously this is much faster * * than decoding and encoding again. This routine should be followed by calls * * to DGifGetCodeNext, until NULL block is returned. * * The block should NOT be freed by the user (not dynamically allocated). * ******************************************************************************/ int CGIFFF DGifGetCode(CGIFFF GifFileType *GifFile, int *CodeSize, CGIFFF GifByteType **CodeBlock) { GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } *CodeSize = Private->BitsPerPixel; return DGifGetCodeNext(GifFile, CodeBlock); } /****************************************************************************** * Continue to get the image code in compressed form. This routine should be * * called until NULL block is returned. * * The block should NOT be freed by the user (not dynamically allocated). * ******************************************************************************/ int CGIFFF DGifGetCodeNext(CGIFFF GifFileType *GifFile, CGIFFF GifByteType **CodeBlock) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (fread(&Buf, 1, 1, Private->File) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (Buf > 0) { *CodeBlock = Private->Buf; /* Use private unused buffer. */ (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ if (fread(&((*CodeBlock)[1]), 1, Buf, Private->File) != Buf) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else { *CodeBlock = NULL; Private->Buf[0] = 0; /* Make sure the buffer is empty! */ Private->PixelCount = 0; /* And local info. indicate image read. */ } return GIF_OK; } /****************************************************************************** * Setup the LZ decompression for this image: * ******************************************************************************/ static int DGifSetupDecompress(CGIFFF GifFileType *GifFile) { int i, BitsPerPixel; CGIFFF GifByteType CodeSize; unsigned int *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (fread(&CodeSize, 1, 1, Private->File) != 1) /* Read Code size from file. */ return GIF_ERROR; BitsPerPixel = CodeSize; Private->Buf[0] = 0; /* Input Buffer empty. */ Private->BitsPerPixel = BitsPerPixel; Private->ClearCode = (1 << BitsPerPixel); Private->EOFCode = Private->ClearCode + 1; Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ Private->StackPtr = 0; /* No pixels on the pixel stack. */ Private->LastCode = NO_SUCH_CODE; Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ Private->CrntShiftDWord = 0; Prefix = Private->Prefix; for (i = 0; i <= LZ_MAX_CODE; i++) Prefix[i] = NO_SUCH_CODE; return GIF_OK; } /****************************************************************************** * The LZ decompression routine: * * This version decompress the given gif file into Line of length LineLen. * * This routine can be called few times (one per scan line, for example), in * * order the complete the whole image. * ******************************************************************************/ static int DGifDecompressLine(CGIFFF GifFileType *GifFile, CGIFFF GifPixelType *Line, int LineLen) { int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; CGIFFF GifByteType *Stack, *Suffix; unsigned int *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; StackPtr = Private->StackPtr; Prefix = Private->Prefix; Suffix = Private->Suffix; Stack = Private->Stack; EOFCode = Private->EOFCode; ClearCode = Private->ClearCode; LastCode = Private->LastCode; if (StackPtr != 0) { /* Let pop the stack off before continueing to read the gif file: */ while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr]; } while (i < LineLen) { /* Decode LineLen items. */ if (DGifDecompressInput(Private, &CrntCode) == GIF_ERROR) return GIF_ERROR; /*fprintf(stderr,"CrntCode=0x%x\n",CrntCode);*/ if (CrntCode == EOFCode) { /* Note however that usually we will not be here as we will stop */ /* decoding as soon as we got all the pixel, or EOF code will */ /* not be read at all, and DGifGetLine/Pixel clean everything. */ if (i != LineLen - 1 || Private->PixelCount != 0) { CGIFFF _GifError = D_GIF_ERR_EOF_TOO_SOON; return GIF_ERROR; } i++; } else if (CrntCode == ClearCode) { /* We need to start over again: */ for (j = 0; j <= LZ_MAX_CODE; j++) Prefix[j] = NO_SUCH_CODE; Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = Private->BitsPerPixel + 1; Private->MaxCode1 = 1 << Private->RunningBits; LastCode = Private->LastCode = NO_SUCH_CODE; } else { /* Its regular code - if in pixel range simply add it to output */ /* stream, otherwise trace to codes linked list until the prefix */ /* is in pixel range: */ if (CrntCode < ClearCode) { /* This is simple - its pixel scalar, so add it to output: */ Line[i++] = CrntCode; } else { /* Its a code to needed to be traced: trace the linked list */ /* until the prefix is a pixel, while pushing the suffix */ /* pixels on our stack. If we done, pop the stack in reverse */ /* (thats what stack is good for!) order to output. */ if (Prefix[CrntCode] == NO_SUCH_CODE) { /* Only allowed if CrntCode is exactly the running code: */ /* In that case CrntCode = XXXCode, CrntCode or the */ /* prefix code is last code and the suffix char is */ /* exactly the prefix of last code! */ if (CrntCode == Private->RunningCode - 2) { CrntPrefix = LastCode; Suffix[Private->RunningCode - 2] = Stack[StackPtr++] = DGifGetPrefixChar(Prefix, LastCode, ClearCode); } else { CGIFFF _GifError = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } } else CrntPrefix = CrntCode; /* Now (if image is O.K.) we should not get an NO_SUCH_CODE */ /* During the trace. As we might loop forever, in case of */ /* defective image, we count the number of loops we trace */ /* and stop if we got LZ_MAX_CODE. obviously we can not */ /* loop more than that. */ j = 0; while (j++ <= LZ_MAX_CODE && CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { Stack[StackPtr++] = Suffix[CrntPrefix]; CrntPrefix = Prefix[CrntPrefix]; } if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { CGIFFF _GifError = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } /* Push the last character on stack: */ Stack[StackPtr++] = CrntPrefix; /* Now lets pop all the stack into output: */ while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr]; } if (LastCode != NO_SUCH_CODE) { Prefix[Private->RunningCode - 2] = LastCode; if (CrntCode == Private->RunningCode - 2) { /* Only allowed if CrntCode is exactly the running code: */ /* In that case CrntCode = XXXCode, CrntCode or the */ /* prefix code is last code and the suffix char is */ /* exactly the prefix of last code! */ Suffix[Private->RunningCode - 2] = DGifGetPrefixChar(Prefix, LastCode, ClearCode); } else { Suffix[Private->RunningCode - 2] = DGifGetPrefixChar(Prefix, CrntCode, ClearCode); } } LastCode = CrntCode; } } Private->LastCode = LastCode; Private->StackPtr = StackPtr; return GIF_OK; } /****************************************************************************** * Routine to trace the Prefixes linked list until we get a prefix which is * * not code, but a pixel value (less than ClearCode). Returns that pixel value.* * If image is defective, we might loop here forever, so we limit the loops to * * the maximum possible if image O.k. - LZ_MAX_CODE times. * ******************************************************************************/ static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode) { int i = 0; while (Code > ClearCode && i++ <= LZ_MAX_CODE) Code = Prefix[Code]; return Code; } /****************************************************************************** * Interface for accessing the LZ codes directly. Set Code to the real code * * (12bits), or to -1 if EOF code is returned. * ******************************************************************************/ int CGIFFF DGifGetLZCodes(CGIFFF GifFileType *GifFile, int *Code) { GifByteType *CodeBlock; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (DGifDecompressInput(Private, Code) == GIF_ERROR) return GIF_ERROR; if (*Code == Private->EOFCode) { /* Skip rest of codes (hopefully only NULL terminating block): */ do if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) return GIF_ERROR; while (CodeBlock != NULL); *Code = -1; } else if (*Code == Private->ClearCode) { /* We need to start over again: */ Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = Private->BitsPerPixel + 1; Private->MaxCode1 = 1 << Private->RunningBits; } return GIF_OK; } /****************************************************************************** * The LZ decompression input routine: * * This routine is responsable for the decompression of the bit stream from * * 8 bits (bytes) packets, into the real codes. * * Returns GIF_OK if read succesfully. * ******************************************************************************/ static int DGifDecompressInput(GifFilePrivateType *Private, int *Code) { CGIFFF GifByteType NextByte; static unsigned int CodeMasks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff }; while (Private->CrntShiftState < Private->RunningBits) { /* Needs to get more bytes from input stream for next code: */ if (DGifBufferedInput(Private->File, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= ((unsigned long) NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; /* If code cannt fit into RunningBits bits, must raise its size. Note */ /* however that codes above 4095 are used for special signaling. */ if (++Private->RunningCode > Private->MaxCode1 && Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; } /****************************************************************************** * This routines read one gif data block at a time and buffers it internally * * so that the decompression routine could access it. * * The routine returns the next byte from its internal buffer (or read next * * block in if buffer empty) and returns GIF_OK if succesful. * ******************************************************************************/ static int DGifBufferedInput(FILE *File, CGIFFF GifByteType *Buf, CGIFFF GifByteType *NextByte) { if (Buf[0] == 0) { /* Needs to read the next buffer - this one is empty: */ if (fread(Buf, 1, 1, File) != 1) { CGIFFF _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (fread(&Buf[1], 1, Buf[0], File) != Buf[0]) { CGIFFF _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *NextByte = Buf[1]; Buf[1] = 2; /* We use now the second place as last char read! */ Buf[0]--; } else { *NextByte = Buf[Buf[1]++]; Buf[0]--; } return GIF_OK; } /****************************************************************************** * This routine reads an entire GIF into core, hanging all its state info off * * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() * * first to initialize I/O. Its inverse is EGifSpew(). * ******************************************************************************/ int CGIFFF DGifSlurp(CGIFFF GifFileType *GifFile) { static unsigned InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ /**** pts: unused vars ****/ /* int i, j, Error, ImageSize; */ int ext_code; GifRecordType RecordType; /**** pts ****/ SavedImage *sp=0; /**** pts: avoid gcc warning */ /** Extension info of next SavedImage */ SavedImage ext; /** No-extension info */ SavedImage noext; GifByteType *ExtData; /**** pts ****/ memset(&noext, 0, sizeof(noext)); noext.delay=0; noext.dispose=0; noext.iter=1; noext.transp=(-1); noext.ExtensionBlocks=NULL; noext.ExtensionBlockCount=0; ext=noext; /**** pts ****/ GifFile->SavedImages=0; do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) return(GIF_ERROR); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) return(GIF_ERROR); /**** pts: DGifGetImageDesc has already allocated the mem ****/ sp = &GifFile->SavedImages[GifFile->ImageCount-1]; /**** pts: apply extensions to the image just read */ ext.RasterBits=sp->RasterBits; ext.ImageDesc=sp->ImageDesc; *sp=ext; ext=noext; /**** pts ****/ sp->RasterBits = (GifPixelType*) malloc((0L+sp->ImageDesc.Width) * sp->ImageDesc.Height * sizeof(GifPixelType)); if (sp->RasterBits==NULL) { _GifError=D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } if (sp->ImageDesc.Interlace) { unsigned i, j, Height=sp->ImageDesc.Height, Width=sp->ImageDesc.Width; /* Need to perform 4 passes on the images: */ for (i = 0; i < 4; i++) for (j = InterlacedOffset[i]; j < Height; j += InterlacedJumps[i]) if (DGifGetLine(GifFile, sp->RasterBits+Width*j, Width) != GIF_OK) return GIF_ERROR; } else { if (DGifGetLine(GifFile, sp->RasterBits, (0L+sp->ImageDesc.Width) * sp->ImageDesc.Height) == GIF_ERROR) return(GIF_ERROR); } break; case EXTENSION_RECORD_TYPE: if (DGifGetExtension(GifFile,&ext_code,&ExtData)==GIF_ERROR) return(GIF_ERROR); if (ExtData!=NULL) { #if 0 /**** pts ****/ ep = &ext.ExtensionBlocks[ext.ExtensionBlockCount++]; ep->ByteCount = ExtData[0]; ep->Bytes = (GifByteType *)malloc(ep->ByteCount * sizeof(GifByteType)); memcpy(ep->Bytes, ExtData, ep->ByteCount * sizeof(char)); #else /**** pts ****/ if (0xf9==(unsigned char)(ext_code)) { assert(ExtData[0]>=4); ext.dispose=ExtData[1]>>2; ext.delay=(ExtData[3] << 8) | ExtData[2]; if ((ExtData[1] & 0x01) == 1) ext.transp=ExtData[4]; } else if (0xff==(unsigned char)(ext_code)) { assert(ExtData[0]>=3); ext.iter=(ExtData[3] << 8) | ExtData[2]; } else { AddExtensionBlock(&ext, ExtData[0], ExtData+1); ext.ExtensionBlocks[ext.ExtensionBlockCount-1].code=ext_code; } #endif while (1) { if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) return(GIF_ERROR); #if 0 /**** pts ****/ ep = &ext.ExtensionBlocks[ext.ExtensionBlockCount++]; ep->ByteCount = ExtData[0]; ep->Bytes = (GifByteType *)malloc(ep->ByteCount * sizeof(GifByteType)); memcpy(ep->Bytes,ExtData,ep->ByteCount * sizeof(char)); #else if (ExtData==NULL) break; AddExtensionBlock(sp, ExtData[0], ExtData+1); #endif } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); return(GIF_OK); } /* __END__ */ sam2p-0.49.2/encoder.cpp0000644000175100017510000016607612211371426013172 0ustar ptspts/* encoder.cpp -- various PostScript and PDF encoding filter implementations * by pts@fazekas.hu at Sun Mar 3 14:16:00 CET 2002 * --- Mon Mar 4 00:00:20 CET 2002 */ /* Imp: make built-in FlateEncode DYNALLOC */ /* Imp: add lzw_codec */ /* Imp: add gzip */ /* Imp: add zlib */ #ifdef __GNUC__ #pragma implementation #endif #include "encoder.hpp" #include "error.hpp" #include "gensio.hpp" #include /* getenv() */ #include /* --- */ /** Does output EOD (end-of-data) marker `>' */ class ASCIIHexEncode: public PSEncoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ ASCIIHexEncode(GenBuffer::Writable &out_, unsigned maxcpl_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned maxcpl; /** Number of hex digits already printed. */ unsigned curcpl; GenBuffer::Writable &out; }; /** Does output EOD (end-of-data) marker `~>' */ class ASCII85Encode: public PSEncoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ ASCII85Encode(GenBuffer::Writable &out_, unsigned maxcpl_); virtual void vi_write(char const*buf, slen_t len); protected: void wout(unsigned PTS_INT32_T buf_); unsigned maxcpl; /** Number of digits available in this line */ GenBuffer::Writable &out; unsigned ascii85breaklen; unsigned ascii85left; unsigned PTS_INT32_T ascii85buf; char *obuf, *obufend, *op; }; /** Doesn't output EOD (end-of-data) marker `>' */ class RunLengthEncode: public PSEncoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ RunLengthEncode(GenBuffer::Writable &out_, slen_t RecordSize_); virtual void vi_write(char const*buf, slen_t len); protected: slen_t recordsize; GenBuffer::Writable &out; // char *obuf, *obufend, *op; slen_t record_left; unsigned saved_c, saved_rep; /** size == header+buffer+EOD */ char saved[130]; }; static int gen_write(char *block, unsigned len, void *zfile); #if USE_BUILTIN_ZIP #include "pts_defl.h" /* Imp: because pts_defl_interface :-( */ #if OBJDEP # warning REQUIRES: pts_defl #endif class FlateEncode: public PSEncoder { #if PTS_DEFL_RIPPED_ZLIB /* Dat: defined in pts_defl.h */ public: /** @param level: 1..9: 9==highest compression */ FlateEncode(GenBuffer::Writable &out_, unsigned level_); virtual ~FlateEncode() { zlib_deflateEnd(&zs); } /* Dat: ==Z_OK check (for unflushed buffers) omitted */ virtual void vi_write(char const*buf, slen_t len); protected: /** Formerly only one instance of FlateEncode was allowed. * It exists <=> loced==true */ // static bool locked; /** Writable that this filter writes to */ GenBuffer::Writable &out; char workspace[ZLIB_DEFLATE_WORKSPACESIZE_MIN]; /* big, about 300k */ char obuf[4096]; /*struct*/ z_stream zs; #else /* old, ripped from Info-ZIP 2.2 */ public: /** @param level: 1..9: 9==highest compression */ FlateEncode(GenBuffer::Writable &out_, unsigned level_); virtual ~FlateEncode() { if (fs!=NULLP) fs->delete2(fs); } virtual void vi_write(char const*buf, slen_t len); static void *gen_malloc(unsigned n); static void gen_free(void *p); protected: /** Formerly only one instance of FlateEncode was allowed. * It exists <=> loced==true */ // static bool locked; /** Writable that this filter writes to */ GenBuffer::Writable &out; #if SIZEOF_INT>2 typedef unsigned s_t; #else typedef unsigned short s_t; #endif /** Adler32 checksum */ s_t s1, s2; bool had_header; struct pts_defl_interface* fs; #endif /* else PTS_DEFL_RIPPED_ZLIB */ }; #endif /** Just store the data in Flate (ZLIB) format, no real compression. Adds * about 3 bytes of overhead per 65535 bytes (compression ratio: * 100.004578%) */ class FlateStoreEncode: public PSEncoder { public: /** @param level: 1..9: 9==highest compression */ FlateStoreEncode(GenBuffer::Writable &out_); inline virtual ~FlateStoreEncode() {} virtual void vi_write(char const*buf, slen_t len); protected: GenBuffer::Writable &out; #if SIZEOF_INT>2 typedef unsigned s_t; #else typedef unsigned short s_t; #endif /** Adler32 checksum */ s_t s1, s2; bool had_header; /** Number of bytes already in buf */ unsigned abuflen; /** Max: 65535 */ #if HAVE_STATIC_CONST static const unsigned ABUFSIZE=65535; #else #define ABUFSIZE 65535 #endif /** Should really not allocate a FlateStoreEncode on the stack. */ char abuf[ABUFSIZE+5]; }; #if USE_BUILTIN_FAXE #include "pts_fax.h" #if OBJDEP # warning REQUIRES: pts_faxe #endif class CCITTFaxEncode: public PSEncoder { public: CCITTFaxEncode(GenBuffer::Writable &out_, slendiff_t K, slen_t Columns, bool EndOfLine, bool BlackIs1); virtual void vi_write(char const*buf, slen_t len); protected: GenBuffer::Writable &out; stream_CFE_state sCFEs; unsigned char rbuf[4096]; unsigned char wbuf[4096]; stream_cursor_read r; stream_cursor_write w; unsigned char *hard, *rlimit; static void*gen_xalloc(unsigned n); static void gen_free(void *ptr); static void gen_memset(void *s, int c, unsigned n); static void gen_memcpy(void *dest, const void *src, unsigned n); }; #endif #if USE_BUILTIN_LZW #include "pts_lzw.h" /* Imp: because pts_lzw_state :-( */ #if OBJDEP # warning REQUIRES: pts_lzw #endif class LZWEncode: public PSEncoder { public: LZWEncode(GenBuffer::Writable &out_); virtual void vi_write(char const*buf, slen_t len); protected: GenBuffer::Writable &out; struct pts_lzw_state fs; }; #endif /** * Reporting of GS errors is somewhat dump: the actual message isn't reported, * only the fact that something went wrong. * Imp: force a no-error trailer output by gs, and check that */ class GSEncode: public PSEncoder { public: /** @param filter_psname is a full-featured PostScript *Encode filter * specification string, for example: "<>/FlateEncode" or * "0/RunLengthEncode" or "72 pop/ASCIIHexEncode"; will be surrounded as * `currentfile ... filter' */ GSEncode(GenBuffer::Writable &out_, char const*filter_psname); inline virtual ~GSEncode() {} /* vvv Imp: correct these */ virtual void vi_write(char const*buf, slen_t len); protected: class P: public Filter::PipeE { protected: virtual void vi_check(); public: P(GenBuffer::Writable &out_, char const*filter_psname); }; /** We need this delegator because `delete ...' won't work with multiple * inheritance. (?? ) */ P p; }; class CjpegEncode: public PSEncoder { public: /** @param filter_psname is a full-featured PostScript *Encode filter * specification string, for example: "<>/FlateEncode" or * "0/RunLengthEncode" or "72 pop/ASCIIHexEncode"; will be surrounded as * `currentfile ... filter' */ CjpegEncode(GenBuffer::Writable &out_, char const*filter_psname, slen_t Columns, slen_t Rows, bool rgbp_, unsigned char quality); inline virtual ~CjpegEncode() {} virtual void vi_write(char const*buf, slen_t len); protected: class P: public Filter::PipeE { public: // protected: virtual void vi_check(); P(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, bool rgbp_, unsigned char quality); protected: /* Not needed: protected -> public: pacify VC6.0 */ virtual void vi_copy(FILE *f); bool rgbp; }; /** We need this delegator because `delete ...' won't work with multiple * inheritance. (?? ) */ P p; }; #if !USE_BUILTIN_LZW class Lzw_codecEncode: public PSEncoder { public: /** @param filter_psname is a full-featured PostScript *Encode filter * specification string, for example: "<>/FlateEncode" or * "0/RunLengthEncode" or "72 pop/ASCIIHexEncode"; will be surrounded as * `currentfile ... filter' */ Lzw_codecEncode(GenBuffer::Writable &out_, char const*filter_psname); inline virtual ~Lzw_codecEncode() {} virtual void vi_write(char const*buf, slen_t len); protected: class P: public Filter::PipeE { public: // protected: virtual void vi_check(); P(GenBuffer::Writable &out_); protected: // virtual void vi_copy(FILE *f); }; /** We need this delegator because `delete ...' won't work with multiple * inheritance. (?? ) */ P p; }; #endif class TIFFPredictor2: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ TIFFPredictor2(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h; unsigned char *obuf, *op, bpc, cpp; slen_t rlen; GenBuffer::Writable &out; }; class PNGPredictorNone: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorNone(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: slen_t rlen, opleft; GenBuffer::Writable &out; }; class PNGPredictorSub: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorSub(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h; unsigned char *obuf, *op; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; }; class PNGPredictorUp: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorUp(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned char *obuf, *op, *oq; slen_t rlen; GenBuffer::Writable &out; }; class PNGPredictorAverage: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorAverage(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h/*, g*/; unsigned char *obuf, *op, *oq; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; }; class PNGPredictorPaeth: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorPaeth(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h, g; unsigned char *obuf, *op, *oq; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; }; /** This class implements inferior predictor autoselection heuristics. * Please use PNGPredictorAuto instead. * Imp: code reuse with PNGPredictorAuto */ class PNGPredictorAutoBadSigned: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorAutoBadSigned(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h, g; unsigned char *obuf, *o_prior, *o_0, *o_1, *o_2, *o_3, *o_4, *oo[5]; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; slen_t opleft; }; /** This class implements inferior predictor autoselection heuristics. * Please use PNGPredictorAuto instead. * Imp: code reuse with PNGPredictorAuto */ class PNGPredictorAutoBadUnsigned: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorAutoBadUnsigned(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h, g; unsigned char *obuf, *o_prior, *o_0, *o_1, *o_2, *o_3, *o_4, *oo[5]; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; slen_t opleft; }; /** This class implements to so-called ``minimum sum of absolute differences'' * predictior autoselection heuristics, the same as what pngwutil.c * contains in function png_write_find_filter() in libpng 1.2.20. (See that * function for a discussion of other heuristics. A summary of this heuristics: * we find which method provides the smallest value when summing the absolute * values of the distances from zero, using anything >= 128 as negative * numbers. */ class PNGPredictorAuto: public Encoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ PNGPredictorAuto(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_); virtual void vi_write(char const*buf, slen_t len); protected: unsigned PTS_INT32_T h, g; unsigned char *obuf, *o_prior, *o_0, *o_1, *o_2, *o_3, *o_4, *oo[5]; slen_t rlen; GenBuffer::Writable &out; unsigned char bpccpp; slen_t opleft; }; /* --- */ FlateStoreEncode::FlateStoreEncode(GenBuffer::Writable &out_) :out(out_) ,s1(1) ,s2(0) ,had_header(false) ,abuflen(0) {} #if 0 /** 0x7801: ZLIB header signaling fastest compression * 0: 2 bits: DEFLATE block header signaling stored (uncompressed) block + * 6 bits of padding. */ char FlateStoreEncode::header[3]= { 0x78, 1, 0 }; #endif void FlateStoreEncode::vi_write(char const*buf, slen_t len) { register s_t sold; register char const*p=buf; char const*pend=p+len; (void)sold; if (len==0) { /* EOF: flush and send trailer */ /* Dat: Last block has to be written even if it's empty. */ if (!had_header) { out.vi_write("\x78\x01", 2); had_header=true; } abuf[0]=(char)1; /* Last, stored block with padding */ abuf[1]=abuflen; abuf[2]=abuflen>>8; abuf[3]=~(abuflen); abuf[4]=~(abuflen>>8); out.vi_write(abuf, abuflen+5); if (s1>=65521) s1-=65521; if (s2>=65521) s2-=65521; unsigned char trailer[4]; trailer[0]=s2>>8; trailer[1]=s2&255; trailer[2]=s1>>8; trailer[3]=s1&255; out.vi_write((char const*)trailer,4); out.vi_write(0,0); /* Signal EOF */ return; } /* From rfc1950.txt: Adler-32 is composed of two sums accumulated per byte: s1 is the sum of all bytes, s2 is the sum of all s1 values. Both sums are done modulo 65521. s1 is initialized to 1, s2 to zero. The Adler-32 checksum is stored as s2*65536 + s1 in most- significant-byte first (network) order. */ /* Update Adler-32 checksum */ while (p!=pend) { #if SIZEOF_INT>2 if ((s1+=*(unsigned char const*)p)>=65521) s1-=65521; if ((s2+=s1)>=65521) s2-=65521; #elif SIZEOF_SHORT==2 sold=s1; if ((s1+=*(unsigned char const*)p)) 0..65535 */ sold=s1; s1=(s1+*(unsigned char const*)p)&0xffff; if (s1>8); abuf[3]=(char)~(ABUFSIZE); abuf[4]=(char)~(ABUFSIZE>>8); if (!had_header) { out.vi_write("\x78\x01", 2); had_header=true; } /* fprintf(stderr,"%02x %02x", abuf[1], abuf[2]); */ out.vi_write(abuf, ABUFSIZE+5); /* emit next stored block with header */ abuflen=0; len-=abufleft; buf+=abufleft; } // putchar('X'); memcpy(abuf+abuflen+5, buf, len); abuflen+=len; /* Now abuf is possibly full. That is intentional, so we will be able to * emit a full last block instead of an empty one. */ } /* --- */ ASCIIHexEncode::ASCIIHexEncode(GenBuffer::Writable &out_, unsigned maxcpl_) :maxcpl(maxcpl_) ,curcpl(0) ,out(out_) {} void ASCIIHexEncode::vi_write(char const*buf, slen_t len) { /* Imp: buffering (1K etc.) */ static char const hextable []="0123456789abcdef"; char obuf[3]; obuf[0]='\n'; if (len==0) { out.vi_write(">",1); out.vi_write(0,0); } else while (len--!=0) { obuf[1]=hextable[(*(unsigned char const*)buf)>>4]; obuf[2]=hextable[(*(unsigned char const*)buf)&15]; if (curcpl>=maxcpl) { curcpl=2; out.vi_write(obuf, 3); } else { curcpl+=2; out.vi_write(obuf+1, 2); } buf++; } } /* --- */ ASCII85Encode::ASCII85Encode(GenBuffer::Writable &out_, unsigned maxcpl_) :maxcpl(maxcpl_) ,out(out_) ,ascii85breaklen(maxcpl_) ,ascii85left(4) { obufend=(op=obuf=new char[4096])+4096; } void ASCII85Encode::vi_write(char const*buf, slen_t len) { if (len==0) { char encoded[6]; assert(ascii85left<=4); if (ascii85left!=4) { unsigned PTS_INT32_T buf_=ascii85buf<<8*ascii85left; unsigned PTS_INT32_T q; unsigned w1; q = buf_ / ((unsigned PTS_INT32_T)85*85*85*85); /* actually only a byte */ assert(q<=85); encoded[0] = q + '!'; buf_ -= q * ((unsigned PTS_INT32_T)85*85*85*85); q = buf_ / ((unsigned PTS_INT32_T)85*85*85); encoded[1] = q + '!'; buf_ -= q * ((unsigned PTS_INT32_T)85*85*85); q = buf_ / (85*85); encoded[2] = q + '!'; w1 = (unsigned) (buf_ - q*(unsigned PTS_INT32_T)(85*85)); assert(w1/85<85); encoded[3] = (w1 / 85) + '!'; encoded[4] = (w1 % 85) + '!'; encoded[5-ascii85left] = '\0'; char* cp; for (cp = encoded; *cp!='\0'; ) { if (op==obufend) out.vi_write(op=obuf, obufend-obuf); // if (*cp<='!') { fprintf(stderr, "e=%d.\n", cp-encoded); } assert(*cp>='!'); assert(*cp<='~'); *op++=*cp++; if (--ascii85breaklen == 0) { if (op==obufend) out.vi_write(op=obuf, obufend-obuf); *op++='\n'; ascii85breaklen = maxcpl; } } /* NEXT */ } /* IF */ if (op!=obuf) out.vi_write(obuf, op-obuf); /* flush buffer cache */ out.vi_write("~>",2); out.vi_write(0,0); delete [] obuf; obuf=(char*)NULLP; } else { assert(obuf!=NULLP); register unsigned PTS_INT32_T abuf=ascii85buf; register unsigned aleft=ascii85left; assert(aleft>=1 && aleft<=4); do { while (len!=0 && aleft!=0) { abuf=(abuf<<8)+*(unsigned char const*)buf++; len--; aleft--; } if (aleft!=0) break; wout(abuf); aleft=4; } while (len!=0); ascii85buf=abuf; ascii85left=aleft; } } void ASCII85Encode::wout(unsigned PTS_INT32_T buf_) { char encoded[6]; if (buf_ != (unsigned PTS_INT32_T)0) { unsigned PTS_INT32_T q; unsigned w1; q = buf_ / ((unsigned PTS_INT32_T)85*85*85*85); /* actually only a byte */ encoded[0] = q + '!'; buf_ -= q * ((unsigned PTS_INT32_T)85*85*85*85); q = buf_ / ((unsigned PTS_INT32_T)85*85*85); encoded[1] = q + '!'; buf_ -= q * ((unsigned PTS_INT32_T)85*85*85); q = buf_ / (85*85); encoded[2] = q + '!'; w1 = (unsigned) (buf_ - q*(unsigned PTS_INT32_T)(85*85)); encoded[3] = (w1 / 85) + '!'; encoded[4] = (w1 % 85) + '!'; encoded[5] = '\0'; } else { encoded[0] = 'z', encoded[1] = '\0'; } char* cp; for (cp = encoded; *cp!='\0'; ) { if (op==obufend) out.vi_write(op=obuf, obufend-obuf); assert(*cp>='!'); assert(*cp<='~'); *op++=*cp++; if (--ascii85breaklen == 0) { if (op==obufend) out.vi_write(op=obuf, obufend-obuf); *op++='\n'; ascii85breaklen = maxcpl; } } } /* --- */ RunLengthEncode::RunLengthEncode(GenBuffer::Writable &out_, slen_t RecordSize_) :recordsize(RecordSize_==0?(slen_t)-1:RecordSize_) ,out(out_) { record_left=recordsize; // obufend=(op=obuf=new char[4096])+4096; /* Imp: implement write buffering */ saved_c=saved_rep=0; } void RunLengthEncode::vi_write(char const*buf, slen_t len) { unsigned j, umax; char b; if (len==0) { /* handle EOF */ if (saved_rep!=0) { assert(saved_rep>=2); (saved+1)[-1]=257-saved_rep; (saved+1)[1]=(char)128; /* EOD */ out.vi_write((saved+1)-1,3); // fprintf(stderr,"rd=%u\n",saved_rep); } else if (saved_c!=0) { (saved+1)[-1]=saved_c-1; (saved+1)[saved_c]=(char)128; /* EOD */ out.vi_write((saved+1)-1, saved_c+2); // fprintf(stderr,"re=%u\n",saved_c); } else { (saved+1)[-1]=(char)128; out.vi_write((saved+1)-1, 1); } out.vi_write(0,0); /* propagate EOF */ record_left=0; /* signal that no further data will be accepted */ return; } again: assert(record_left>=1); assert(len>=1); /* Imp: locally cache vars saved* */ j=0; if (saved_c==0) { saved_rep=0; saved_c=1; b=(saved+1)[0]=*buf++; len--; if (0==--record_left) goto put_norep; if (0==len) return; goto yes; } if (saved_c==1 && saved_rep==0) { yes: if (*buf++==(saved+1)[0]) { saved_rep=2; len--; if (0==--record_left) goto put_rep; } else { (saved+1)[1]=buf[-1]; saved_c=2; len--; if (0==--record_left) goto put_norep; } if (0==len) return; } assert(record_left>=1); assert(len>=1); assert((saved_rep==0 && saved_c>=2) || (saved_rep>=2 && saved_c==1)); if (saved_rep!=0) { /* Try to increase the repeating sequence */ assert(saved_rep>=2); assert(saved_c==1); assert(len>=1); b=(saved+1)[0]; umax=len>128?128:len; if (umax>record_left) umax=record_left; /* fprintf(stderr,"um1=%u\n", umax); */ if (umax>128-saved_rep) umax=128-saved_rep; assert(umax>=1); j=0; while (j!=umax && buf[j]==b) { j++; saved_rep++; } if (j!=len || saved_rep==128) { put_rep: /* Found a maximal repeat width */ (saved+1)[-1]=257-saved_rep; out.vi_write((saved+1)-1,2); /* fprintf(stderr,"ra=%u\n",saved_rep); */ if ((record_left-=j)==0) record_left=recordsize; buf+=j; saved_c=saved_rep=0; if (0==(len-=j)) return; goto again; } /* Current repeat width can be further increased */ } else { /* Try to increase the non-repeating sequence */ assert(saved_c>=2); if (buf[0]==(saved+1)[saved_c-1]) { /* this decision might be sub-optimal */ saved_c--; /* Now: saved_c: non-repeat length, >=1 */ (saved+1)[-1]=saved_c-1; out.vi_write((saved+1)-1, saved_c+1); /* fprintf(stderr,"rb=%u\n",saved_c); */ // record_left++; /* because of saved_c--; but we would increase it later anyway */ // buf+=saved_c; (saved+1)[0]=buf[0]; /* first matching char-pair data */ saved_c=1; saved_rep=2; /* make the new block a >=2 repeat */ record_left--; buf++; if (0==--len) return; goto again; } (saved+1)[saved_c++]=buf[0]; //record_left--; //buf++; //len--; //if (saved_c==128) goto put_norep; //if (0==len) return; umax=len>128?128:len; if (umax>record_left) umax=record_left; if (umax>128-saved_c) umax=128-saved_c; /* fprintf(stderr,"um2=%u\n", umax); */ assert(umax>=1); j=1; while (j!=umax && buf[j]!=buf[j-1]) (saved+1)[saved_c++]=buf[j++]; if (j!=len || saved_c==128) { put_norep: /* Found a maximal non-repeat width */ (saved+1)[-1]=saved_c-1; out.vi_write((saved+1)-1, saved_c+1); /* fprintf(stderr,"rc=%u\n",saved_c); */ if ((record_left-=j)==0) record_left=recordsize; buf+=j; saved_c=saved_rep=0; if (0==(len-=j)) return; goto again; } /* Current non-repeat width can be further increased */ } assert(j==len); record_left-=j; assert(saved_rep<128); assert(saved_c<128); } /* --- */ #if USE_BUILTIN_ZIP // bool FlateEncode::locked=false; #if PTS_DEFL_RIPPED_ZLIB FlateEncode::FlateEncode(GenBuffer::Writable &out_, unsigned level_) :out(out_) { // assert(!locked); locked /* locking is not necessary anymore */ // pts_deflate_init(&fs); /* obsolete */ zs.total_in=0; zs.total_out=0; zs.workspace=workspace; zs.msg=(char*)0; zs.state=(struct zlib_internal_state*)0; zs.data_type=Z_UNKNOWN; /* Imp: do we have to initialize it? */ assert(zlib_deflate_workspacesize()+(unsigned)0(buf); zs.avail_in=len; if (len==0) { /* flush all output */ do { /* SUXX: C compiler should emit a warning: while (1) { ... } while(...); */ zs.next_out=(unsigned char*)obuf; zs.avail_out=sizeof(obuf); /* fprintf(stderr,"wdone zai=%d zao=%d\n", zs.avail_in, zs.avail_out); */ if (Z_STREAM_END!=(zgot=zlib_deflate(&zs, Z_FINISH)) && Z_OK!=zgot) Error::sev(Error::EERROR) << "Flate close error: " << zs.msg << (Error*)0; got=sizeof(obuf)-zs.avail_out; /* fprintf(stderr, "got=%u zgot=%d Z_OK=%d\n", got, zgot, Z_OK); */ if (got>0) out.vi_write(obuf, got); } while (zgot==Z_OK); /* Dat: zlib_deflateEnd() will be called in the destructur */ out.vi_write(0,0); /* Signal EOF */ /* Dat: zlib_deflate() adds RFC 1950 header and adler32 checksum automatically */ } else { do { /* fprintf(stderr,"writ\n"); */ zs.next_out=(unsigned char*)obuf; zs.avail_out=sizeof(obuf); if (Z_OK!=zlib_deflate(&zs, 0)) Error::sev(Error::EERROR) << "Flate write error: " << zs.msg << (Error*)0; if (0<(got=sizeof(obuf)-zs.avail_out)) out.vi_write(obuf, got); } while (0!=zs.avail_in); } } #else FlateEncode::FlateEncode(GenBuffer::Writable &out_, unsigned level_) :out(out_) ,s1(1) ,s2(0) ,had_header(false) { // assert(!locked); locked /* locking is not necessary anymore */ // pts_deflate_init(&fs); /* obsolete */ fs=pts_defl_new( /*zpfwrite=*/ gen_write, /*zpfmalloc=*/ gen_malloc, /*zpffree=*/ gen_free, /*pack_level=*/ level_, /*zfile=*/ (void*)&out_ ); if (fs==NULL) Error::sev(Error::EERROR) << "Flate init error (out of memory?)" << (Error*)0; } void *FlateEncode::gen_malloc(unsigned n) { return operator new(n); // return new char[n]; } void FlateEncode::gen_free(void *p) { /*return*/ operator delete(p); // delete [] (char*)p; } void FlateEncode::vi_write(char const*buf, slen_t len) { register s_t sold; register char const*p=buf; char const*pend=p+len; (void)sold; if (!had_header) { out.vi_write("\x78\xda",2); /* ZLIB (RFC 1950): max compression header */ had_header=true; } if (len==0) { /* EOF: send trailer */ fs->deflate2(0,0,fs); /* Let the compressor flush its buffers. */ if (fs->err!=0) Error::sev(Error::EERROR) << "Flate compression error" << (Error*)0; fs->delete2(fs); fs=(struct pts_defl_interface*)NULL; if (s1>=65521) s1-=65521; if (s2>=65521) s2-=65521; unsigned char trailer[4]; trailer[0]=s2>>8; trailer[1]=s2&255; trailer[2]=s1>>8; trailer[3]=s1&255; out.vi_write((char const*)trailer,4); out.vi_write(0,0); /* Signal EOF */ return; } assert(fs!=NULL); /* From rfc1950.txt: Adler-32 is composed of two sums accumulated per byte: s1 is the sum of all bytes, s2 is the sum of all s1 values. Both sums are done modulo 65521. s1 is initialized to 1, s2 to zero. The Adler-32 checksum is stored as s2*65536 + s1 in most- significant-byte first (network) order. */ /* Update Adler-32 checksum */ while (p!=pend) { #if SIZEOF_INT>2 if ((s1+=*(unsigned char const*)p)>=65521) s1-=65521; if ((s2+=s1)>=65521) s2-=65521; #elif SIZEOF_SHORT==2 sold=s1; if ((s1+=*(unsigned char const*)p)) 0..65535 */ sold=s1; s1=(s1+*(unsigned char const*)p)&0xffff; if (s1=0x8000) { fs->deflate2(const_cast(buf),0x8000, fs); len-=0x8000; buf+=0x8000; } if (len!=0) fs->deflate2(const_cast(buf),len, fs); } #endif /* PTS_DEFL_RIPPED_ZLIB */ #endif /* USE_BUILTIN_ZIP */ int /*FlateEncode::*/gen_write(char *block, unsigned len, void *zfile) { static_cast(zfile)->vi_write(block, len); return 0; } /* --- */ #if USE_BUILTIN_FAXE void* CCITTFaxEncode::gen_xalloc(unsigned n) { return operator new(n); // void *ret; if ((ret=malloc(n))==0) abort(); return ret; } void CCITTFaxEncode::gen_free(void *ptr) { /*return*/ operator delete(ptr); // free(ptr); } void CCITTFaxEncode::gen_memset(void *s, int c, unsigned n) { /*return*/ memset(s,c,n); } void CCITTFaxEncode::gen_memcpy(void *dest, const void *src, unsigned n) { /*return*/ memcpy(dest, src, n); } CCITTFaxEncode::CCITTFaxEncode(GenBuffer::Writable &out_, slendiff_t K, slen_t Columns, bool EndOfLine, bool BlackIs1): out(out_) { sCFEs.memset_=gen_memset; sCFEs.xalloc_=gen_xalloc; sCFEs.free_=gen_free; sCFEs.memcpy_=gen_memcpy; s_CFE_template.set_defaults((stream_state*)&sCFEs); sCFEs.K=K; sCFEs.Columns=Columns; sCFEs.EndOfLine=EndOfLine; sCFEs.BlackIs1=BlackIs1; const int cf_max_height=(unsigned)-1/2-100; /* Dat: was slen_t */ if (sCFEs.K < -cf_max_height || sCFEs.K > cf_max_height /* Dat: .K is an int */ || sCFEs.Columns < 0 || sCFEs.Columns > cfe_max_width /* Dat: .Columns is an int */ || sCFEs.Rows < 0 || sCFEs.Rows > cf_max_height /* Dat: .Rows is an int */ || sCFEs.DamagedRowsBeforeError < 0 || sCFEs.DamagedRowsBeforeError > cf_max_height /* Dat: .DamagedRowsBeforeError is an int */ || sCFEs.DecodedByteAlign < 1 || sCFEs.DecodedByteAlign > 16 || (sCFEs.DecodedByteAlign & (sCFEs.DecodedByteAlign - 1)) != 0 ) Error::sev(Error::EERROR) << "pts_fax: invalid params" << (Error*)0; if (0!=s_CFE_template.init((stream_state*)&sCFEs)) Error::sev(Error::EERROR) << "pts_fax: init failed" << (Error*)0; #if __CHECKER__ memset(&r, 0, sizeof(r)); memset(&w, 0, sizeof(w)); #endif r.ptr=rlimit=rbuf-1; hard=rbuf+sizeof(rbuf)-1; assert(hard-r.ptr>=(int)s_CFE_template.min_in_size); } void CCITTFaxEncode::vi_write(char const*buf, slen_t len) { int pog; // unsigned char *save_wptr; if (len==0) { r.limit=rlimit; do { w.ptr=wbuf-1; w.limit=wbuf+sizeof(wbuf)-1; assert(w.limit-w.ptr>=(int)s_CFE_template.min_out_size); pog=s_CFE_template.process((stream_state*)&sCFEs, &r, &w, /*last:*/ true); // fprintf(stderr, "pog=%d write=%d last=%d\n", pog, w.ptr-(wbuf-1), true); assert(pog!=PTSFAX_ERRC); /* /CCITTFaxEncode filter must accept any input */ assert(pog!=PTSFAX_EOFC); /* /CCITTFaxEncode filter doesn't have EOD markers */ if (w.ptr!=wbuf-1) out.vi_write((char const*)wbuf, w.ptr-(wbuf-1)); } while (pog==1); s_CFE_template.release((stream_state*)&sCFEs); out.vi_write(0,0); /* propagate EOF */ return; } while (len!=0) { assert(r.ptr==rbuf-1); assert(hard>rlimit); unsigned clen=hard-rlimit; if (clen>len) clen=len; assert(clen>0); // fprintf(stderr, "clen=%u\n", clen); memcpy(rlimit+1, buf, clen); rlimit+=clen; buf+=clen; len-=clen; /* if (r.ptr==rlimit) break; */ r.limit=rlimit; do { w.ptr=wbuf-1; w.limit=wbuf+sizeof(wbuf)-1; assert(w.limit-w.ptr>=(int)s_CFE_template.min_out_size); pog=s_CFE_template.process((stream_state*)&sCFEs, &r, &w, /*last:*/ false); // fprintf(stderr, "len=%d pog=%d write=%d last=%d\n", len, pog, w.ptr-(wbuf-1), false); assert(pog!=PTSFAX_ERRC); /* /CCITTFaxEncode filter must accept any input */ assert(pog!=PTSFAX_EOFC); /* /CCITTFaxEncode filter doesn't have EOD markers */ if (w.ptr!=wbuf-1) out.vi_write((char const*)wbuf, w.ptr-(wbuf-1)); } while (pog==1); // assert(pog!=1); /* not true: output space is enough (sizeof(wbuf)>min_out_size) */ assert(pog==0); /* more input is needed */ if (r.ptr!=rbuf-1) { // fprintf(stderr, "limit=%d\n", rlimit-r.ptr); memmove(rbuf, r.ptr+1, rlimit-r.ptr); rlimit=rbuf-1+(rlimit-r.ptr); r.ptr=rbuf-1; } } // fprintf(stderr, "done\n"); } #endif /* USE_BUILTIN_FAXE */ /* --- */ #if USE_BUILTIN_LZW LZWEncode::LZWEncode(GenBuffer::Writable &out_): out(out_) { fs.tif_writer=/*FlateEncode::*/gen_write; fs.tif_sout=(void*)&out_; if (0==pts_lzw_init(&fs)) Error::sev(Error::EERROR) << "LZW init error" << (Error*)0; } void LZWEncode::vi_write(char const*buf, slen_t len) { /* Imp: report real error _reason_ (if appropriate?? ) */ if (len==0) { if (0==fs.tif_feeder(0,0,&fs)) goto we; out.vi_write(0,0); /* propagate EOF */ return; } while (len>=0x8000) { if (0==fs.tif_feeder(const_cast(buf),0x8000,&fs)) we: Error::sev(Error::EERROR) << "LZW write error" << (Error*)0; len-=0x8000; buf+=0x8000; } if (len!=0 && 0==fs.tif_feeder(const_cast(buf),len,&fs)) goto we; } #endif /* USE_BUILTIN_LZW */ /* --- */ #if !USE_BUILTIN_LZW Lzw_codecEncode::Lzw_codecEncode(GenBuffer::Writable &out_, char const*filter_psname) :p(out_) { (void)filter_psname; } void Lzw_codecEncode::vi_write(char const*buf, slen_t len) { p.vi_write(buf,len); } /* Imp: figure out path-to-gs: gs or gswin32c */ Lzw_codecEncode::P::P(GenBuffer::Writable &out_) // :PipeEncoder(out_, ">/tmp/t cat - cjpeg quality %i", quality), rgbp(rgbp_) { // :Filter::PipeE(out_, "cjpeg -quality %i >%D", quality), rgbp(rgbp_) { :Filter::PipeE(out_, "lzw_codec encode >%D") {} #endif /* --- */ CjpegEncode::CjpegEncode(GenBuffer::Writable &out_, char const*filter_psname, slen_t Columns, slen_t Rows, bool rgbp_, unsigned char quality) :p(out_, Columns, Rows, rgbp_, quality) { (void)filter_psname; } void CjpegEncode::vi_write(char const*buf, slen_t len) { p.vi_write(buf,len); } /* Imp: figure out path-to-gs: gs or gswin32c */ CjpegEncode::P::P(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, bool rgbp_, unsigned char quality) // :PipeEncoder(out_, ">/tmp/t cat - cjpeg quality %i", quality), rgbp(rgbp_) { :Filter::PipeE(out_, "cjpeg -quality %i >%D", quality), rgbp(rgbp_) { /* Dat: we're extremely lucky that cjpeg can read PGM or PPM files from stdin */ // operator<<("P5 width height 255\n"); /* RAWBITS PGM */ // operator<<("P6 width height 255\n"); /* RAWBITS PPM */ *this << (rgbp_?"P6 ":"P5 ") << Columns << ' ' << Rows << " 255\n"; } void CjpegEncode::P::vi_copy(FILE *f) { char r[10]; static char jfif[9]="\377\340\000\020JFIF"; static unsigned char adobe[16]= { 0xff, /* marker */ 0xee, /* APP14 */ 0, /* length-hi */ 14, /* length-lo */ 'A', 'd', 'o', 'b', 'e', /* ID */ 1, /* version-hi */ 0, /* version-lo */ 0, 0, /* flags0 */ 0, 0, /* flags1 */ 0, /* ColorTransform */ }; if (MACRO_GETC(f)!=0xff || MACRO_GETC(f)!=0xd8 || fread(r, 1, 8, f)!=8) { bad: Error::sev(Error::EERROR) << "CjpegEncode: cjpeg created bad JPEG" << (Error*)0; } out.vi_putcc((char)0xff); out.vi_putcc((char)0xd8); r[9]=r[3]; r[3]='\020'; if ((unsigned char)r[9]>=6 && 0==memcmp(r, jfif, 8)) { /* JFIF marker */ r[3]=r[9]; unsigned skip=r[9]-6; out.vi_write(r, 8); while (skip--!=0) out.vi_putcc(MACRO_GETC(f)); } if (ferror(f) || feof(f)) goto bad; /* Now we can emit the Adobe marker. */ adobe[sizeof(adobe)-1]=rgbp==true; /* ColorTransform value 0 for Gray, 1 for RGB->YCbCr */ out.vi_write((char*)adobe, sizeof(adobe)); /* vvv Dat: pacify VC6.0: Filter::PipeE::vi_copy(f); doesn't work */ PipeE::vi_copy(f); /* ^^^ copy rest of file verbatim */ // ((Filter::PipeE)*this).vi_copy(f); } /* --- */ GSEncode::GSEncode(GenBuffer::Writable &out_, char const*filter_psname) :p(out_, filter_psname) {} void GSEncode::vi_write(char const*buf, slen_t len) { p.vi_write(buf,len); } /* Imp: figure out path-to-gs: gs or gswin32c */ GSEncode::P::P(GenBuffer::Writable &out_, char const*filter_psname) :Filter::PipeE(out_, "gs -s_OFN=%D -dNODISPLAY -q - >%E") { operator<<("{/o _OFN(w)file "); operator<<(filter_psname); operator<<(" filter def/s 4096 string def" "{currentfile s readstring exch o exch writestring not{exit}if}loop " "o closefile quit}bind exec\n"); } void GSEncode::P::vi_check() { /* If STDOUT of gs is not empty, then it is very probably an error message. */ // tmpename.term0(); /* already is */ assert(tmpename.end_()[0]=='\0'); if (0!=Files::statSize(tmpename())) Error::sev(Error::EERROR) << "GSEncode: GS runtime error" << (Error*)0; /* Imp: display a meaningful error message */ } /* --- */ PSEncoder* PSEncoder::newASCIIHexEncode(GenBuffer::Writable &out_,unsigned maxcpl_) { // SimBuffer::B fp; (fp << maxcpl_ << " pop/ASCIIHexEncode").term0(); // PSEncoder *ret=new GSEncode(out_, fp()); PSEncoder *ret=new ASCIIHexEncode(out_,maxcpl_); // ret->shortname="AHx"; ret->longname="ASCIIHex"; // ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newASCII85Encode(GenBuffer::Writable &out_,unsigned maxcpl_) { // SimBuffer::B fp; (fp << maxcpl_ << " pop/ASCII85Encode").term0(); PSEncoder *ret=new ASCII85Encode(out_,maxcpl_); // PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="A85"; ret->longname="ASCII85"; // ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newCCITTFaxEncode(GenBuffer::Writable &out_,slendiff_t K, slen_t Columns, bool EndOfLine, bool BlackIs1) { #if USE_BUILTIN_FAXE return new CCITTFaxEncode(out_, K, Columns, EndOfLine, BlackIs1); #else // (void)out_; (void)K; (void)Columns; // assert(0 && "unimplemented"); SimBuffer::B fp("<< /K "); fp << K << "/Columns " << Columns; if (EndOfLine) fp << "/EndOfLine true"; /* PS default: false */ if (BlackIs1) fp << "/BlackIs1 true"; (fp << ">>/CCITTFaxEncode").term0(); // fprintf(stderr, "fp=(%s)\n", fp()); PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="CCF"; ret->longname="CCITTFax"; // ret->filter_psname << fp; /* Dat: this could be made faster */ return ret; #endif } PSEncoder* PSEncoder::newLZWEncode(GenBuffer::Writable &out_) { #if USE_BUILTIN_LZW SimBuffer::B fp("/LZWEncode"); PSEncoder *ret=new LZWEncode(out_); // PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="LZW"; ret->longname="LZW"; // ret->filter_psname << fp; return ret; #else (void)out_; #if 0 Error::sev(Error::EERROR) << "LZW not supported in this compilation of sam2p" << (Error*)0; #endif Error::sev(Error::WARNING) << "LZW: please `configure --enable-lzw' for builtin /Compression/LZW support" << (Error*)0; #if 0 /* This is useless, because gs 5.50--7.04 have dummy LZW compressor: * it emits a correct LZW stream, but does no real compression, and * the file size is often increased. */ PSEncoder *ret=new GSEncode(out_, "/LZWEncode"); // ret->shortname="LZW"; ret->longname="LZW"; // ret->filter_psname << "/LZWEncode"; return ret; #endif #if 1 /* ask lzw_codec from the author of sam2p */ return new Lzw_codecEncode(out_, "/LZWEncode"); #endif return 0; #endif } PSEncoder* PSEncoder::newFlateEncode(GenBuffer::Writable &out_, signed Effort) { // (void)out_; (void)K; (void)Columns; // assert(0 && "unimplemented"); if (Effort==0) { PSEncoder *ret=new FlateStoreEncode(out_); // ret->shortname="Fla"; ret->longname="Flate"; // ret->filter_psname << fp; return ret; } if (Effort<1 || Effort>9) Effort=5; #if USE_BUILTIN_ZIP PSEncoder *ret=new FlateEncode(out_, Effort); #else SimBuffer::B fp("<>/FlateEncode").term0(); PSEncoder *ret=new GSEncode(out_, fp()); #endif // ret->shortname="Fla"; ret->longname="Flate"; // ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newRunLengthEncode(GenBuffer::Writable &out_, slen_t RecordSize) { SimBuffer::B fp; (fp << RecordSize << "/RunLengthEncode").term0(); PSEncoder *ret=new RunLengthEncode(out_, RecordSize); // PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="RL"; ret->longname="RunLength"; // ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newDCTIJGEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char quality /*libJPEG quality: 0..100 */ ) { /* Dat: this supports only the Gray and RGB color spaces of JPEG */ param_assert(Colors==1 || Colors==3); param_assert(/* quality>=0 && */ quality <=100); SimBuffer::B fp("<>/DCTEncode").term0(); /* Dat: the default of /ColorTransform (defined in DCTEncode in subsubsection 3.13.3 in PLRM.pdf) is just perfect. */ PSEncoder *ret=new CjpegEncode(out_, fp(), Columns, Rows, Colors==3, quality); // ret->longname=ret->shortname="DCT"; ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newDCTEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char quality, /*libJPEG quality: 0..100 */ unsigned char const*HSamples, /*all 1..4, NULLP OK*/ unsigned char const*VSamples, /*all 1..4, NULLP OK*/ unsigned char (*QuantTables)[64], /*NULLP OK*/ double QFactor, /*0..1000000*/ unsigned numHuffTables, unsigned char **HuffTables, /*NULLP OK*/ unsigned char ColorTransform /*0,1,2 3=default*/ ) { (void)quality; (void)QuantTables; (void)QFactor; (void)numHuffTables; (void)HuffTables; SimBuffer::B tmp; /* Imp: respect quality */ /* Imp: respect QFactor (double) */ /* Imp: respect QuantTables */ /* Imp: respect numHuffTables, HuffTables */ SimBuffer::B fp("<<"); fp << "/Columns " << Columns << "/Rows " << Rows << "/Colors " << (unsigned)Colors; if (HSamples!=(unsigned char const*)NULLP) { tmp.clear(); tmp.vi_write((char const*)HSamples, (unsigned)Colors); fp << "/HSamples "; fp.appendDumpPS(tmp,true); } if (VSamples!=(unsigned char const*)NULLP) { tmp.clear(); tmp.vi_write((char const*)VSamples, (unsigned)Colors); fp << "/VSamples "; fp.appendDumpPS(tmp,true); } if (ColorTransform!=3) fp << "/ColorTransform " << (unsigned)ColorTransform; (fp << ">>/DCTEncode").term0(); // PSEncoder *ret=new DCTEncode(out_,? ? ?); PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="DCT"; ret->longname="DCT"; // ret->filter_psname << fp; return ret; } PSEncoder* PSEncoder::newDCTEncode(GenBuffer::Writable &out_, slen_t Columns, slen_t Rows, unsigned char Colors, /*1..4*/ unsigned char ColorTransform, /*0,1,2 3=default*/ SimBuffer::Flat const& other_parameters ) { SimBuffer::B fp("<<"); fp << "/Columns " << Columns << "/Rows " << Rows << "/Colors " << (unsigned)Colors; if (ColorTransform!=3) fp << "/ColorTransform " << (unsigned)ColorTransform; (fp << other_parameters << ">>/DCTEncode").term0(); PSEncoder *ret=new GSEncode(out_, fp()); // ret->shortname="DCT"; ret->longname="DCT"; // ret->filter_psname << fp; return ret; } /* --- */ TIFFPredictor2::TIFFPredictor2(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : h(0), bpc(bpc_), cpp(cpp_), out(out_) { param_assert(cpp_*bpc_<=32); rlen=(columns_*cpp_*bpc_+7)>>3; /* BUGFIX at Tue Mar 12 12:09:51 CET 2002 */ op=obuf=new unsigned char[rlen]; } void TIFFPredictor2::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; slen_t opleft=rlen-(op-obuf); register unsigned int i, d, o, bpccpp; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] obuf; obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } bpccpp=(cpp-1)*bpc; if (bpc==1) { while (p!=pend0) { i=*p++; d=(i>>7); o =((d-((h>>bpccpp)))&1)<<7; h=(h<<1)|d; d=(i>>6); o|=((d-((h>>bpccpp)))&1)<<6; h=(h<<1)|d; d=(i>>5); o|=((d-((h>>bpccpp)))&1)<<5; h=(h<<1)|d; d=(i>>4); o|=((d-((h>>bpccpp)))&1)<<4; h=(h<<1)|d; d=(i>>3); o|=((d-((h>>bpccpp)))&1)<<3; h=(h<<1)|d; d=(i>>2); o|=((d-((h>>bpccpp)))&1)<<2; h=(h<<1)|d; d=(i>>1); o|=((d-((h>>bpccpp)))&1)<<1; h=(h<<1)|d; d=(i ); o|=((d-((h>>bpccpp)))&1) ; h=(h<<1)|d; *op++=o; if (--opleft==0) { h=0; out.vi_write((char*)obuf,rlen); op=obuf; opleft=rlen; } } } else if (bpc==2) { while (p!=pend0) { i=*p++; d=(i>>6); o =((d-((h>>bpccpp)))&3)<<6; h=(h<<2)|d; // fprintf(stderr,"d=%#x\n", d); d=(i>>4); o|=((d-((h>>bpccpp)))&3)<<4; h=(h<<2)|d; d=(i>>2); o|=((d-((h>>bpccpp)))&3)<<2; h=(h<<2)|d; d=(i ); o|=((d-((h>>bpccpp)))&3) ; h=(h<<2)|d; *op++=o; if (--opleft==0) { h=0; out.vi_write((char*)obuf,rlen); op=obuf; opleft=rlen; } } } else if (bpc==4) { while (p!=pend0) { i=*p++; d=(i>>4); o =((d-((h>>bpccpp)))&15)<<4; h=(h<<4)|d; d=(i ); o|=((d-((h>>bpccpp)))&15) ; h=(h<<4)|d; *op++=o; if (--opleft==0) { h=0; out.vi_write((char*)obuf,rlen); op=obuf; opleft=rlen; } } } else if (bpc==8) { while (p!=pend0) { i=*p++; *op++=((i-((h>>bpccpp)))/*&255*/); h=(h<<8)|i; if (--opleft==0) { h=0; out.vi_write((char*)obuf,rlen); op=obuf; opleft=rlen; } } } else assert(0); } /* --- */ PNGPredictorNone::PNGPredictorNone(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : opleft(0), out(out_) { rlen=(columns_*cpp_*bpc_+7)>>3; } void PNGPredictorNone::vi_write(char const*buf, slen_t len) { if (len==0) { assert(opleft==0); /* unflushed (half-ready) row disallowed */ out.vi_write(0,0); return; } /* The following code just inserts a '\0' in front of each scanline */ /* Imp: make it faster by collapsing vi_writes */ if (opleft==0) { opleft=rlen; out.vi_write("\0",1); } /* Scanline (row) header: describes predictor used */ while (len>opleft) { out.vi_write(buf,opleft); buf+=opleft; len-=opleft; opleft=rlen; out.vi_write("\0",1); /* Scanline (row) header: describes predictor used */ } if (len!=0) out.vi_write(buf,len); opleft-=len; } /* --- */ PNGPredictorSub::PNGPredictorSub(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : h(0), out(out_) { param_assert(cpp_*bpc_<=32); rlen=(columns_*cpp_*bpc_+7)>>3; op=obuf=1+new unsigned char[rlen+1]; obuf[-1]='\1'; /* Scanline (row) header: describes predictor used */ bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorSub::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; slen_t opleft=rlen-(op-obuf); register unsigned int i; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] (obuf-1); obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } while (p!=pend0) { i=*p++; *op++=((i-((h>>bpccpp)))/*&255*/); h=(h<<8)|i; if (--opleft==0) { h=0; out.vi_write((char*)obuf-1,rlen+1); op=obuf; opleft=rlen; } } } /* --- */ PNGPredictorUp::PNGPredictorUp(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : out(out_) { rlen=(columns_*cpp_*bpc_+7)>>3; // fprintf(stderr, "rUp.rlen=%u cpp=%u bpc=%u\n", rlen, cpp_, bpc_); op=obuf=1+new unsigned char[2*rlen+1]; oq=op+rlen; /* prev scanline */ memset(oq, '\0', rlen); obuf[-1]='\2'; /* Scanline (row) header: describes predictor used */ } void PNGPredictorUp::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; slen_t opleft=rlen-(op-obuf); if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] (obuf-1); obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } while (p!=pend0) { *op++=((*p-*oq)/*&255*/); *oq++=*p++; if (--opleft==0) { out.vi_write((char*)obuf-1,rlen+1); opleft=rlen; op=obuf; oq=obuf+rlen; } } } /* --- */ PNGPredictorAverage::PNGPredictorAverage(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : h(0), /*g(0),*/ out(out_) { param_assert(cpp_*bpc_<=32); rlen=(columns_*cpp_*bpc_+7)>>3; op=obuf=1+new unsigned char[2*rlen+1]; oq=op+rlen; /* prev scanline */ memset(oq, '\0', rlen); obuf[-1]='\3'; /* Scanline (row) header: describes predictor used */ bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorAverage::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; slen_t opleft=rlen-(op-obuf); register unsigned int i; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] (obuf-1); obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } while (p!=pend0) { /* vvv Data: *og+h can be 0..510 */ i=*p; *op++=i-((((h>>bpccpp)&255)+*oq)>>1); h=(h<<8)|i; *oq++=*p++; // i=*p; *op++=(*p-((*oq+h)>>1)/*&255*/); h=i; *oq++=*p++; if (--opleft==0) { out.vi_write((char*)obuf-1,rlen+1); opleft=rlen; op=obuf; oq=obuf+rlen; h=0; } } } /* --- */ /* Dat: egcs-2.91.60 is buggy */ // static inline unsigned abs_(unsigned i) { return ((signed)i)<0 ? -i : i; } static inline unsigned abs_(unsigned i) { return ((signed)i)<0 ? (i*-1) : i; } static inline unsigned paeth_predictor(unsigned a, unsigned b, unsigned c) { /* Code ripped from RFC 2083 (PNG specification), which also says: * The calculations within the PaethPredictor function must be * performed exactly, without overflow. Arithmetic modulo 256 is to * be used only for the final step of subtracting the function result * from the target byte value. */ /* a = left, b = above, c = upper left */ unsigned p = a + b - c; /* initial estimate */ unsigned pa = abs_(p - a); /* distances to a, b, c */ unsigned pb = abs_(p - b); unsigned pc = abs_(p - c); // assert(abs_(3*(-1))==3); // fprintf(stderr, "b=%u c=%u %d %d\n", b, c, p-b, ((signed)(p-b))<0 ? (b-p) : (p-b) ); // fprintf(stderr, "pa=%u pb=%u pc=%u\n", pa, pb, pc); assert(pa<=255); assert(pb<=255); assert(pc<=255*2); /* return nearest of a,b,c, breaking ties in order a,b,c. */ return (pa <= pb && pa <= pc) ? a : pb <= pc ? b : c; } PNGPredictorPaeth::PNGPredictorPaeth(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : h(0), g(0), out(out_) { param_assert(cpp_*bpc_<=32); rlen=(columns_*cpp_*bpc_+7)>>3; op=obuf=1+new unsigned char[2*rlen+2]; oq=obuf+rlen+1; /* prev scanline */ memset(obuf+rlen, '\0', rlen+1); obuf[-1]='\4'; /* Scanline (row) header: describes predictor used */ bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorPaeth::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; slen_t opleft=rlen-(op-obuf); register unsigned int i; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] (obuf-1); obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } while (p!=pend0) { // assert(0==obuf[rlen] && 4==obuf[-1]); i=*p; *op++=i-paeth_predictor((h>>bpccpp)&255, *oq, (g>>bpccpp)&255); h=(h<<8)|i; g=(g<<8)|*oq; *oq++=*p++; // i=*p; *op++=i-h; h=i; *oq++=*p++; if (--opleft==0) { out.vi_write((char*)obuf-1,rlen+1); opleft=rlen; op=obuf; oq=obuf+rlen+1; h=0; g=0; } } } /* --- */ #if SIZEOF_INT >= 4 typedef int weight_t; #else typedef long weight_t; #endif PNGPredictorAutoBadSigned::PNGPredictorAutoBadSigned(GenBuffer::Writable &out_, unsigned char bpc_, slen_t columns_, unsigned char cpp_) : h(0), g(0), out(out_) { param_assert(cpp_*bpc_<=32); opleft=rlen=(columns_*cpp_*bpc_+7)>>3; obuf=new unsigned char[6*rlen+6]; o_prior=obuf+rlen+1; /* Prior(x): ooprior[-opleft] */ obuf[rlen*1+1]='\0'; o_0=obuf+2*rlen+2; obuf[rlen*2+2]='\1'; o_1=obuf+3*rlen+3; obuf[rlen*3+3]='\2'; o_2=obuf+4*rlen+4; obuf[rlen*4+4]='\3'; o_3=obuf+5*rlen+5; obuf[rlen*5+5]='\4'; o_4=obuf+6*rlen+6; oo[0]=o_0; oo[1]=o_1; oo[2]=o_2; oo[3]=o_3; oo[4]=o_4; memset(obuf, '\0', rlen+1); bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorAutoBadSigned::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; register unsigned int i; register unsigned raw_x_bpp, prior_x, prior_x_bpp; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] obuf; obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } while (p!=pend0) { raw_x_bpp=(h>>bpccpp) &255; prior_x=*(o_prior-opleft); prior_x_bpp=(g>>bpccpp) &255; i=*p; *(o_0-opleft)=i; *(o_1-opleft)=i-raw_x_bpp; *(o_2-opleft)=i-prior_x; *(o_3-opleft)=i-((raw_x_bpp+prior_x)>>1); *(o_4-opleft)=i-paeth_predictor(raw_x_bpp, prior_x, prior_x_bpp); h=(h<<8)|i; g=(g<<8)|*(o_prior-opleft); *(o_prior-opleft)=*p++; if (--opleft==0) { /* Select the predictor having the smallest signed sum of values. */ weight_t min_weight, cur_weight; unsigned min_pred=0, cur_pred; register signed char *beg, *end; min_weight=0; beg=(end=(signed char*)o_0)-rlen; while (beg!=end) min_weight+=*beg++; if (min_weight<0) min_weight*=-1; for (cur_pred=1; cur_pred<=4; cur_pred++) { cur_weight=0; beg=(end=(signed char*)oo[cur_pred])-rlen; while (beg!=end) cur_weight+=*beg++; if (cur_weight<0) cur_weight*=-1; if (cur_weight>3; obuf=new unsigned char[6*rlen+6]; o_prior=obuf+rlen+1; /* Prior(x): ooprior[-opleft] */ obuf[rlen*1+1]='\0'; o_0=obuf+2*rlen+2; obuf[rlen*2+2]='\1'; o_1=obuf+3*rlen+3; obuf[rlen*3+3]='\2'; o_2=obuf+4*rlen+4; obuf[rlen*4+4]='\3'; o_3=obuf+5*rlen+5; obuf[rlen*5+5]='\4'; o_4=obuf+6*rlen+6; oo[0]=o_0; oo[1]=o_1; oo[2]=o_2; oo[3]=o_3; oo[4]=o_4; memset(obuf, '\0', rlen+1); bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorAutoBadUnsigned::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; register unsigned int i; register unsigned raw_x_bpp, prior_x, prior_x_bpp; // unsigned lines=0; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] obuf; obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } // fprintf(stderr, "rlen=%u len=%u opleft=%u\n", rlen, len, opleft); while (p!=pend0) { raw_x_bpp=(h>>bpccpp) &255; prior_x=*(o_prior-opleft); prior_x_bpp=(g>>bpccpp) &255; i=*p; *(o_0-opleft)=i; *(o_1-opleft)=i-raw_x_bpp; *(o_2-opleft)=i-prior_x; *(o_3-opleft)=i-((raw_x_bpp+prior_x)>>1); *(o_4-opleft)=i-paeth_predictor(raw_x_bpp, prior_x, prior_x_bpp); h=(h<<8)|i; g=(g<<8)|*(o_prior-opleft); *(o_prior-opleft)=*p++; if (--opleft==0) { /* Select the predictor having the smallest unsigned sum of values. */ weight_t min_weight, cur_weight; unsigned min_pred=0, cur_pred; register unsigned char *beg, *end; min_weight=0; beg=(end=(unsigned char*)o_0)-rlen; while (beg!=end) min_weight+=*beg++; for (cur_pred=1; cur_pred<=4; cur_pred++) { cur_weight=0; beg=(end=(unsigned char*)oo[cur_pred])-rlen; while (beg!=end) cur_weight+=*beg++; if (cur_weight>3; obuf=new unsigned char[6*rlen+6]; o_prior=obuf+rlen+1; /* Prior(x): ooprior[-opleft] */ obuf[rlen*1+1]='\0'; o_0=obuf+2*rlen+2; obuf[rlen*2+2]='\1'; o_1=obuf+3*rlen+3; obuf[rlen*3+3]='\2'; o_2=obuf+4*rlen+4; obuf[rlen*4+4]='\3'; o_3=obuf+5*rlen+5; obuf[rlen*5+5]='\4'; o_4=obuf+6*rlen+6; oo[0]=o_0; oo[1]=o_1; oo[2]=o_2; oo[3]=o_3; oo[4]=o_4; memset(obuf, '\0', rlen+1); bpccpp=((cpp_*bpc_+7)&~7)-8; } void PNGPredictorAuto::vi_write(char const*buf, slen_t len) { unsigned char const *p=(unsigned char const*)buf, *pend0=p+len; register unsigned int i; register unsigned raw_x_bpp, prior_x, prior_x_bpp; // unsigned lines=0; if (len==0) { assert(opleft==rlen); /* unflushed (half-ready) row disallowed */ assert(obuf!=NULLP); delete [] obuf; obuf=(unsigned char*)NULLP; out.vi_write(0,0); return; } // fprintf(stderr, "rlen=%u len=%u opleft=%u\n", rlen, len, opleft); while (p!=pend0) { raw_x_bpp=(h>>bpccpp) &255; prior_x=*(o_prior-opleft); prior_x_bpp=(g>>bpccpp) &255; i=*p; *(o_0-opleft)=i; *(o_1-opleft)=i-raw_x_bpp; *(o_2-opleft)=i-prior_x; *(o_3-opleft)=i-((raw_x_bpp+prior_x)>>1); *(o_4-opleft)=i-paeth_predictor(raw_x_bpp, prior_x, prior_x_bpp); h=(h<<8)|i; g=(g<<8)|*(o_prior-opleft); *(o_prior-opleft)=*p++; if (--opleft==0) { /* Select the predictor having the smallest unsigned sum of values. */ weight_t min_weight, cur_weight; unsigned min_pred=0, cur_pred; register signed char *beg, *end; /* abs_(...) here converts '\xFF' to 1. Good. */ min_weight=0; beg=(end=(signed char*)o_0)-rlen; while (beg!=end) min_weight+=abs_(*beg++); for (cur_pred=1; cur_pred<=4; cur_pred++) { cur_weight=0; beg=(end=(signed char*)oo[cur_pred])-rlen; while (beg!=end) cur_weight+=abs_(*beg++); if (cur_weight #include /* exit() */ #include /* strlen() */ #if _MSC_VER > 1000 # include "windows.h" /* ExitThread() */ #endif char const* Error::argv0=(char const*)NULLP; char const* Error::long_argv0=(char const*)NULLP; char const* Error::banner0=(char const*)NULLP; char const* Error::tmpargv0=(char const*)"pRg_tMp"; static Filter::NullE devNull; Files::FILEW serr_default(stderr); GenBuffer::Writable * Error::serr = &serr_default; static Error::Policy defaultPolicy={ (SimBuffer::B*)NULLP, /* record */ (Error::level_t)-9999, /* topSecret */ (Error::level_t)-9999, /* topRecorded */ (Error::level_t)0, /* killer (level>=0) */ (Error::level_t)-99, /* printed */ (Error::level_t)-199, /* recorded */ Error::serr, /* err */ (Error::Policy*)NULLP, /* prev */ (Error::Policy*)NULLP, /* next */ (Error::level_t)-9999, /* curlev */ }; Error::Policy *Error::policy_top=&defaultPolicy, *Error::policy_bottom=&defaultPolicy; char const*Error::level2str(level_t level) { return level==ASSERT ? "failed_assertion" : /* Imp: make assert() produce this */ level==FATAL ? "Fatal Error" : level==ERROR_CONT ? "Error" : level==EERROR ? "Error" : level==WARNING_DEFER ? "Warning" : level==WARNING ? "Warning" : level==NOTICE ? "Notice" : level==NOTICE_DEFER ? "Notice" : level==INFO ? "Info" : level==DEBUG ? "DEBUG" : "??level" ; } GenBuffer::Writable& Error::sev(level_t level) { /* So they are trying to make an error? Let's see whether they can. */ GenBuffer::Writable *err=policy_top->err; // printf("curlev=%d\n", policy_top->curlev); assert(policy_top->curlev==-9999 && "nested error/ unfinished prev err"); policy_top->curlev=level; /* printf("level=%d\n", level); */ if (level>=policy_top->printed) { /* printed or killer */ #if 0 /* Disables printing of "using template: " */ /* vvv Delay printing this message after all recorded messages */ if (policy_top->record!=NULLP) err=policy_top->record; #endif } else if (level>=policy_top->recorded) { /* recorded */ if (NULLP==(err=policy_top->record)) err=policy_top->record=new SimBuffer::B(); if (level>policy_top->topRecorded) policy_top->topRecorded=level; } else { /* secret */ if (level>policy_top->topSecret) policy_top->topSecret=level; return devNull; } return *err << (argv0==(char const*)NULLP?"??argv0":argv0) << ": " << level2str(level) << ": "; /* Processing will continue soon by GenBuffer::Writable& operator <<(GenBuffer::Writable& gb,Error*) */ } GenBuffer::Writable& operator <<(GenBuffer::Writable& err,Error*) { err << '\n'; Error::level_t level=Error::policy_top->curlev; if (level>=Error::policy_top->killer) { /* killer */ /* Also print recorded messages throughout the the policy stack */ Error::Policy *p=Error::policy_bottom; while (p!=NULLP) { if (NULLP!=p->record) Error::policy_top->err->vi_write(p->record->begin_(), p->record->getLength()); p=p->next; } // if (level>=Error::policy_top->killer) Error::cexit(level); } /* Note that the order of error messages might be scrambled, i.e `printed' * is printed before `recorded'. */ Error::policy_top->curlev=(Error::level_t)-9999; /* pedantic but useless because of nesting */ return err; } void Error::pushPolicy(level_t killer_, level_t printed_, level_t recorded_, GenBuffer::Writable *err) { Policy *p=new Policy(); p->record=(SimBuffer::B*)NULLP; p->topSecret=p->topRecorded=(Error::level_t)-9999; p->killer=killer_; p->printed=printed_; p->recorded=recorded_; p->err=(err==NULLP) ? policy_top->err : err; p->prev=policy_top; p->next=(Policy*)NULLP; policy_top=p->prev->next=p; p->curlev=(Error::level_t)-9999; /* pedantic but useless because of nesting */ } SimBuffer::B *Error::getRecorded() { SimBuffer::B *ret=policy_top->record; policy_top->record=(SimBuffer::B*)NULLP; return ret; } void Error::setTopPrinted(level_t printed_) { policy_top->printed=printed_; } Error::level_t Error::getTopPrinted() { return policy_top->printed; } void Error::popPolicy() { if (policy_top==policy_bottom) { Error::sev(Error::ASSERT) << "popPolicy: underflow" << (Error*)0; } else { if (NULLP!=policy_top->record) { (*Error::policy_top->err) << "-- recorded messages:\n"; Error::policy_top->err->vi_write(policy_top->record->begin_(), policy_top->record->getLength()); delete policy_top->record; } policy_top=policy_top->prev; delete policy_top->next; policy_top->next=(Policy*)NULLP; } } /* --- */ Error::Cleanup *Error::first_cleanup=(Error::Cleanup*)NULLP; int Error::runCleanups(int exitCode) { /* Flush buffered messages and revert to the default policy so subsequent * errors can be logged. */ while (policy_top != policy_bottom) popPolicy(); Cleanup *next; int exit2; while (first_cleanup!=NULLP) { // fprintf(stderr, "hand %p\n", first_cleanup); if (exitCode<(exit2=first_cleanup->handler(first_cleanup))) exitCode=exit2; next=first_cleanup->next; delete [] (char*)first_cleanup; /* Allocated from as an array, but has no destructors. */ first_cleanup=next; } return exitCode; } void Error::cexit(int exitCode) { #if _MSC_VER > 1000 ExitThread(exitCode); #else exit(exitCode); /* */ #endif } Error::Cleanup* Error::newCleanup(Error::Cleanup::handler_t handler, void *data, slen_t size) { param_assert(handler!=0); // slen_t num_packets=(size+sizeof(Cleanup)-1)/sizeof(Cleanup); Cleanup *new_=(Cleanup*)new char[size+sizeof(Cleanup)]; /* new Cleanup[1+num_packets]; */ /* ^^^ should be a new Cleanup + new char[size]; now we can avoid alignment * problems */ new_->handler=handler; new_->size=size; new_->data=data; new_->next=first_cleanup; first_cleanup=new_; return new_; } Error::Cleanup* Error::newCleanup(Error::Cleanup::handler_t handler, void *data, char const*cstr) { slen_t slen1=strlen(cstr)+1; Cleanup *new_=newCleanup(handler, data, slen1+1); memcpy(new_->getBuf(), cstr, slen1); return new_; } /* __END__ */ sam2p-0.49.2/image.cpp0000644000175100017510000020206212212351433012614 0ustar ptspts/* * image.cpp (formerly sampled.cpp) * by pts@fazekas.hu at Wed Feb 27 09:26:05 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #include /* strlen() */ #include "gensio.hpp" /* --- 4-byte hashing */ #if SIZEOF_INT>=4 typedef unsigned int u32_t; typedef signed int s32_t; #else typedef unsigned long u32_t; typedef signed long s32_t; #endif /* vvv Dat: moved these out of Hash46 to pacify VC6.0 */ const unsigned M=1409; /** Number of _value_ data bytes (they are not hashed) */ const unsigned D=2; /** Size of each tuple in the array `t' */ const unsigned HD=4+D; /** A tuple is considered free iff its first byte equals FREE */ const unsigned char FREE=255; /** * M=1409 * h(K)=K%1409 * h(i,K)=-i*(1+(K%1408)) (i in 0..1408) * K=[a,r,g,b]=(a<<24)+(r<<16)+(g<<8)+b (4 bytes) * h(K)=(253*a+722*r+(g<<8)+b)%1409 * h(i,K)=-i*(1+(896*a+768*r+(g<<8)+b)%1408) * * -- No dynamic growing or re-hashing. Useful for hashing colormap palettes * with a maximum size of 256. * -- Deleting not supported. * * Implementation: Use 32 bit integers for calculation. * * Imp: remove unused attr `size' */ class Hash46 { public: /** Creates an empty hash. */ Hash46(); inline unsigned getSize() const { return size; } inline unsigned getLength() const { return size; } inline unsigned getMaxSize() const { return M; } inline bool isFull() const { return size==M; } /** @return NULLP or the pointer to a tuple */ inline unsigned char* lookup(unsigned char k[4]) { unsigned char *ret=walk(k); return ret==NULLP || *ret==FREE ? (unsigned char*)NULLP : ret; } /** Can be called only if !isFull() * @return NULL if isFull() and not found; otherwise: pointer to the tuple * found or the place to which the insert can take place. */ unsigned char* walk(unsigned char k[4]); protected: /** Number of non-free tuples in the hash. */ unsigned size; unsigned char t[M*HD]; }; Hash46::Hash46(): size(0) { memset(t, FREE, sizeof(t)); } unsigned char *Hash46::walk(unsigned char k[4]) { u32_t hk, hik; hk=HD*(((((u32_t)1<<24)%M)*k[0]+(((u32_t)1<<16)%M)*k[1]+ (((u32_t)1<< 8)%M)*k[2]+k[3])%M); hik=HD*(1+((((u32_t)1<<24)%(M-1))*k[0]+(((u32_t)1<<16)%(M-1))*k[1]+ (((u32_t)1<< 8)%(M-1))*k[2]+k[3])%(M-1)); /* fprintf(stderr, "hk=%u hik=%u\n", hk, hik); */ register unsigned char *p=t+hk; unsigned i=M; /* fprintf(stderr, "?? %02x %02x %02x %02x\n", k[0], k[1], k[2], k[3]); */ do { /* fprintf(stderr, "examining %02x %02x %02x %02x %d\n", p[0], p[1], p[2], p[3], (k[0]=p[0] && k[1]==p[1] && k[2]==p[2])); */ if (*p==FREE || (k[0]==p[0] && k[1]==p[1] && k[2]==p[2] && k[3]==p[3])) return p; /* ^^^ huge == BUGFIX at Sun Apr 14 00:16:59 CEST 2002 */ if (hk>=hik) { hk-=hik; p-=hik; } else { hk+=M*HD-hik; p+=M*HD-hik; } } while (--i!=0); /* fprintf(stderr, "full\n"); */ return (unsigned char*)NULLP; } /* --- */ const unsigned char Image::Sampled::cs2cpp[6]= { 0, 1, 3, 3, 4, 4 }; char const *Image::Sampled::cs2devcs(unsigned char cs) { static const char *names[]={ (char*)NULLP, "Gray", "RGB", "RGB", "CMYK", "CMYK" }; return cs>=1 && cs<=5 ? names[cs] : (char*)NULLP; } void Image::Sampled::init(slen_t l_comment, slen_t l_header, dimen_t wd_, dimen_t ht_, /* ^^^ 24 is required for /Transparent in out_tiff_work */ unsigned char bpc_, unsigned char ty_, unsigned char cpp_) { static const slen_t PADDING=24; bpc=bpc_; ty=ty_; wd=wd_; ht=ht_; cpp=cpp_; // pred=1; transpc=0x1000000UL; /* Dat: this means: no transparent color */ rlen=(((rlen_t)bpc_)*cpp_*wd_+7)>>3; beg=new char[len=l_comment+l_header+rlen*ht_+PADDING]; rowbeg=(headp=const_cast(beg)+l_comment)+l_header; trail=const_cast(beg)+len-bpc; } Image::Gray* Image::Sampled::toGray0(unsigned char bpc_) { unsigned char *crow=new unsigned char[wd*3+7*3], *p, *pend; Image::Gray *img=new Image::Gray(wd, ht, bpc_); unsigned char *outp=(unsigned char*)img->getRowbeg(); dimen_t htc; memset(crow+wd*3, '\0', 7*3); /* *3 BUGFIX at Tue Jan 18 17:04:15 CET 2005 */ unsigned i; /* Dat: not optimising for minimal rounding error since caller should ensure * that there is no such error at all. */ if (bpc_==1) { assert(img->getBpc()==1); for (htc=0;htcgetRowbeg(); dimen_t htc; memset(crow+wd*3, '\0', 7); unsigned i; /* Dat: not optimising for minimal rounding error since caller should ensure * that there is no such error at all. */ if (bpc_==1) { for (htc=0;htcgetHeadp(), *outp=(unsigned char*)img->getRowbeg(); unsigned ncols=0; Hash46 h; k[0]=0; for (htc=0;htc=256. */ /* fprintf(stderr, "w=%p\n", w); */ if (*w==/*h.*/FREE) { if (ncols==256) { delete img; delete [] crow; return (Image::Indexed*)NULLP; } /* ^^^ too many colors; cannot convert image to indexed */ memcpy(w,k,4); memcpy(pal,k+1,3); /* fprintf(stderr,"newcol=%02x #%02x%02x%02x\n", k[0], k[1], k[2], k[3]); */ /* fprintf(stderr,"newcol=pal #%02x%02x%02x\n", pal[0], pal[1], pal[2]); */ pal+=3; *outp++=w[4]=ncols++; } else { /* a color that we have already seen */ *outp++=w[4]; } } } img->setNcolsMove(ncols); delete [] crow; /* Now img is ready. The user should call packPal() to make it even tighter. */ return img; } void Image::Sampled::to8mul() { if (bpc==8) return; if (wd==0 || ht==0) { bpc=8; return; } unsigned oldBpc=bpc; slen_t wdcpp=wd*cpp; const char *oldBeg=beg; unsigned char *p=(unsigned char*)rowbeg; bpc=8; rlen=wd; beg=new char[len=rowbeg-oldBeg+rlen*ht+bpc]; headp= const_cast(beg)+(headp-oldBeg); rowbeg=const_cast(beg)+(rowbeg-oldBeg); trail= const_cast(beg)+len-bpc; memcpy(const_cast(beg), oldBeg, rowbeg-beg); unsigned char *to=(unsigned char*)rowbeg, *toend; unsigned int i, j; Image::Sampled::dimen_t htc; if (oldBpc==1) { htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~7); while (to!=toend) { i=*p++; *to++=(i>>7)*255; *to++=((i>>6)&1)*255; *to++=((i>>5)&1)*255; *to++=((i>>4)&1)*255; *to++=((i>>3)&1)*255; *to++=((i>>2)&1)*255; *to++=((i>>1)&1)*255; *to++=( i&1)*255; } if (0!=(j=(wdcpp)&7)) { i=*p; /* No mem overrun, even if (wd&7)==0 */ while (j--!=0) { *to++=(i>>7)*255; i<<=1; } } } } else if (oldBpc==2) { htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~3); while (to!=toend) { i=*p++; *to++=(i>>6)*85; *to++=((i>>4)&3)*85; *to++=((i>>2)&3)*85; *to++=( i&3)*85; } if (0!=(j=(wdcpp)&3)) { i=*p; /* No mem overrun, even if (wd&7)==0 */ while (j--!=0) { *to++=(i>>6)*85; i<<=2; } } } } else if (oldBpc==4) { htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~1); while (to!=toend) { i=*p++; *to++=(i>>4)*17; *to++=( i&15)*17; } if (0!=((wdcpp)&1)) *to++=(*p++>>4)*17; } } else assert(0 && "invalid bpc"); delete [] const_cast(oldBeg); } void Image::Sampled::to8nomul() { if (bpc==8) return; if (wd==0 || ht==0) { bpc=8; return; } unsigned oldBpc=bpc; slen_t wdcpp=wd*cpp; const char *oldBeg=beg; unsigned char *p=(unsigned char*)rowbeg; bpc=8; rlen=wd; beg=new char[len=rowbeg-oldBeg+rlen*ht+bpc]; headp= const_cast(beg)+(headp-oldBeg); rowbeg=const_cast(beg)+(rowbeg-oldBeg); trail= const_cast(beg)+len-bpc; memcpy(const_cast(beg), oldBeg, rowbeg-beg); unsigned char *to=(unsigned char*)rowbeg, *toend; unsigned int i, j; Image::Sampled::dimen_t htc; if (oldBpc==1) { htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~7); while (to!=toend) { i=*p++; *to++=(i>>7); *to++=((i>>6)&1); *to++=((i>>5)&1); *to++=((i>>4)&1); *to++=((i>>3)&1); *to++=((i>>2)&1); *to++=((i>>1)&1); *to++=( i&1); } if (0!=(j=(wdcpp)&7)) { i=*p++; /* No mem overrun, even if (wd&7)==0 */ while (j--!=0) { *to++=(i>>7); i<<=1; } } } } else if (oldBpc==2) { // assert(0); htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~3); while (to!=toend) { i=*p++; *to++=(i>>6); *to++=((i>>4)&3); *to++=((i>>2)&3); *to++=( i&3); } if (0!=(j=(wdcpp)&3)) { i=*p++; // fprintf(stderr,"j=%d\n",j); while (j--!=0) { *to++=(i>>6); i<<=2; } } } assert((slen_t)((char*)to-rowbeg)==(slen_t)wd*cpp*ht); } else if (oldBpc==4) { htc=ht; while (htc--!=0) { toend=to+((wdcpp)&~1); while (to!=toend) { i=*p++; *to++=(i>>4); *to++=( i&15); } if (0!=((wdcpp)&1)) *to++=(*p++>>4); } } else assert(0 && "invalid bpc"); delete [] const_cast(oldBeg); } unsigned char Image::Sampled::minRGBBpc() const { unsigned char *crow=new unsigned char[wd*3], *p, *pend=crow+wd*3; register unsigned minbpb=0; dimen_t htc; for (htc=0;htc0xffffffUL) return false; unsigned char *crow=new unsigned char[wd*3], *p, *pend=crow+wd*3, t[3]; dimen_t htc; t[0]=(rgb>>16)&255; t[1]=(rgb>>8)&255; t[2]=rgb&255; for (htc=0;htc0xffffffUL) return false; unsigned char t[3]; t[0]=(rgb>>16)&255; t[1]=(rgb>>8)&255; t[2]=rgb&255; if (t[0]!=t[1] || t[0]!=t[2]) return false; if (bpc==8) { unsigned char *p=(unsigned char*)rowbeg, *pend=p+wd*ht; /* Imp: use memchr() if available */ while (p!=pend && t[0]!=p[0]) p++; return p!=pend; } unsigned char *crow=new unsigned char[wd*3], *p, *pend=crow+wd*3; dimen_t htc; for (htc=0;htcto8(); iimg->packPal(); if ((ncols=iimg->getNcols())==256) Error::sev(Error::EERROR) << "addAlpha: too many colors, transparency impossible" << (Error*)0; iimg->setNcolsMove(ncols+1); /* fprintf(stderr,"old ncols=%u\n", ncols); */ iimg->setPal(ncols,0); /* black */ iimg->setTransp(ncols); assert(iimg->getRlen()==iimg->getWd()); assert(iimg->getWd()==al->getWd()); char *p=iimg->getRowbeg(), *pend=p+iimg->getRlen()*iimg->getHt(), *alq=al->getRowbeg(); while (p!=pend) { if ((unsigned char)*alq++!=255) *p=ncols; /* make it transparent */ p++; } return iimg; } /* --- */ Image::Indexed::Indexed(Image::Sampled::dimen_t wd_, Image::Sampled::dimen_t ht_, unsigned short ncols_, unsigned char bpc_) { param_assert(ncols_<=256); /* vvv Dat: `3' is here for an extra palette entry */ init(3,3*ncols_,wd_,ht_,bpc_,TY_INDEXED,1); transp=-1; cs=CS_Indexed_RGB; } void Image::Indexed::setNcols(unsigned short ncols_) { headp=rowbeg-ncols_*3; } void Image::Indexed::setNcolsMove(unsigned short ncols_) { param_assert(ncols_<=256); unsigned ncols=getNcols(); if (ncols_==ncols) return; if (ncols_=(ncols_-ncols)*3) { memmove(rowbeg-ncols_*3, headp, ncols_*3); /* ^^^ *3 BUGFIX at Sun Apr 14 00:50:34 CEST 2002 */ } else { /* Imp: test this routine */ /* Tue Jun 11 16:22:52 CEST 2002 */ assert(ncols_>ncols); const char *oldBeg=beg, *oldHeadp=headp, *oldRowbeg=rowbeg, *oldEnd=beg+len; slen_t delta=(ncols_-ncols)*3; // substr_grow(headp-oldBeg, ncols*3, ncols_*3); /* no such method */ beg=new char[len+delta]; headp= const_cast(beg)+(headp-oldBeg); rowbeg=const_cast(beg)+(rowbeg-oldBeg)+delta; trail= const_cast(beg)+(trail-oldBeg)+delta; assert(beg+(headp-oldBeg)==rowbeg-ncols_*3); /* Dat: this->xoffs is left unchanged */ memcpy(headp, oldHeadp, oldRowbeg-oldHeadp); memcpy(rowbeg, oldRowbeg, oldEnd-oldRowbeg); delete [] const_cast(oldBeg); } headp=rowbeg-ncols_*3; } void Image::Indexed::setPal(unsigned char color, Image::Sampled::rgb_t rgb) { assert(color<(rowbeg-headp)/3); unsigned char *p=(unsigned char*)headp+3*color; *p++=rgb>>16; *p++=rgb>>8; *p=rgb; } void Image::Indexed::setTransp(unsigned char color) { // param_assert(color>=0); /* always */ assert(transp==-1); transp=color; unsigned char *p=(unsigned char*)headp+3*color; transpc=((Image::Sampled::rgb_t)p[0]<<16)+(p[1]<<8)+p[2]; } bool Image::Indexed::setTranspc(rgb_t color) { char t[3]; /** vvv BUGFIX at Sat Jun 15 13:40:30 CEST 2002 */ if (color==0x1000000UL) return transp!=-1; /* no effect */ if (color==transpc) return transp!=-1; /* would not change */ t[0]=color>>16; t[1]=color>>8; t[2]=color; char *p=headp, *pend=rowbeg; while (p!=pend) { /* Examine the palette. */ if (p[0]==t[0] && p[1]==t[1] && p[2]==t[2]) { transpc=color; transp=(p-headp)/3; /* destroy old transparency */ return true; } p+=3; } /* No transparency set this time. Maybe there is an old one; unchanged. */ return transp!=-1; } void Image::Indexed::to8() { to8nomul(); } Image::Indexed* Image::Indexed::toIndexed()/* const*/ { return this; } Image::RGB* Image::Indexed::toRGB(unsigned char bpc_)/* const*/ { return toRGB0(bpc_); } Image::Gray* Image::Indexed::toGray(unsigned char bpc_)/* const*/ { return toGray0(bpc_); } bool Image::Indexed::canGray() const { char *p=headp, *pend=rowbeg, *tp=p+transp*3; /* ignore transparent color at Sat Jun 15 15:18:24 CEST 2002 */ if (transp!=-1 && tp!=pend-3) { while (p!=pend) { /* Examine the palette. */ if (p!=tp && (p[0]!=p[1] || p[1]!=p[2])) return false; /* Found a non-gray color. */ p+=3; } } else { if (transp!=-1 && tp==pend-3) pend-=3; /* both conditions are important */ while (p!=pend) { /* Examine the palette. */ if (p[0]!=p[1] || p[1]!=p[2]) return false; /* Found a non-gray color. */ p+=3; } } return true; } unsigned char Image::Indexed::minRGBBpc() const { unsigned char *p=(unsigned char*)headp, *pend=(unsigned char*)rowbeg; unsigned char *tp=p+transp*3; /* ignore transparent color at Sat Jun 15 15:18:24 CEST 2002 */ register unsigned minbpb=0; while (p!=pend) { /* Examine the palette. */ if (p==tp) { p+=3; continue; } /* ignore transparent color */ if ((*p&15)*17!=*p) return 8; /* 4 bits are not enough */ else if ((*p&3)*85!=*p) minbpb=3; /* 2 bits are not enough */ else if ((*p&1)*255!=*p) minbpb|=1; /* 1 bit is not enough */ p++; } return 1+minbpb; } void Image::Indexed::copyRGBRow(char *to, Image::Sampled::dimen_t whichrow) const { param_assert(whichrow>7); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>6)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>5)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>4)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>3)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>2)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>1)&1); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*( i&1); *to++=*r++; *to++=*r++; *to++=*r++; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=wd&7; while (j--!=0) { r=headp+3*(i>>7); *to++=*r++; *to++=*r++; *to++=*r++; i<<=1; } } else if (bpc==2) { toend-=3*(wd&3); while (to!=toend) { i=*p++; r=headp+3*(i>>6); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>4)&3); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*((i>>2)&3); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*( i&3); *to++=*r++; *to++=*r++; *to++=*r++; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=wd&3; while (j--!=0) { r=headp+3*(i>>6); *to++=*r++; *to++=*r++; *to++=*r++; i<<=2; } } else if (bpc==4) { toend-=3*(wd&1); while (to!=toend) { i=*p++; r=headp+3*(i>>4); *to++=*r++; *to++=*r++; *to++=*r++; r=headp+3*( i&15); *to++=*r++; *to++=*r++; *to++=*r++; } if (0!=(wd&1)) { r=headp+3*(*p>>4); *to++=*r++; *to++=*r++; *to++=*r++; } } else if (bpc==8) { // fprintf(stderr, "p=%u pp=%u ppp=%u\n", p[0], p[1], p[2]); while (to!=toend) { r=headp+3**p++; *to++=*r++; *to++=*r++; *to++=*r++; } } else assert(0 && "invalid bpc"); } void Image::Indexed::packPal() { /* Convert samples, make bpc=8. */ to8(); unsigned oldNcols=getNcols(); unsigned char *p, *pend; assert((rowbeg-headp)%3==0); assert(transp>=-1); assert(transp<(int)oldNcols); if (oldNcols<=1) return; /* Cannot optimize further. */ /* Find unused colors. old2new[c]=(is c used at least once)?1:0 */ unsigned char old2new[256], newpal[768]; memset(old2new, 0, sizeof(old2new)); for (p=(unsigned char*)rowbeg, pend=p+wd*ht; p!=pend; p++) old2new[*p]=1; /* Find and eliminate duplicate colors. Build the new palette in the * beginning of newpal. Use a Hash46 for a quick lookup of colors already * seen. Use the previously computed old2new, but also overwrite it. */ Hash46 h; int newTransp=-1; unsigned char *op=old2new, *opend=op+oldNcols, *w, k[6], *ptransp=(unsigned char*)headp+3*transp; /* ==p-3 if no transparent color */ /* ^^^ headp BUGFIX at Fri Mar 22 18:02:18 CET 2002 */ p=(unsigned char*)headp; // fprintf(stderr, "oldNcols=%d\n", (int)oldNcols); unsigned newNcols=0; while (op!=opend) { // fprintf(stderr, "color=%d %d\n", (int)(op-old2new), p-ptransp); if (0!=*op) { /* Map the color only if it is used in the image. */ // fprintf(stderr, "used=%d\n", (int)(op-old2new)); if (p==ptransp) { k[0]=1; k[1]=k[2]=k[3]=0; newTransp=newNcols; } else { k[0]=0; memcpy(k+1,p,3); } w=h.walk(k); assert(w!=NULL); /* Hash cannot be full since h.M>=256. */ if (*w==/*h.*/FREE) { memcpy(newpal+3*newNcols, p /* k+1 */, 3); /* ^^^ side effect: make the transparent color black */ memcpy(w,k,4); w[4]=newNcols; *op=newNcols++; } else *op=w[4]; } p+=3; op++; } // fprintf(stderr,"newTransp=%d transp=%d\n", newTransp, transp); // assert((newTransp==-1) == (transp==-1)); assert(newTransp==-1 || transp!=-1); /* ^^^ BUGFIX: == not true, because image may have transparency, but no * transparent pixels. */ assert((char*)p==headp+oldNcols*3); if (newNcols==oldNcols && transp==newTransp) { /* Could not change # colors. */ if (transp==-1) goto done; if ((unsigned)transp==oldNcols-1) { setPal(transp, 0); goto done; } } /* Make the transparent color last. */ if (newTransp!=-1 && newTransp!=(int)newNcols-1) { assert(transp!=-1); unsigned newLast=newNcols-1; memcpy(newpal+3*newTransp, newpal+3*newLast, 3); memset(newpal+3*newLast, 0, 3); transpc=0; /* make it black */ for (op=old2new; op!=opend; op++) if (*op==newLast) *op=newTransp; old2new[transp]=newLast; transp=newTransp=newLast; p=newpal+newTransp*3; } /* Update the image. */ for (p=(unsigned char*)rowbeg, pend=p+wd*ht; p!=pend; p++) { assert(*p=4 typedef unsigned short d_t; #elif SIZEOF_INT>=4 typedef unsigned d_t; #else typedef unsigned long d_t; #endif d_t d[256]; unsigned char *p, *pend; for (i = 0, p = (unsigned char*)headp; i < ncols; ++i, p += 3) { d[i] = (d_t)p[0] << 24 | (d_t)p[1] << 16 | (d_t)p[2] << 8 | i; /*printf("c[%d]=0x%08x\n", i, d[i]);*/ } for (i = 1; i < ncols; ++i) { if (d[i] < d[i - 1]) break; } if (i >= ncols) return; /* Palette already sorted. */ /* Heap sort (unstable). Based on Knuth's TAOCP 5.2.3.H . * Although heap sort is unstable, sortPal implements a stable sort, because * the color index (i) is included in the sorted number (d[i]). */ { unsigned k; d_t tmp, *i, *j, *l=d+(ncols>>1), *r=d+ncols-1; while (1) { /* h2: */ k=l-d; if (k!=0) { tmp=*--l; } else { tmp=*r; *r=d[0]; if (--r==d) { d[0]=tmp; break; } k++; } i=j=l; while ((j+=k)<=r) { /* h4: */ k<<=1; if (j= d[i - 1]) && "bug in sorting palette"); old2new[di & 255] = i; *p++ = di >> 24; *p++ = di >> 16; *p++ = di >> 8; } /* Update the image. */ for (p=(unsigned char*)rowbeg, pend=p+wd*ht; p!=pend; p++) { *p=old2new[*p]; } } void Image::Indexed::delete_separated(register Indexed **p) { while (*p!=NULLP) delete *p++; } Image::Indexed **Image::Indexed::separate() { assert(getNcols()>=1); unsigned char ncols1=getNcols()-1; signed nncols=getNcols()-(transp==-1 ? 0 : 1); register unsigned char curcol; Indexed **ret=new Indexed*[nncols+1], **curimg=ret; Image::Sampled::dimen_t htc; assert(cpp==1); slen_t wdcpp=wd/* *cpp*/; register unsigned char *p; char *to, *toend; register unsigned int i; ret[nncols]=(Indexed*)NULLP; to8(); for (curcol=0; curcol<=ncols1; curcol++) { if (transp==(signed int)curcol) continue; curimg[0]=new Indexed(wd, ht, /*ncols:*/2, /*bpc:*/1); memcpy(curimg[0]->headp, headp+3*curcol, 3); /* copy the color value */ curimg[0]->setTransp(1); to=curimg[0]->rowbeg; p=(unsigned char*)rowbeg; htc=ht; while (htc--!=0) { toend=to+((wdcpp+7)>>3); while (to!=toend) { i =(*p++!=curcol)<<7; i|=(*p++!=curcol)<<6; i|=(*p++!=curcol)<<5; i|=(*p++!=curcol)<<4; i|=(*p++!=curcol)<<3; i|=(*p++!=curcol)<<2; i|=(*p++!=curcol)<<1; i|=(*p++!=curcol); *to++=i; } if (0!=(wdcpp&7)) p+=(wdcpp&7)-8; /* negative */ } curimg++; } assert(curimg==ret+nncols); return ret; } Image::Indexed *Image::Indexed::calcAlpha() { /* by pts@fazekas.hu at Tue Jun 4 21:27:29 CEST 2002 */ assert(getNcols()>=1); packPal(); /* removes transparency if no transparent pixel */ if (transp==-1) return (Image::Indexed*)NULLP; to8(); Indexed *ret=new Indexed(wd, ht, /*ncols:*/2, /*bpc:*/1); Image::Sampled::dimen_t htc; assert(cpp==1); slen_t wdcpp=wd/* *cpp*/; register unsigned char *p; char *to, *toend; register unsigned int i, i8, i7; unsigned char transpx=transp; ret->headp[0]=ret->headp[1]=ret->headp[2]='\xFF'; /* white */ ret->headp[3]=ret->headp[4]=ret->headp[5]='\x00'; /* black, transparent */ ret->setTransp(1); to=ret->rowbeg; p=(unsigned char*)rowbeg; assert(transpx!=0); #if 0 printf("tx=%u\n", transpx); printf("%u %u %u\n", headp[0], headp[1], headp[2]); #endif htc=ht; while (htc--!=0) { // putchar('.'); printf("mod=%d\n",(to-ret->rowbeg)%ret->rlen); // assert((to-ret->rowbeg)%ret->rlen==0); toend=to+(wdcpp>>3); /* ((wdcpp+7)>>3)-1; */ /* ^^^ BUGFIX at Tue Sep 17 11:08:46 CEST 2002 */ assert(toend>=to); while (to!=toend) { #if 1 /* add ->pal[0] funcitonality at Sat Jun 15 14:24:25 CEST 2002 */ i=0; i8=256; /* vvv p[-1]=0 BUGFIX at Sun Dec 8 23:21:47 CET 2002 */ while ((i8>>=1)!=0) if (*p++==transpx) { p[-1]=0; i|=i8; } #else i =(*p++==transpx)<<7; i|=(*p++==transpx)<<6; i|=(*p++==transpx)<<5; i|=(*p++==transpx)<<4; i|=(*p++==transpx)<<3; i|=(*p++==transpx)<<2; i|=(*p++==transpx)<<1; i|=(*p++==transpx); #endif *to++=i; } #if 1 /* This works even when p gets modified; this puts fixed 0 pads at EOLs */ if ((wdcpp&7)!=0) { i7=1<<(7-(wdcpp&7)); i8=256; i=0; /* vvv p[-1]=0 BUGFIX at Sun Dec 8 23:21:47 CET 2002 */ while ((i8>>=1)!=i7) if (*p++==transpx) { p[-1]=0; i|=i8; } *to++=i; } #else if (0!=(wdcpp&7)) p+=(wdcpp&7)-8; /* negative */ #endif } assert(ret->rlen==((wd+7)>>3)); /* printf("rlen=%d %d\n", ret->rlen, to-ret->rowbeg); */ assert(to==ret->rowbeg+ht*ret->rlen); return ret; } void Image::Indexed::setBpc(unsigned char bpc_) { unsigned ncols=getNcols(); if (bpc_==0) { if (ncols<=2) bpc_=1; else if (ncols<=4) bpc_=2; else if (ncols<=16) bpc_=4; else bpc_=8; } else { if (bpc_==1) assert(ncols<=2); else if (bpc_==2) assert(ncols<=4); else if (bpc_==4) assert(ncols<=16); else if (bpc_!=8) param_assert(0 && "invalid bpc_"); } // fprintf(stderr, "bpc: %u -> %u\n", bpc, bpc_); if (bpc==bpc_) return; to8(); /* Imp: make the transition without the intermediate 8-bits... */ if (bpc_==8) return; if (ht==0 || wd==0) { bpc=bpc_; return; } const char *oldBeg=beg; unsigned char *p=(unsigned char*)rowbeg; assert(cpp==1); slen_t wdcpp=wd/* *cpp*/; bpc=bpc_; rlen=(((rlen_t)bpc_)*wd+7)>>3; beg=new char[len=rowbeg-oldBeg+rlen*ht+bpc]; headp= const_cast(beg)+(headp-oldBeg); rowbeg=const_cast(beg)+(rowbeg-oldBeg); trail= const_cast(beg)+len-bpc; memcpy(const_cast(beg), oldBeg, rowbeg-beg); unsigned char *to=(unsigned char*)rowbeg, *toend; unsigned int i; Image::Sampled::dimen_t htc; if (bpc_==1) { htc=ht; while (htc--!=0) { toend=to+((wdcpp+7)>>3); while (to!=toend) { i =*p++<<7; i|=*p++<<6; i|=*p++<<5; i|=*p++<<4; i|=*p++<<3; i|=*p++<<2; i|=*p++<<1; i|=*p++; *to++=i; } if (0!=(wdcpp&7)) p+=(wdcpp&7)-8; /* negative */ } } else if (bpc_==2) { htc=ht; while (htc--!=0) { toend=to+((wdcpp+3)>>2); while (to!=toend) { i =*p++<<6; i|=*p++<<4; i|=*p++<<2; i|=*p++; *to++=i; } if (0!=(wdcpp&3)) p+=(wdcpp&3)-4; } } else if (bpc_==4) { htc=ht; while (htc--!=0) { toend=to+((wdcpp+1)>>1); while (to!=toend) { i =*p++<<4; i|=*p++; *to++=i; } if (0!=(wdcpp&1)) p--; } } else assert(0 && "invalid bpc"); delete [] const_cast(oldBeg); } Image::Sampled::rgb_t Image::Indexed::getPal(unsigned char color) const { unsigned char *p=(unsigned char*)headp+3*color; return ((Image::Sampled::rgb_t)p[0]<<16)+(p[1]<<8)+p[2]; } void Image::Indexed::dumpDebug(GenBuffer::Writable& gw) { gw <<"% ncols=" << getNcols() << " rlen=" << rlen << " ht=" << ht << " wd=" << wd << " cpp=" << (unsigned)cpp << " bpc=" << (unsigned)bpc << " transp=" << transp << " transpc=" << (transp==-1?"none":rgb2webhash(getPal(transp))) << " ty=" << (unsigned)ty //<< " pred=" << (unsigned)pred << '\n'; unsigned char *p=(unsigned char*)headp; while (p!=(unsigned char*)rowbeg) { gw << rgb2webhash(((Image::Sampled::rgb_t)p[0]<<16)+(p[1]<<8)+p[2]) << '\n'; p+=3; } gw << '\n'; gw.vi_write(rowbeg,rlen*ht); } Image::Sampled* Image::Indexed::addAlpha(Image::Gray *al) { // Error::sev(Error::WARNING) << "Indexed: alpha channel ignored" << (Error*)0; return this; if (al->getHt()!=ht || al->getWd()!=wd) Error::sev(Error::EERROR) << "addAlpha: image dimension mismatch" << (Error*)0; bool ign_mid=false; unsigned char lightest, darkest; al->to8(); al->calcExtrema(lightest, darkest); if (darkest==255) return this; /* no transparent pixels at all */ to8(); if (transp>=0) { /* Already have a transparent index. Join. */ register char *p=rowbeg; register unsigned char transp_=transp; char *pend=rowbeg+rlen*ht, *alq=al->getRowbeg(); /* Imp: choose an image color instead of black... */ /* Dat: 0..254: transparent, 255: opaque */ while (p!=pend) { if ((unsigned char)(*alq+1)>1) ign_mid=true; /* fprintf(stderr,"alq=%u\n", (unsigned char)*alq); */ if ((unsigned char)*alq++!=255) p[0]=transp_; /* black out transparent-wannabe pixels */ p++; } } else { /* No transparent color yet. */ packPal(); unsigned ncols=getNcols(); char *p=rowbeg, *pend=rowbeg+rlen*ht, *alq=al->getRowbeg(); /* Imp: choose an image color instead of black... */ /* Dat: 0..254: transparent, 255: opaque */ while (p!=pend) { if ((unsigned char)(*alq+1)>1) ign_mid=true; /* fprintf(stderr,"alq=%u\n", (unsigned char)*alq); */ if ((unsigned char)*alq++!=255) p[0]=ncols; /* may set to 0 if ncols==256 */ p++; } if (ncols==256) { /* Try again, probably now we have less colors */ packPal(); if ((ncols=getNcols())==256) Error::sev(Error::EERROR) << "Indexed::addAlpha: too many colors, transparency impossible" << (Error*)0; for (p=rowbeg,alq=al->getRowbeg(); p!=pend; p++) if ((unsigned char)*alq++!=255) *p=ncols; } setNcolsMove(ncols+1); setPal(ncols,0); /* black */ setTransp(ncols); } if (ign_mid) Error::sev(Error::WARNING) << "addAlpha: half-transparent pixels made transparent" << (Error*)0; return this; } void Image::Indexed::makeTranspZero() { if (transp<1) return; /* no transparency or already 0 */ unsigned char oldBpc=bpc; register unsigned char transpch=transp; /* Imp: make this faster by not converting to 8 bits */ if (oldBpc!=8) to8(); /* Update the image. */ register unsigned char *p; unsigned char *pend; for (p=(unsigned char*)rowbeg, pend=p+wd*ht; p!=pend; p++) { if (*p==0) *p=transp; else if (*p==transpch) *p=0; } rgb_t rzero=getPal(0), rtransp=getPal(transp); setPal(transp, rzero); setPal(0, rtransp); transp=0; if (oldBpc!=8) setBpc(oldBpc); } /* --- */ Image::Gray::Gray(Image::Sampled::dimen_t wd_, Image::Sampled::dimen_t ht_, unsigned char bpc_) { init(0,0,wd_,ht_,bpc_,TY_GRAY,1); cs=CS_GRAYSCALE; } void Image::Gray::to8() { to8mul(); } Image::RGB * Image::Gray::toRGB(unsigned char bpc_)/* const*/ { return toRGB0(bpc_); } Image::Gray* Image::Gray::toGray(unsigned char bpc_)/* const*/ { return bpc==bpc_ ? this : toGray0(bpc_); } Image::Indexed* Image::Gray::toIndexed()/* const*/ { Image::Indexed *img=new Image::Indexed(wd, ht, (1<setPal(0,0); img->setPal(1,0xffffffL); } else if (bpc==2) { img->setPal(0,0); img->setPal(1,0x555555L); img->setPal(2,0xaaaaaaL); img->setPal(3,0xffffffL); } else if (bpc==4) { for (i=0,rgb=0;i<16;i++,rgb+=(rgb_t)0x111111L) img->setPal(i,rgb); } else if (bpc==8) { for (i=0,rgb=0;i<256;i++,rgb+=(rgb_t)0x010101L) img->setPal(i,rgb); } memcpy(img->getRowbeg(), rowbeg, beg+len-rowbeg); return img; } bool Image::Gray::canGray() const { return true; } void Image::Gray::copyRGBRow(char *to, Image::Sampled::dimen_t whichrow) const { param_assert(whichrow>7)*255; *to++=k; *to++=k; *to++=k; k=((i>>6)&1)*255; *to++=k; *to++=k; *to++=k; k=((i>>5)&1)*255; *to++=k; *to++=k; *to++=k; k=((i>>4)&1)*255; *to++=k; *to++=k; *to++=k; k=((i>>3)&1)*255; *to++=k; *to++=k; *to++=k; k=((i>>2)&1)*255; *to++=k; *to++=k; *to++=k; k=((i>>1)&1)*255; *to++=k; *to++=k; *to++=k; k=( i&1)*255; *to++=k; *to++=k; *to++=k; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=wd&7; while (j--!=0) { k=(i>>7)*255; *to++=k; *to++=k; *to++=k; i<<=1; } } else if (bpc==2) { toend-=3*(wd&3); while (to!=toend) { i=*p++; k=(i>>6)*85; *to++=k; *to++=k; *to++=k; k=((i>>4)&3)*85; *to++=k; *to++=k; *to++=k; k=((i>>2)&3)*85; *to++=k; *to++=k; *to++=k; k=( i&3)*85; *to++=k; *to++=k; *to++=k; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=wd&3; while (j--!=0) { k=(i>>6)*85; *to++=k; *to++=k; *to++=k; i<<=2; } } else if (bpc==4) { toend-=3*(wd&1); while (to!=toend) { i=*p++; k=(i>>4)*17; *to++=k; *to++=k; *to++=k; k=( i&15)*17; *to++=k; *to++=k; *to++=k; } if (0!=(wd&1)) { k=(*p>>4)*17; *to++=k; *to++=k; *to++=k; } } else if (bpc==8) { while (to!=toend) { *to++=*p; *to++=*p; *to++=*p++; } } else assert(0 && "invalid bpc"); } #if 0 void Image::Gray::setBpc(unsigned char bpc_) { (void)bpc_; assert(0 && "unimplemented"); /* unimplemented */ } #endif Image::Sampled* Image::Gray::addAlpha(Image::Gray *al) { // Error::sev(Error::WARNING) << "Gray: alpha channel ignored" << (Error*)0; return this; if (al->getHt()!=ht || al->getWd()!=wd) Error::sev(Error::EERROR) << "addAlpha: image dimension mismatch" << (Error*)0; bool ign_mid=false; unsigned char lightest, darkest; al->to8(); al->calcExtrema(lightest, darkest); if (darkest==255) return this; /* no transparent pixels at all */ char *p=rowbeg, *pend=rowbeg+rlen*ht, *alq=al->getRowbeg(); /* Imp: choose an image color instead of black... */ /* Dat: 0..254: transparent, 255: opaque */ while (p!=pend) { if ((unsigned char)(*alq+1)>1) ign_mid=true; /* fprintf(stderr,"alq=%u\n", (unsigned char)*alq); */ if ((unsigned char)*alq++!=255) *p=0; /* black out transparent-wannabe pixels */ p++; } if (ign_mid) Error::sev(Error::WARNING) << "addAlpha: half-transparent pixels made transparent" << (Error*)0; return addAlpha0(toIndexed(), al); } void Image::Gray::calcExtrema(unsigned char &lightest, unsigned char &darkest) { to8(); unsigned l=0, d=255, val; char *p=rowbeg, *pend=rowbeg+ht*wd; while (p!=pend) { val=*(unsigned char*)p++; if (val>l) l=val; if (val>7)*255; *to++=k; k=((i>>6)&1)*255; *to++=k; k=((i>>5)&1)*255; *to++=k; k=((i>>4)&1)*255; *to++=k; k=((i>>3)&1)*255; *to++=k; k=((i>>2)&1)*255; *to++=k; k=((i>>1)&1)*255; *to++=k; k=( i&1)*255; *to++=k; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=(wd*3)&7; while (j--!=0) { k=(i>>7)*255; *to++=k; i<<=1; } } else if (bpc==2) { toend-=(wd*3)&3; while (to!=toend) { i=*p++; k=(i>>6)*85; *to++=k; k=((i>>4)&3)*85; *to++=k; k=((i>>2)&3)*85; *to++=k; k=( i&3)*85; *to++=k; } i=*p; /* No mem overrun, even if (wd&7)==0 */ j=(wd*3)&3; while (j--!=0) { k=(i>>6)*85; *to++=k; i<<=2; } } else if (bpc==4) { toend-=(wd*3)&7; while (to!=toend) { i=*p++; k=(i>>4)*17; *to++=k; k=( i&15)*17; *to++=k; } if (0!=((wd*3)&1)) *to++=(*p>>4)*17; } else if (bpc==8) { memcpy(to, p, 3*wd); } else assert(0 && "invalid bpc"); } #if 0 void Image::RGB::setBpc(unsigned char bpc_) { (void)bpc_; assert(0 && "unimplemented"); /* unimplemented */ } #endif Image::Sampled* Image::RGB::addAlpha(Image::Gray *al) { if (al->getHt()!=ht || al->getWd()!=wd) Error::sev(Error::EERROR) << "addAlpha: image dimension mismatch" << (Error*)0; bool ign_mid=false; unsigned char lightest, darkest; al->to8(); al->calcExtrema(lightest, darkest); if (darkest==255) return this; /* no transparent pixels at all */ char *p=rowbeg, *pend=rowbeg+rlen*ht, *alq=al->getRowbeg(); /* Imp: choose an image color instead of black... */ /* Dat: 0..254: transparent, 255: opaque */ while (p!=pend) { if ((unsigned char)(*alq+1)>1) ign_mid=true; /* fprintf(stderr,"alq=%u\n", (unsigned char)*alq); */ if ((unsigned char)*alq++!=255) p[0]=p[1]=p[2]=0; /* black out transparent-wannabe pixels */ p+=3; } if (ign_mid) Error::sev(Error::WARNING) << "addAlpha: half-transparent pixels made transparent" << (Error*)0; return addAlpha0(toIndexed(), al); } /* --- */ char *Image::Sampled::rgb2webhash(rgb_t rgb) { static char tmp[8]; char *p=tmp; *p='#'; *++p='0'+(rgb>>20); if (*p>'9') *p+='a'-'0'-10; *++p='0'+((rgb>>16)&15); if (*p>'9') *p+='a'-'0'-10; *++p='0'+((rgb>>12)&15); if (*p>'9') *p+='a'-'0'-10; *++p='0'+((rgb>>8)&15); if (*p>'9') *p+='a'-'0'-10; *++p='0'+((rgb>>4)&15); if (*p>'9') *p+='a'-'0'-10; *++p='0'+((rgb )&15); if (*p>'9') *p+='a'-'0'-10; *++p='\0'; return tmp; } GenBuffer::Writable& operator<<(GenBuffer::Writable& gw, Image::Sampled const& img) { slen_t buflen=img.getWd()*3; char *buf=new char[buflen]; Image::Sampled::dimen_t y, ht=img.getHt(); /* vvv in the xv program: image file must be >=30 bytes long to be treated as image */ gw << "P6\n###############\n" << img.getWd() << ' ' << ht; if (img.getTranspc()>=0x1000000UL) gw << "\n#Opaque"; else gw << "\n#T" << img.rgb2webhash(img.getTranspc()); gw << "\n255\n"; for (y=0; ynext=first; first=anew; } #if 0 /* removed by code refactoring */ Image::Sampled* Image::load(char const* format, filep_t f_, SimBuffer::Flat const& loadHints) {} /* Removed. */ #endif // #include /* sleep() */ #if 0 Rule::Sampled *Rule::load(char const* filename) { static char buf[2*Applier::MAGIC_LEN]; FILE *f=fopen(filename, "rb"); unsigned got=0; if (f==NULLP) Error::sev(Error::EERROR) << "Cannot open/read image file: " << FNQ(filename) << (Error*)0; slen_t ret=fread(buf, 1, Applier::MAGIC_LEN, f); /* vvv Imp: clarify error message: may be a read error */ if (ret==0) Error::sev(Error::EERROR) << "Zero-length image file: " << FNQ(filename) << (Error*)0; if (retchecker(buf,buf+Applier::MAGIC_LEN))) { return reader(f); } p=p->next; } Error::sev(Error::EERROR) << "Unknown image format: " << FNQ(filename) << (Error*)0; // Error::sev(Error::WARNING) << "Zero-length image1." << (Error*)0; // Error::sev(Error::WARNING) << "Zero-length image2." << (Error*)0; return 0; /*notreached*/ } #endif Image::Sampled *Image::load(Image::Loader::UFD* ufd0, SimBuffer::Flat const& loadHints, char const* format) { Filter::UngetFILED &ufd=*(Filter::UngetFILED*)ufd0; /* Dat: format arg used in in_pnm.cpp */ static char buf[Loader::MAGIC_LEN+1]; slen_t ret=ufd.vi_read(buf, Loader::MAGIC_LEN); /* vvv Imp: clarify error message: may be a read error */ if (ufd.hadError()) Error::sev(Error::EERROR) << "I/O error pre in image file: " << FNQ(ufd.getFilenameDefault("-")) << (Error*)0; if (ret==0) Error::sev(Error::EERROR) << "Zero-length image file: " << FNQ(ufd.getFilenameDefault("-")) << (Error*)0; if (retchecker() uses it yet. */ Loader *p=first; Loader::reader_t reader; ufd.unread(buf, ret); /* tries to seek back, on failure calls ufd.getUnget().vi_write() */ // ^^^ rewind(f); /* checker might have read */ /* ^^^ do this early for the checkers */ while (p!=NULLP) { /* vvv each checker() must rewind ufd for itself */ if ((format==(char const*)NULLP || 0==strcmp(p->format, format)) && (Loader::checker_t)0!=p->checker && (Loader::reader_t)0!=(reader=p->checker(buf,buf+Loader::MAGIC_LEN, loadHints, ufd0)) ) { // fprintf(stderr, "%p %p\n", ufd0, &ufd); return reader(ufd0, loadHints); } p=p->next; } // sleep(1000); Error::sev(Error::EERROR) << "Unknown input image format: " << FNQ(ufd.getFilenameDefault("-")) << (Error*)0; return 0; /*notreached*/ } #if 0 /* not used anywhere, except in test_main. */ Image::Sampled *Image::load(char const* filename, SimBuffer::Flat const& loadHints, filep_t stdin_f, char const* format) { /* Commented out. */ Filter::UngetFILED ufd(filename, stdin_f==NULLP ? stdin : (FILE*)stdin_f, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); return load((Image::Loader::UFD*)&ufd, loadHints, format); // Imp: better error message, something like: if (f==NULLP) Error::sev(Error::EERROR) << "Cannot open/read image file: " << FNQ(filename) << (Error*)0; } #endif #if 0 /* before Sat Apr 19 13:42:04 CEST 2003 */ Image::Sampled *Image::load(char const* filename, SimBuffer::Flat const& loadHints, filep_t stdin_f, char const* format) { /* Dat: format arg used in in_pnm.cpp */ static char buf[2*Loader::MAGIC_LEN]; bool stdin_p=filename[0]=='-' && filename[1]=='\0'; FILE *f=!stdin_p ? fopen(filename, "rb") : stdin_f!=NULLP ? (FILE*)stdin_f : stdin; unsigned got=0; if (f==NULLP) Error::sev(Error::EERROR) << "Cannot open/read image file: " << FNQ(filename) << (Error*)0; slen_t ret=fread(buf, 1, Loader::MAGIC_LEN, f); /* vvv Imp: clarify error message: may be a read error */ if (ret==0) Error::sev(Error::EERROR) << "Zero-length image file: " << FNQ(filename) << (Error*)0; if (retchecker() uses it yet. */ unsigned long pos=fseek(f, 0, SEEK_END); pos=(pos<=Loader::MAGIC_LEN)?0:pos-Loader::MAGIC_LEN; if (0!=fseek(f, pos, SEEK_SET) || (got=fread(buf+Loader::MAGIC_LEN, 1, Loader::MAGIC_LEN, f))==0 #else if (0 #endif || (rewind(f), 0) || ferror(f)) Error::sev(Error::EERROR) << "I/O error pre in image file: " << FNQ(filename) << (Error*)0; if (got!=0 && got!=Loader::MAGIC_LEN) memmove(buf+2*Loader::MAGIC_LEN-got, buf+Loader::MAGIC_LEN, got); Loader *p=first; Loader::reader_t reader; while (p!=NULLP) { if ((format==(char const*)NULLP || 0==strcmp(p->format, format)) && (Loader::checker_t)NULLP!=p->checker && (Loader::reader_t)NULLP!=(reader=p->checker(buf,buf+Loader::MAGIC_LEN, loadHints, f)) ) { rewind(f); /* checker might have read */ Image::Sampled *ret=reader(f, loadHints); if (ferror(f) || (!stdin_p && 0!=fclose(f))) /* don't close stdin */ Error::sev(Error::EERROR) << "I/O error post in image file: " << FNQ(filename) << (Error*)0; return ret; } p=p->next; } Error::sev(Error::EERROR) << "Unknown input image format: " << FNQ(filename) << (Error*)0; // Error::sev(Error::WARNING) << "Zero-length image1." << (Error*)0; // Error::sev(Error::WARNING) << "Zero-length image2." << (Error*)0; return 0; /*notreached*/ } #endif unsigned Image::printLoaders(GenBuffer::Writable &out) { unsigned num=0; Loader *p=first; while (p!=NULLP) { if (p->checker!=(Loader::checker_t)0 && p->format!=(char const*)NULLP) { num++; out << ' ' << p->format; } p=p->next; } return num; } /* --- */ Image::SampledInfo::SampledInfo(Sampled *img_) :hasTransp(false) ,nncols(257) ,canGray(false) ,minRGBBpc(8) ,img(img_) ,imgs((Indexed**)NULLP) { param_assert(img_!=NULLP); Sampled *bak=img; if ((img=img->toIndexed())==NULLP) { img=bak; } else { if (bak!=img) delete bak; assert(img->getTy()==img->TY_INDEXED); Indexed *iimg=PTS_dynamic_cast(Image::Indexed*,img); /* This packPal() contains a call to sortPal(), which converts the indexed * image to canonical form. */ iimg->packPal(); nncols=iimg->getNcols(); if (true==(hasTransp=iimg->hasTransp())) nncols--; } minRGBBpc=img->minRGBBpc(); if ((canGray=img->canGray())==true && nncols==257) nncols=256; sf=(sf_t)((img->getTy()==img->TY_BLACKBOX) ? 0+SF_Asis : 0+SF_None); /* Dat: 0+: pacify gcc-3.1 */ } Image::SampledInfo::~SampledInfo() { delete img; if (imgs!=NULLP) { Image::Indexed::delete_separated(imgs); delete imgs; } } void Image::SampledInfo::separate() { // bool ok; // ASSERT_SIDE(ok=(sf!=SF_Transparent2 && sf!=SF_Transparent4 && sf!=SF_Transparent8)); // if (!ok) return; if (sf!=SF_Transparent2 && sf!=SF_Transparent4 && sf!=SF_Transparent8) return; Indexed *iimg=PTS_dynamic_cast(Indexed*,img); imgs=iimg->separate(); } bool Image::SampledInfo::setSampleFormat(sf_t sf_, bool WarningOK, bool TryOnly, Sampled::rgb_t Transparent) { /* at Sat Jun 15 11:48:51 CEST 2002: added transparency warnings */ /* fprintf(stderr, "sf=%u sf_=%u transparent=0x%lx\n", sf, sf_, Transparent+0UL); */ // assert(sf_==SF_Asis); Indexed *iimg; Sampled *bak=img; param_assert(sf_!=SF_None); param_assert(sf==SF_None || sf==SF_Asis || sf==sf_); if (sf_==sf) return true; /* already converted */ bool zero=img->getWd()==0 || img->getHt()==0; if (sf==SF_Asis && sf_!=SF_Asis && sf_!=SF_Bbox) { Error::sev(Error::WARNING) << "SampleFormat: can't convert image loaded as Asis to other" << (Error*)0; return false; } switch (sf_) { case SF_Bbox: sf=SF_Bbox; return true; case SF_Opaque: if (!hasTransp && nncols==1 && PTS_dynamic_cast(Indexed*,img)->setTranspc(Transparent)) { hasTransp=true; nncols=0; } if (hasTransp || nncols!=1) return false; assert(img->getTy()==img->TY_INDEXED); /* The color can be calculated: PTS_dynamic_cast(Indexed*>(img)->getPal(0); */ /* Conversion is not necessary. */ sf=SF_Opaque; return true; case SF_Transparent: if (!hasTransp && nncols==1 && PTS_dynamic_cast(Indexed*,img)->setTranspc(Transparent)) { hasTransp=true; nncols=0; } if (!hasTransp || nncols!=0) return false; assert(img->getTy()==img->TY_INDEXED); /* Conversion is not necessary. */ sf=SF_Transparent; return true; case SF_Gray1: /* vvv strict hasTransp added at Mon Sep 9 22:53:24 CEST 2002 */ if (nncols>2 || !canGray || minRGBBpc>1 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; /* ^^^ Imp: !! make the hasPixelRFB() check a lot faster (cache results) */ if (TryOnly) return WarningOK || (nncols>=2 && !hasTransp); if (hasTransp) { if (!WarningOK) return false; /* Dat: nncols may be 1 or 2 ! (both transparent and opaque black) */ Error::sev(Error::WARNING) << (nncols<=1 ? "SampleFormat: Mask would be better than " : "SampleFormat: Transparent2 would be better than ") << "Gray1" << (Error*)0; } if (nncols<2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Opaque would be better than Gray1" << (Error*)0; } img=img->toGray(1); if (bak!=img) delete bak; assert(img!=NULLP); assert(img->getBpc()==1); sf=SF_Gray1; return true; case SF_Indexed1: if (nncols>2 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || nncols>=2; if (nncols<2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Opaque would be better than Indexed1" << (Error*)0; } if (canGray && minRGBBpc==1) { Error::sev(Error::NOTICE) << "SampleFormat: Gray1 would be better than Indexed1" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); // img=img->toIndexed(); /* should be a no-op */ // assert(img!=NULLP); if (bak!=img) delete bak; { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(1); if (iimg->setTranspc(Transparent)) return false; /* Dat: false if must be changed to become transparent; Imp: undo changes */ } sf=SF_Indexed1; return true; case SF_Mask: if (!hasTransp && nncols==2 && PTS_dynamic_cast(Indexed*,img)->setTranspc(Transparent)) { hasTransp=true; nncols=1; } if (nncols>1 || zero) return false; if (TryOnly) return WarningOK || nncols+(hasTransp?1:0)==2; if (nncols==1 && !hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Opaque would be better than Mask" << (Error*)0; } if (nncols==0) { assert(hasTransp); Error::sev(Error::WARNING) << "SampleFormat: Transparent would be better than Mask" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(1); if (!iimg->setTranspc(Transparent)) return false; iimg->packPal(); } /* printf("gett=%d\n", PTS_dynamic_cast(Indexed*,img)->getTransp()); */ /* vvv BUGFIX: <1U -> <2U */ assert(PTS_dynamic_cast(Indexed*,img)->getTransp()==-1 || PTS_dynamic_cast(Indexed*,img)->getTransp()+0U<2U); /* ^^^ color 0 is opaque, color 1 is transparent, thanks to * img->packPal() called in SampleInfo() -- but setTranspc may have changed this */ sf=SF_Mask; return true; case SF_Transparent2: if (nncols==4) { (iimg=PTS_dynamic_cast(Indexed*,img))->setTranspc(Transparent); /* Imp: are we Indexed*?? */ hasTransp=iimg->hasTransp(); } if (nncols>3 || zero) return false; if (TryOnly) return WarningOK || (hasTransp && nncols>=2); Error::sev(Error::NOTICE) << "SampleFormat: Transparent2 separates colors" << (Error*)0; if (!hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Indexed2 would be better than Transparent2" << (Error*)0; } if (nncols<2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Mask would be better than Transparent2" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(2); /* BUGFIX at Sat Jun 15 13:55:25 CEST 2002 */ iimg->setTranspc(Transparent); // imgs=iimg->separate(); /* postponed because of GIF89a output */ } sf=SF_Transparent2; return true; case SF_Gray2: if (nncols>4 || !canGray || minRGBBpc>2 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>2 && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << (nncols<=3 ? "SampleFormat: Transparent2 would be better than " : "SampleFormat: Transparent4 would be better than ") << "Gray2" << (Error*)0; } if (nncols<=2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray1 would be better than Gray2" << (Error*)0; } img=img->toGray(2); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Gray2; return true; case SF_Indexed2: if (nncols>4 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || nncols>2; if (nncols<=2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Indexed1 would be better than Indexed2" << (Error*)0; } if (canGray && minRGBBpc<=2) { Error::sev(Error::NOTICE) << "SampleFormat: Gray2 would be better than Indexed2" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(2); if (iimg->setTranspc(Transparent)) return false; } sf=SF_Indexed2; return true; case SF_Transparent4: if (nncols==16) PTS_dynamic_cast(Indexed*,img)->setTranspc(Transparent); if (nncols>15 || zero) return false; if (TryOnly) return WarningOK || (hasTransp && nncols>=4); Error::sev(Error::NOTICE) << "SampleFormat: Transparent4 separates colors" << (Error*)0; if (!hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Indexed4 would be better than Transparent4" << (Error*)0; } if (nncols<4) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Transparent2 would be better than Transparent4" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(4); iimg->setTranspc(Transparent); // imgs=iimg->separate(); /* postponed because of GIF89a output */ } sf=SF_Transparent4; return true; case SF_Rgb1: if (nncols>8 || minRGBBpc>1 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>4 && !canGray && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Transparent4 would be better than " << "Rgb1" << (Error*)0; } if (canGray) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray1 would be better than Rgb1" << (Error*)0; } if (nncols<=4) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: " << (hasTransp ? "Transparent2 may" : "Indexed2 would") << " be better than Rgb1" << (Error*)0; } img=img->toRGB(1); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Rgb1; return true; case SF_Gray4: if (nncols>16 || !canGray || minRGBBpc>4 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; /* ^^^ BUGFIX at Sat Jun 1 18:27:10 CEST 2002 */ if (TryOnly) return WarningOK || (nncols>4 && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << (nncols<=15 ? "SampleFormat: Transparent4 would be better than " : "SampleFormat: Transparent8 may be better than ") << "Gray4" << (Error*)0; } if (nncols<=4) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray2 would be better than Gray4" << (Error*)0; } img=img->toGray(4); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Gray4; return true; case SF_Indexed4: if (nncols>16 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>4 && minRGBBpc>=4); if (nncols<=4) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Indexed2 would be better than Indexed4" << (Error*)0; } if (minRGBBpc<=1) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: RGB1 would be better than Indexed4" << (Error*)0; } if (canGray && minRGBBpc<=4) { if (!WarningOK) return false; Error::sev(Error::NOTICE) << "SampleFormat: Gray4 would be better than Indexed4" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(4); if (iimg->setTranspc(Transparent)) return false; } sf=SF_Indexed4; return true; case SF_Transparent8: if (nncols==256) PTS_dynamic_cast(Indexed*,img)->setTranspc(Transparent); if (nncols>255 || zero) return false; if (!WarningOK) return false; if (TryOnly) return true; Error::sev(Error::WARNING) << "SampleFormat: Transparent8 separates too many colors" << (Error*)0; if (!hasTransp) { Error::sev(Error::WARNING) << "SampleFormat: Indexed8 would be much better than Transparent8" << (Error*)0; } if (nncols<16) { Error::sev(Error::WARNING) << "SampleFormat: Transparent4 would be better than Transparent8" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(8); /* should be a no-op */ iimg->setTranspc(Transparent); // imgs=iimg->separate(); /* postponed because of GIF89a output */ } sf=SF_Transparent8; return true; case SF_Rgb2: if (nncols>64 || minRGBBpc>2 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>16 && !canGray && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Transparent8 would be better than " << "Rgb2" << (Error*)0; } if (canGray) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray2 would be better than Rgb2" << (Error*)0; } if (nncols<=16) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: " << (hasTransp ? "Transparent4 may" : "Indexed4 would") << " be better than Rgb2" << (Error*)0; } img=img->toRGB(2); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Rgb2; return true; case SF_Gray8: if (nncols>256 || !canGray || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>16 && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << (nncols<=255 ? "SampleFormat: Transparent8 may be better than " : "SampleFormat: ignoring transparency for ") << "Gray8" << (Error*)0; } if (minRGBBpc<=4) { /* BUGFIX at Wed Jul 3 01:07:44 CEST 2002 */ if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray4 would be better than Gray8" << (Error*)0; } img=img->toGray(8); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Gray8; return true; case SF_Indexed8: // fprintf(stderr, "nncols=%u hasTransp=%u zero=%u\n", nncols, hasTransp, zero); if (nncols>256 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; // assert(0); if (TryOnly) return WarningOK || (nncols>16 && minRGBBpc>=8); if (nncols<=16) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Indexed4 would be better than Indexed8" << (Error*)0; } if (minRGBBpc<=2) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: RGB2 would be better than Indexed8" << (Error*)0; } if (canGray) { if (!WarningOK) return false; Error::sev(Error::NOTICE) << "SampleFormat: Gray8 would be better than Indexed8" << (Error*)0; } assert(img->getTy()==img->TY_INDEXED); { iimg=PTS_dynamic_cast(Indexed*,img); iimg->setBpc(8); /* should be a no-op */ if (iimg->setTranspc(Transparent)) return false; } sf=SF_Indexed8; return true; case SF_Rgb4: // fprintf(stderr, "minrgbbpc=%d to=%d\n", minRGBBpc, TryOnly); if (minRGBBpc>4 || zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>256 && !canGray && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << (nncols<=255 ? "SampleFormat: Transparent8 may be better than " : "SampleFormat: ignoring transparency for ") << "Rgb4" << (Error*)0; } if (canGray) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray4 would be better than Rgb4" << (Error*)0; } if (nncols<=256) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: " << (hasTransp && nncols<=255 ? "Transparent8 may" : "Indexed8 would") << " be better than Rgb4" << (Error*)0; } img=img->toRGB(4); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Rgb4; return true; case SF_Rgb8: if (zero || hasTransp || img->hasPixelRGB(Transparent)) return false; if (TryOnly) return WarningOK || (nncols>256 && !canGray && minRGBBpc>=8 && !hasTransp); if (hasTransp) { if (!WarningOK) return false; Error::sev(Error::WARNING) << (nncols<=255 ? "SampleFormat: Transparent8 may be better than " : "SampleFormat: ignoring transparency for ") << "Rgb8" << (Error*)0; } if (canGray) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Gray8 would be better than Rgb8" << (Error*)0; } if (minRGBBpc<=4) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: Rgb4 would be better than Rgb8" << (Error*)0; } if (nncols<=256) { if (!WarningOK) return false; Error::sev(Error::WARNING) << "SampleFormat: " << (hasTransp && nncols<=255 ? "Transparent8 may" : "Indexed8 would") << " be better than Rgb8" << (Error*)0; } img=img->toRGB(8); if (bak!=img) delete bak; assert(img!=NULLP); sf=SF_Rgb8; return true; case SF_Asis: if (img->getTy()!=img->TY_BLACKBOX) { Error::sev(Error::WARNING) << "SampleFormat: cannot convert image to /Asis" << (Error*)0; return false; } sf=SF_Asis; return true; } assert(0 && "unknown SampleFormat requested"); return false; /* NOTREACHED */ } /* __END__ */ sam2p-0.49.2/in_bmp.cpp0000644000175100017510000000305512211371426013002 0ustar ptspts/* * in_bmp.cpp -- read a Windows(?) BMP bitmap file * by pts@fazekas.hu at Sat Mar 2 00:46:54 CET 2002 * */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_BMP #include "gensio.hpp" #include "input-bmp.ci" static Image::Sampled *in_bmp_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; bitmap_type bitmap=bmp_load_image(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else assert(0 && "invalid BMP depth"); delete [] BITMAP_BITS(bitmap); return ret; } static Image::Loader::reader_t in_bmp_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (buf[0]=='B' && buf[1]=='M' && buf[6]==0 && buf[7]==0 && buf[8]==0 && buf[9]==0 && (unsigned char)(buf[14])<=64 && buf[15]==0 && buf[16]==0 && buf[17]==0) ? in_bmp_reader : 0; } #else #define in_bmp_checker NULLP #endif /* USE_IN_BMP */ Image::Loader in_bmp_loader = { "BMP", in_bmp_checker, 0 }; sam2p-0.49.2/in_gif.cpp0000644000175100017510000000571512211371426012776 0ustar ptspts/* * in_gif.cpp -- read a Compuserve GIF file * by pts@fazekas.hu at Fri Mar 1 22:28:46 CET 2002 * */ /*The creators of the GIF format require the following acknowledgement: The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated. */ #ifdef __GNUC__ #pragma implementation #endif #define _POSIX_SOURCE 1 #define _POSIX_C_SOURCE 2 #include "config2.h" /* SUXX, ignores features.h */ #if USE_IN_GIF #include "cgif.h" #include "cgif.c" /* _POSIX_SOURCE */ #include "image.hpp" #include "error.hpp" #include "gensio.hpp" #undef CGIFFF #define CGIFFF CGIF:: static Image::Sampled *in_gif_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { Image::Indexed *img; CGIFFF GifFileType *giff; CGIFFF SavedImage *sp; CGIFFF ColorMapObject *cm; char const *err; /* Dat: (CGIFFF GetGifError() || "unknown error") doesn't work like in Perl or Ruby */ if (0==(giff=CGIFFF DGifOpenFILE(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false))) || GIF_ERROR==CGIFFF DGifSlurp(giff)) Error::sev(Error::EERROR) << "GIF: " << ((err=CGIFFF GetGifError()) ? err : "unknown error") << (Error*)0; if (giff->ImageCount<1) Error::sev(Error::EERROR) << "GIF: no image in file" << (Error*)0; sp=giff->SavedImages+0; cm = (sp->ImageDesc.ColorMap ? sp->ImageDesc.ColorMap : giff->SColorMap); img=new Image::Indexed(sp->ImageDesc.Width, sp->ImageDesc.Height, cm->ColorCount, 8); CGIFFF GifColorType *co=cm->Colors, *ce=co+cm->ColorCount; char *p=img->getHeadp(); while (co!=ce) { *p++=(char)co->Red; *p++=(char)co->Green; *p++=(char)co->Blue; co++; } // fprintf(stderr, "transp=%d\n", sp->transp); if (sp->transp!=-1) img->setTransp(sp->transp); /* ^^^ comment out this line to ignore transparency of the GIF file */ assert(1L*sp->ImageDesc.Width*sp->ImageDesc.Height<=img->end_()-img->getRowbeg()); memcpy(img->getRowbeg(), sp->RasterBits, (slen_t)sp->ImageDesc.Width*sp->ImageDesc.Height); CGIFFF DGifCloseFile(giff); /* also frees memory structure */ return img; } static Image::Loader::reader_t in_gif_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (0==memcmp(buf,"GIF87a",6) || 0==memcmp(buf,"GIF89a",6)) ? in_gif_reader : 0; } #define in_gif_name "GIF" #else #include #include "image.hpp" #include "error.hpp" #define in_gif_name (char const*)NULLP /* #define in_gif_checker (Image::Loader::checker_t)NULLP */ static Image::Loader::reader_t in_gif_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { if (0==memcmp(buf,"GIF87a",6) || 0==memcmp(buf,"GIF89a",6)) { Error::sev(Error::WARNING) << "loader: please `configure --enable-gif' for loading GIF files" << (Error*)0; } return 0; } #endif /* USE_IN_GIF */ Image::Loader in_gif_loader = { in_gif_name, in_gif_checker, 0 }; sam2p-0.49.2/in_jai.cpp0000644000175100017510000003214312211371426012767 0ustar ptspts/* * in_jai.cpp -- read a JPEG file as-is * by pts@math.bme.hu at Sun Mar 17 20:15:25 CET 2002 */ /* Imp: test this code with various JPEG files! */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_JAI #include "in_jai.hpp" #include /* memchr() */ #include /* --- */ class JAI: public Image::Sampled { public: /** (Horiz<<4+Vert) sampling factor for the first color component. Usually * 0x11, but TIFF defaults to 0x22. */ JAI(dimen_t wd_, dimen_t ht_, unsigned char bpc_, unsigned char cs_, slen_t flen_, slen_t SOF_offs_, unsigned char hvs_); virtual void copyRGBRow(char *to, dimen_t whichrow) const; virtual void to8(); virtual Image::Indexed* toIndexed(); virtual bool canGray() const; // virtual void setBpc(unsigned char bpc_); virtual Image::RGB * toRGB(unsigned char bpc_); virtual Image::Gray * toGray(unsigned char bpc_); virtual unsigned char minRGBBpc() const; virtual Image::Sampled* addAlpha(Image::Gray *al); void fixEOI(); }; JAI::JAI(dimen_t wd_, dimen_t ht_, unsigned char bpc_, unsigned char cs_, slen_t flen_, slen_t SOF_offs_, unsigned char hvs_) { param_assert(cs_<=5); // init(0,0,wd_,ht_,bpc_,TY_BLACKBOX,cs2cpp[cs_]); cs=cs_; bpc=8; (void)bpc_; // bpc=bpc_; /* /DCTDecode supports only BitsPerComponent==8 */ ty=TY_BLACKBOX; wd=wd_; ht=ht_; cpp=cs2cpp[cs_]; // pred=1; transpc=0x1000000UL; /* Dat: this means: no transparent color */ rlen=0; beg=new char[len=0+flen_+0+bpc]; rowbeg=(headp=const_cast(beg))+flen_; xoffs=SOF_offs_; trail=const_cast(beg)+len-bpc; const_cast(beg)[len-1]=hvs_; /* dirty place */ } void JAI::fixEOI() { /* by pts@fazekas.hu at Tue Jun 4 15:36:12 CEST 2002 */ if (rowbeg[-2]!='\xFF' || rowbeg[-1]!='\xD9') { *rowbeg++='\xFF'; *rowbeg++='\xD9'; } } Image::Sampled* JAI::addAlpha(Image::Gray *) { Error::sev(Error::WARNING) << "JAI: alpha channel ignored" << (Error*)0; return this; } unsigned char JAI:: minRGBBpc() const { return bpc; } void JAI::copyRGBRow(char*, dimen_t) const { assert(0); } void JAI::to8() { assert(0); } Image::Indexed* JAI::toIndexed() { return (Image::Indexed*)NULLP; } bool JAI::canGray() const { return cs==CS_GRAYSCALE; } Image::RGB * JAI::toRGB(unsigned char) { assert(0); return 0; } Image::Gray * JAI::toGray(unsigned char) { assert(0); return 0; } /* --- The following code is based on standard/image.c from PHP4 */ /* some defines for the different JPEG block types */ #define M_SOF0 0xC0 /* Start Of Frame0: Baseline JPEG */ #define M_SOF1 0xC1 /* N indicates which compression process */ #define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ #define M_SOF3 0xC3 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ #define M_SOF6 0xC6 #define M_SOF7 0xC7 #define M_SOF9 0xC9 #define M_SOF10 0xCA #define M_SOF11 0xCB #define M_SOF13 0xCD #define M_SOF14 0xCE #define M_SOF15 0xCF #define M_SOI 0xD8 #define M_EOI 0xD9 /* End Of Image (end of datastream) */ #define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ #define M_APP0 0xe0 #define M_APP1 0xe1 #define M_APP2 0xe2 #define M_APP3 0xe3 #define M_APP4 0xe4 #define M_APP5 0xe5 #define M_APP6 0xe6 #define M_APP7 0xe7 #define M_APP8 0xe8 #define M_APP9 0xe9 #define M_APP10 0xea #define M_APP11 0xeb #define M_APP12 0xec #define M_APP13 0xed #define M_APP14 0xee #define M_APP15 0xef #if 0 static unsigned int jai_next_marker(FILE *fp) /* get next marker byte from file */ { int c; #if 0 /**** pts ****/ /* skip unimportant stuff */ c = MACRO_GETC(fp); while (c != 0xff) { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } #else if (0xff!=(c=MACRO_GETC(fp))) return M_EOI; #endif /* get marker byte, swallowing possible padding */ do { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } while (c == 0xff); return (unsigned int) c; } #endif #if 0 static inline int getc_(FILE *f) { return MACRO_GETC(f); } static inline long ftell_(FILE *f) { return ftell(f); } template static unsigned short jai_read2(T *fp); template static void jai_handle_jpeg(struct jai_gfxinfo *result, T *fp) { #endif /* Dat: removed templates at Tue Mar 11 19:59:16 CET 2003, because decoding * JPEG headers isn't time-critical */ static inline unsigned short jai_read2(GenBuffer::Readable *fp) { #if 0 unsigned char a[ 2 ]; /* just return 0 if we hit the end-of-file */ if (fread(a,sizeof(a),1,fp) != 1) return 0; return (((unsigned short) a[ 0 ]) << 8) + ((unsigned short) a[ 1 ]); #else int a=fp->vi_getcc(), b=fp->vi_getcc(); /* just return 0 if we hit the end-of-file */ return a>=0 && b>=0 ? (a<<8)+b : 0; #endif } /** main loop to parse JPEG structure */ void jai_parse_jpeg(struct jai_gfxinfo *result, DecoderTeller *fp, bool must_be_baseline) { int c; unsigned int length; unsigned char had_adobe; result->bad=9; /* signal invalid return value */ result->id_rgb=0; result->had_jfif=0; result->colortransform=127; /* no Adobe marker yet */ // fseek(fp, 0L, SEEK_SET); /* position file pointer on SOF */ /* Verify JPEG header */ /* Dat: maybe 0xFF != '\xFF' */ if ((c=fp->vi_getcc())!=0xFF) return; while ((c=fp->vi_getcc())==0xFF) ; if (c!=M_SOI) return; result->bad=1; // fprintf(stderr, "welcome ofs=%ld\n", fp->vi_tell()); while (1) { if ((c=fp->vi_getcc())!=0xFF) { result->bad=8; return; } while ((c=fp->vi_getcc())==0xFF) ; if (c==-1) { result->bad=2; return; } switch (c) { case M_SOF0: do_SOF: if (result->bad!=1) { result->bad=4; return; } /* only one M_SOF allowed */ result->SOF_type=c-M_SOF0; result->SOF_offs=fp->vi_tell(); // fprintf(stderr, "SOF_offs=%d\n", result->SOF_offs); /* handle SOFn block */ length=jai_read2(fp); result->bpc = fp->vi_getcc(); result->height = jai_read2(fp); result->width = jai_read2(fp); result->cpp = fp->vi_getcc(); if ((length-=8)!=3U*result->cpp) return; if (result->bpc!=8) { result->bad=6; return; } if (result->cpp!=1 && result->cpp!=3 && result->cpp!=4) { result->bad=5; return; } assert(length>=3); if (result->cpp==3) { result->id_rgb =fp->vi_getcc()=='R'; result->hvs=fp->vi_getcc(); fp->vi_getcc(); result->id_rgb&=fp->vi_getcc()=='G'; fp->vi_getcc(); fp->vi_getcc(); result->id_rgb&=fp->vi_getcc()=='B'; fp->vi_getcc(); fp->vi_getcc(); } else { length-=2; fp->vi_getcc(); result->hvs=fp->vi_getcc(); while (length--!=0) fp->vi_getcc(); } result->bad=2; break; case M_SOF1: case M_SOF2: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: if (!must_be_baseline) goto do_SOF; // fprintf(stderr, "SOF%u\n", marker-M_SOF0); assert(0); result->bad=3; return; case M_SOS: /* we are about to hit image data. We're done. Success. */ if (result->bad==2 /* && !feof(fp)*/) { /* Dat: !feof() already guaranteed */ if (result->cpp==1) { result->colorspace=Image::Sampled::CS_GRAYSCALE; } else if (result->cpp==3) { result->colorspace=Image::Sampled::CS_YCbCr; if (result->had_jfif!=0) ; else if (result->colortransform==0) result->colorspace=Image::Sampled::CS_RGB; else if (result->colortransform==1) ; else if (result->colortransform!=127) Error::sev(Error::EERROR) << "JAI: unknown ColorTransform: " << (unsigned)result->colortransform << (Error*)0; else if (result->id_rgb!=0) result->colorspace=Image::Sampled::CS_RGB; /* Imp: check for id_ycbcr */ else Error::sev(Error::WARNING) << "JAI: assuming YCbCr color space" << (Error*)0; } else if (result->cpp==4) { result->colorspace=Image::Sampled::CS_CMYK; if (result->colortransform==0) ; else if (result->colortransform==2) result->colorspace=Image::Sampled::CS_YCCK; else if (result->colortransform!=127) Error::sev(Error::EERROR) << "JAI: unknown ColorTransform: " << (unsigned)result->colortransform << (Error*)0; } else assert(0); result->bad=0; } /* fall through */ case M_EOI: /* premature EOF */ return; case M_APP0: /* JFIF application-specific marker */ length=jai_read2(fp); if (length==2+4+1+2+1+2+2+1+1) { result->had_jfif=fp->vi_getcc()=='J' && fp->vi_getcc()=='F' && fp->vi_getcc()=='I' && fp->vi_getcc()=='F' && fp->vi_getcc()==0; length-=7; } else length-=2; while (length--!=0) fp->vi_getcc(); break; case M_APP14: /* Adobe application-specific marker */ length=jai_read2(fp); if ((length-=2)==5+2+2+2+1) { had_adobe=fp->vi_getcc()=='A' && fp->vi_getcc()=='d' && fp->vi_getcc()=='o' && fp->vi_getcc()=='b' && fp->vi_getcc()=='e' && ((unsigned char)fp->vi_getcc())>=1; fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); if (had_adobe) result->colortransform=fp->vi_getcc(); else fp->vi_getcc(); } else while (length--!=0) fp->vi_getcc(); break; case M_APP1: case M_APP2: case M_APP3: case M_APP4: case M_APP5: case M_APP6: case M_APP7: case M_APP8: case M_APP9: case M_APP10: case M_APP11: case M_APP12: case M_APP13: case M_APP15: /* fall through */ default: { /* anything else isn't interesting */ /* skip over a variable-length block; assumes proper length marker */ unsigned short length; length = jai_read2(fp); length -= 2; /* length includes itself */ #if 0 /**** pts: fseek would disturb later ftell()s and feof()s */ fseek(fp, (long) length, SEEK_CUR); /* skip the header */ #else while (length--!=0) fp->vi_getcc(); /* make feof(fp) correct */ #endif } } } } char const*jai_errors[]={ (char const*)NULLP, /*1*/ "missing SOF0 marker", /*2*/ "premature EOF", /*3*/ "not a Baseline JPEG (SOF must be SOF0)", /*4*/ "more SOF0 markers", /*5*/ "bad # components", /*6*/ "bad bpc", /*7*/ "?", /*8*/ "0xFF expected", /*9*/ "invalid JPEG header", // /*10*/ "not ending with EOI", /* not output by jai_handle_jpeg! */ }; static Image::Sampled *in_jai_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const&) { // assert(0); struct jai_gfxinfo gi; Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; FILE *file_=ufdd->getFILE(/*seekable:*/true); jai_parse_jpeg(&gi, ufdd); // jai_parse_jpeg(&gi, (FILE*)file_); // long ftel=ftell((FILE*)file_); if (gi.bad!=0) Error::sev(Error::EERROR) << "JAI: " << jai_errors[gi.bad] << (Error*)0; // printf("ftell=%lu\n", ftell((FILE*)file_)); fseek((FILE*)file_, 0L, 2); /* EOF */ long flen=ftell((FILE*)file_); /* skip extra bytes after EOI. Imp: no need to do this */ // fprintf(stderr, "flen=%lu\n", flen); assert(flen>2); rewind((FILE*)file_); JAI *ret=new JAI(gi.width,gi.height,gi.bpc,gi.colorspace,flen,gi.SOF_offs,gi.hvs); if (fread(ret->getHeadp(), flen, 1, (FILE*)file_)!=1 || ferror((FILE*)file_)) { ret->fixEOI(); /* fclose((FILE*)file_); */ Error::sev(Error::EERROR) << "JAI: IO error" << (Error*)0; } /* fclose((FILE*)file_); */ return ret; } static Image::Loader::reader_t in_jai_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const& loadHints, Image::Loader::UFD* ufd) { if (0!=memcmp(buf, "\xff\xd8\xff", 3) || !(loadHints.findFirst((char const*)",jpeg-asis,",6)!=loadHints.getLength() || loadHints.findFirst((char const*)",asis,",6)!=loadHints.getLength()) ) return 0; Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; ufdd->seek(0); Image::Loader::reader_t ret=jai_is_baseline_jpeg(ufdd) ? in_jai_reader : 0; ufdd->seek(0); return ret; } #if 0 /* Filter::FlatR* used by JPEGSOF0Encode::vi_write() in appliers.cpp */ static inline int getc_(Filter::FlatR *f) { return f->getcc(); } static inline long ftell_(Filter::FlatR *f) { return f->tell(); } void jai_parse_jpeg(struct jai_gfxinfo *result, Filter::FlatR *f) { jai_handle_jpeg(result, f); } void jai_parse_jpeg(struct jai_gfxinfo *result, FILE *f) { jai_handle_jpeg(result, f); } #endif #if 0 /* unused */ int jai_is_baseline_jpeg(char const* filename) { /* by pts@fazekas.hu at Tue Mar 11 20:27:56 CET 2003 */ FILE *f=fopen(filename, "rb"); if (!f) return -1; Filter::FILED filed(f, /*closep:*/true); return jai_is_baseline_jpeg(&filed); } #endif int jai_is_baseline_jpeg(/*DecoderTeller*/Filter::UngetFILED *fp) { char buf[3]; struct jai_gfxinfo gi; bool qfalse=(3!=fp->vi_read(buf, 3) || 0!=memcmp(buf, "\xff\xd8\xff", 3)); fp->unread(buf, 3); if (qfalse) return false; fp->getFILE(/*seekable*/true); /* make it seekable, so the caller can seek back */ jai_parse_jpeg(&gi, fp, /*must_be_baseline:*/false); fp->seek(0); return gi.bad!=0 ? -1 : gi.SOF_type==0; } #else #define in_jai_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_JAI */ Image::Loader in_jai_loader = { "JAI", in_jai_checker, 0 }; sam2p-0.49.2/in_jpeg.cpp0000644000175100017510000000232112211371426013144 0ustar ptspts/* * in_jpeg.cpp -- read JPEG (JFIF and other) files with djpeg * by pts@fazekas.hu at Sun Apr 14 14:50:30 CEST 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_JPEG #include "error.hpp" #include "gensio.hpp" #include "helpere.hpp" #include /* memchr() */ #include /* printf() */ static Image::Sampled *in_jpeg_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { // Error::sev(Error::EERROR) << "Cannot load JPEG images yet." << (Error*)0; HelperE helper("djpeg"); /* Run external process `djpeg' to convert JPEG -> PNM */ Encoder::writeFrom(*(Filter::PipeE*)&helper, *(Filter::UngetFILED*)ufd); ((Filter::PipeE*)&helper)->vi_write(0,0); /* Signal EOF */ return helper.getImg(); } static Image::Loader::reader_t in_jpeg_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const& loadHints, Image::Loader::UFD*) { return (0==memcmp(buf, "\xff\xd8", 2)) && loadHints.findFirst((char const*)",asis,",6)==loadHints.getLength() ? in_jpeg_reader : 0; } #else #define in_jpeg_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_XPM */ Image::Loader in_jpeg_loader = { "JPEG", in_jpeg_checker, 0 }; sam2p-0.49.2/in_lbm.cpp0000644000175100017510000002117412211371426013000 0ustar ptspts/* * in_lbm.cpp -- read a Deluxe Paint IFF/ILBM file * by pts@fazekas.hu at Fri Mar 1 17:12:16 CET 2002 * -- Fri Mar 1 22:28:03 CET 2002 * * I've ripped the reader code from xscavenger's source, and enhanced it * a little bit (at Fri Mar 1 17:12:43 CET 2002), but I still think that * this can read only the minority of the LBM files around. */ /* Imp: get docs about the LBM format, and rewrite this from scratch */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_LBM #include /* memchr() */ #include "gensio.hpp" #define FORM 0x464f524dL #define ILBM 0x494c424dL #define PBM 0x50424d20L #define CMAP 0x434d4150L #define BODY 0x424f4459L #define BMHD 0x424d4844L /* typedef unsigned char uchar; */ #define MAXBYTES 128 /* ?? */ /* --- */ #if SIZEOF_INT>=4 typedef unsigned int u32_t; typedef signed int s32_t; #else typedef unsigned long u32_t; typedef signed long s32_t; #endif class LBMRead { public: inline LBMRead(FILE *f_): f(f_) {} /* inline ~LBMRead() { fclose(f); } */ Image::Sampled *doit(); protected: inline int getcn(); void errUnEOF(); void err(char const*s); u32_t getUnpack(unsigned len, char *where); u32_t getu32(); unsigned getu16(); FILE *f; }; //static inline int fixbyte(char *take,int bit,int depth) { // int res=0,mask=1; // while (depth--) { // if (*take & bit) res|=mask; // mask<<=1; // take+=MAXBYTES; // } // return res; //} #if 0 static void debit(char *picput, char *lines, unsigned wd, unsigned depth) { unsigned depth2, bit=128, res, i, mask; unsigned byteswide=((wd+15)>>4)<<1; unsigned char *take; for (i=0;i>=1; } } #endif void LBMRead::errUnEOF() { Error::sev(Error::EERROR) << "LBM: unexpected EOF" << (Error*)0; } void LBMRead::err(char const*s) { Error::sev(Error::EERROR) << s << (Error*)0; } inline int LBMRead::getcn() { int i=MACRO_GETC(f); if (i==-1) errUnEOF(); return i; } u32_t LBMRead::getUnpack(unsigned len, char *where) { /* RLE decompression */ int ch,ch2; u32_t sofar=0; while (len>0) { ch=getcn(); if (ch<128) { ch++; assert(ch>=1); if (len<(unsigned)ch) err("LBM: packet#1 too long"); len-=ch; sofar+=1+ch; while (ch--) *where++=getcn(); } else { ch=1-(ch-256); /* 2..129 */ assert(ch>=1); // fprintf(stderr, "len=%u ch=%u\n", len, ch); if (len<(unsigned)ch) err("LBM: packet#2 too long"); len-=ch; // fprintf(stderr, "xlen=%u ch=%u\n", len, ch); ch2=getcn(); sofar+=2; while (ch--) *where++=ch2; } } return sofar; } u32_t LBMRead::getu32() { u32_t val1=0; val1=getcn()<<24L; val1|=getcn()<<16L; val1|=getcn()<<8; val1|=getcn(); return val1; } unsigned LBMRead::getu16() { u32_t val1=0; val1|=getcn()<<8; val1|=getcn(); return val1; } Image::Sampled *LBMRead::doit() { char temparea[16]; u32_t type, size, i; unsigned char comp=0; unsigned j; int ii; Image::Sampled::dimen_t lbm_wd, lbm_ht, byteswide, depth=0; /* pts */ unsigned transp=256; Image::Sampled *img=(Image::Sampled*)NULLP; bool had_cmap=false, had_body=false, do_skip, had_transp=false; /* sprintf(temparea,"%s/%s/%s",localname,localdirname,name); */ for (i=0;i<12;i++) temparea[i]=getcn(); if (0!=memcmp(temparea,"FORM",4) || 0!=memcmp(temparea+8,"ILBM",4)) err("LBM: magic says: this is not an LBM"); lbm_wd=lbm_ht=byteswide=0; while ((ii=MACRO_GETC(f))!=-1 && ii!='\0') { ungetc(ii,f); if ((type=getu32())==0xffffffffL) break; size=getu32(); do_skip=(size&1); /* pad to even size */ // fprintf(stderr,"size=%u\n", size); if (type==BMHD) { if (img!=NULLP) err("LBM: duplicate BMHD"); // if (size>sizeof(temparea)) { // for (i=0;i8)) err("LBM: invalid color depth"); if (getcn()!=0) err("LBM: expected masking==0"); if ((comp=getcn())>=2) err("LBM: expected comp==0 || comp==1"); getcn(); /* ignore padding */ transp=getu16(); /* index of transparent color */ // fprintf(stderr, "htt=%u transp=%u\n", lbm_ht, transp); getu16(); /* Ignore aspect ratio. */ if (lbm_wd!=getu16() || lbm_ht!=getu16()) err("LBM: inconsistent dimens"); /* ^^^ Dat: pagex, pagey */ byteswide=((lbm_wd+15)>>4)<<1; /*printf("(%d,%d) %d bpp\n",lbm_wd,lbm_ht,depth);*/ if (depth==24) { had_cmap=true; img=new Image::RGB(lbm_wd, lbm_ht, 8); } else { img=new Image::Indexed(lbm_wd, lbm_ht, 1<getHeadp(), '\0', 3*(1<getRowbeg(); // const_cast(img->getCString()); for (i=0;i>4)<<1; unsigned char *take, *lines=(unsigned char*)buf; if (depth!=24) { for (i=0;i>=1; } } else { u32_t res; for (i=0;i>8; *picput++=res>>16; if (bit==1) { bit=128; ++lines; } else bit>>=1; } } } // fprintf(stderr,"size=%u\n", size); if (size>1) { dtl: err("LBM: data too long"); } if (size==1) getcn(); if (had_transp) { assert(depth!=24); static_cast(img)->setTransp(transp); } // img->getRowbeg()[0]='\001'; img->getRowbeg()[1]='\002'; delete [] buf; had_body=true; } else if (type==CMAP) { if (img==NULLP) err("LBM: should be: BMHD, CMAP"); if (had_cmap) err("LBM: duplicate CMAP"); if (size>3*(1U<getHeadp(); // fprintf(stderr,"Si=%d size=%u\n", img->getRowbeg()-colormap, size); for (i=0;igetFILE(/*seekable:*/false)).doit(); /* ^^^ Destructor: fclose((FILE*)file_); */ } static Image::Loader::reader_t in_lbm_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (0==memcmp(buf,"FORM",4) && 0==memcmp(buf+8,"ILBM",4)) ? in_lbm_reader : 0; } #else #define in_lbm_checker NULLP #endif /* USE_IN_XPM */ Image::Loader in_lbm_loader = { "LBM", in_lbm_checker, 0 }; sam2p-0.49.2/in_pcx.cpp0000644000175100017510000003457612211371426013032 0ustar ptspts/* * in_pcx.cpp: loads PCX images * modified by pts@fazekas.hu at Fri Apr 12 22:16:08 CEST 2002 * -- Fri Apr 12 23:54:57 CEST 2002 * * xvpcx.c - load routine for PCX format pictures * * LoadPCX(fname, pinfo) - loads a PCX file */ /**** pts ****/ #include "config2.h" #include "image.hpp" #if USE_IN_PCX #include "error.hpp" #include "gensio.hpp" #include /* Imp: palette handling etc. according to PCX_VER, see decode.c */ #define dimen Image::Sampled::dimen_t #define pcxError(bname,conststr) Error::sev(Error::WARNING) << "PCX: " conststr << (Error*)0 #define WaitCursor() #define xvbzero(p,len) memset(p, '\0', len) #define FatalError(conststr) Error::sev(Error::EERROR) << "PCX: " conststr << (Error*)0 #define return_pcxError(bname, conststr) Error::sev(Error::EERROR) << "PCX: " conststr << (Error*)0 #define byte unsigned char #define size_t slen_t #define malloc_byte(n) new byte[n] #define free(p) delete p #define DEBUG 1 /* the following list give indicies into saveColors[] array in xvdir.c */ #define F_FULLCOLOR 0 #define F_GREYSCALE 1 #define F_BWDITHER 2 /* values 'picType' can take */ #define PIC8 8 #define PIC24 24 #define xv_fopen(filename,read_mode) fopen(filename,"rb") #define BaseName(x) ((char*)0) #define PARM(parm) parm /* info structure filled in by the LoadXXX() image reading routines */ typedef struct { byte *pic; /* image data */ dimen w, h; /* pic size */ #if 0 /**** pts ****/ byte r[256],g[256],b[256]; #else /* byte pal[3*256]; */ byte *pal; # define PAL_R(pinfo,idx) (pinfo)->pal[3*(idx)] # define PAL_G(pinfo,idx) (pinfo)->pal[3*(idx)+1] # define PAL_B(pinfo,idx) (pinfo)->pal[3*(idx)+2] #endif /* colormap, if PIC8 */ #if 0 /**** pts ****/ int colType; /* def. Color type to save in */ int type; /* PIC8 or PIC24 */ int normw, normh; /* 'normal size' of image file (normally eq. w,h, except when doing 'quick' load for icons */ int frmType; /* def. Format type to save in */ char fullInfo[128]; /* Format: field in info box */ char shrtInfo[128]; /* short format info */ char *comment; /* comment text */ int numpages; /* # of page files, if >1 */ char pagebname[64]; /* basename of page files */ #endif } PICINFO; /* #include "copyright.h" */ /* * the following code has been derived from code written by * Eckhard Rueggeberg (Eckhard.Rueggeberg@ts.go.dlr.de) */ /* #include "xv.h" */ /* offsets into PCX header */ #define PCX_ID 0 #define PCX_VER 1 #define PCX_ENC 2 #define PCX_BPP 3 #define PCX_XMINL 4 #define PCX_XMINH 5 #define PCX_YMINL 6 #define PCX_YMINH 7 #define PCX_XMAXL 8 #define PCX_XMAXH 9 #define PCX_YMAXL 10 #define PCX_YMAXH 11 /* hres (12,13) and vres (14,15) not used */ #define PCX_CMAP 16 /* start of 16*3 colormap data */ #define PCX_PLANES 65 #define PCX_BPRL 66 #define PCX_BPRH 67 #define PCX_MAPSTART 0x0c /* Start of appended colormap */ static int pcxLoadImage8 PARM((char *, FILE *, PICINFO *, byte *)); static int pcxLoadImage24 PARM((char *, FILE *, PICINFO *, byte *)); static void pcxLoadRaster PARM((FILE *, byte *, int, byte *, dimen, dimen)); #if 0 /**** pts ****/ static int pcxError PARM((char *, char *)); #endif /*******************************************/ static Image::Sampled *LoadPCX #if 0 /**** pts ****/ ___((char *fname, PICINFO *pinfo), (fname, pinfo), (char *fname; PICINFO *pinfo;)) #else ___((FILE *fp, PICINFO *pinfo), (fname, pinfo), (char *fname; PICINFO *pinfo;)) #endif /*******************************************/ { Image::Sampled *ret=(Image::Sampled*)NULLP; byte hdr[128]; #if 0 /**** pts ****/ long filesize; char *bname; FILE *fp; char *errstr; byte *image; int gray; #endif int i, colors, fullcolor; pinfo->pic = (byte *) NULL; pinfo->pal = (byte *) NULL; #if 0 /**** pts ****/ pinfo->type = PIC8; pinfo->comment = (char *) NULL; bname = BaseName(fname); /* open the stream */ fp = xv_fopen(fname,"r"); if (!fp) return_pcxError(bname, "unable to open file"); #endif #if 0 /**** pts ****/ /* figure out the file size */ fseek(fp, 0L, 2); filesize = ftell(fp); fseek(fp, 0L, 0); #endif /* read the PCX header */ if (fread(hdr, (size_t) 128, (size_t) 1, fp) != 1 || ferror(fp) || feof(fp)) { /* fclose(fp); */ return_pcxError(bname, "EOF reached in PCX header.\n"); } if (hdr[PCX_ID] != 0x0a || hdr[PCX_VER] > 5) { /* fclose(fp); */ return_pcxError(bname,"unrecognized magic number"); } pinfo->w = (hdr[PCX_XMAXL] + ((int) hdr[PCX_XMAXH]<<8)) - (hdr[PCX_XMINL] + ((int) hdr[PCX_XMINH]<<8)); pinfo->h = (hdr[PCX_YMAXL] + ((int) hdr[PCX_YMAXH]<<8)) - (hdr[PCX_YMINL] + ((int) hdr[PCX_YMINH]<<8)); pinfo->w++; pinfo->h++; colors = 1 << (hdr[PCX_BPP] * hdr[PCX_PLANES]); fullcolor = (hdr[PCX_BPP] == 8 && hdr[PCX_PLANES] == 3); #if USE_DEBUG_MESSAGES if (DEBUG) { fprintf(stderr,"PCX: %dx%d image, version=%d, encoding=%d\n", pinfo->w, pinfo->h, hdr[PCX_VER], hdr[PCX_ENC]); fprintf(stderr," BitsPerPixel=%d, planes=%d, BytePerRow=%d, colors=%d\n", hdr[PCX_BPP], hdr[PCX_PLANES], hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8), colors); } #endif if (colors>256 && !fullcolor) { /* fclose(fp); */ return_pcxError(bname,"No more than 256 colors allowed in PCX file."); } if (hdr[PCX_ENC] != 1) { /* fclose(fp); */ return_pcxError(bname,"Unsupported PCX encoding format."); } /* load the image, the image function fills in pinfo->pic */ if (!fullcolor) { Image::Indexed *img=new Image::Indexed(pinfo->w, pinfo->h, colors, 8); pinfo->pal=(byte*)img->getHeadp(); ASSERT_SIDE(pcxLoadImage8((char*)NULLP/*bname*/, fp, pinfo, hdr)); memcpy(img->getRowbeg(), pinfo->pic, pinfo->w*pinfo->h); ret=img; } else { Image::RGB *img=new Image::RGB(pinfo->w, pinfo->h, 8); ASSERT_SIDE(pcxLoadImage24((char*)NULLP/*bname*/, fp, pinfo, hdr)); memcpy(img->getRowbeg(), pinfo->pic, pinfo->w*pinfo->h*3); ret=img; } free(pinfo->pic); pinfo->pic=(byte*)NULLP; if (ferror(fp) | feof(fp)) /* just a warning */ pcxError(bname, "PCX file appears to be truncated."); if (colors>16 && !fullcolor) { /* handle trailing colormap */ while (1) { i=MACRO_GETC(fp); if (i==PCX_MAPSTART || i==EOF) break; } #if 0 /**** pts ****/ for (i=0; ipal, 1, colors*3, fp) != colors * 3 + 0U || ferror(fp) || feof(fp)) { pcxError(bname,"Error reading PCX colormap. Using grayscale."); for (i=0; i<256; i++) PAL_R(pinfo,i) = PAL_G(pinfo,i) = PAL_B(pinfo,i) = i; } } else if (colors<=16) { /* internal colormap */ #if 0 /**** pts ****/ for (i=0; ipal, hdr+PCX_CMAP, colors*3); #endif } if (colors == 2) { /* b&w */ #if 0 /**** pts ****/ if (MONO(PAL_R(pinfo,0), PAL_G(pinfo,0), PAL_B(pinfo,0)) == MONO(PAL_R(pinfo,1), PAL_G(pinfo,1), PAL_B(pinfo,1))) { #else if (PAL_R(pinfo,0)==PAL_R(pinfo,1) && PAL_G(pinfo,0)==PAL_G(pinfo,1) && PAL_B(pinfo,0)==PAL_B(pinfo,1)) { #endif /* create cmap */ PAL_R(pinfo,0) = PAL_G(pinfo,0) = PAL_B(pinfo,0) = 255; PAL_R(pinfo,1) = PAL_G(pinfo,1) = PAL_B(pinfo,1) = 0; #if USE_DEBUG_MESSAGES if (DEBUG) fprintf(stderr,"PCX: no cmap: using 0=white,1=black\n"); #endif } } /* fclose(fp); */ /* finally, convert into XV internal format */ #if 0 /**** pts ****/ pinfo->type = fullcolor ? PIC24 : PIC8; pinfo->frmType = -1; /* no default format to save in */ #endif #if 0 /**** pts ****/ /* check for grayscaleitude */ gray = 0; if (!fullcolor) { for (i=0; i 2 || (colors==2 && !gray)) { /* grayscale or PseudoColor */ pinfo->colType = (gray) ? F_GREYSCALE : F_FULLCOLOR; #if 0 /**** pts ****/ sprintf(pinfo->fullInfo, "%s PCX, %d plane%s, %d bit%s per pixel. (%ld bytes)", (gray) ? "Greyscale" : "Color", hdr[PCX_PLANES], (hdr[PCX_PLANES]==1) ? "" : "s", hdr[PCX_BPP], (hdr[PCX_BPP]==1) ? "" : "s", filesize); #endif } else { pinfo->colType = F_BWDITHER; #if 0 /**** pts ****/ sprintf(pinfo->fullInfo, "B&W PCX. (%ld bytes)", filesize); #endif } #if 0 /**** pts ****/ sprintf(pinfo->shrtInfo, "%dx%d PCX.", pinfo->w, pinfo->h); pinfo->normw = pinfo->w; pinfo->normh = pinfo->h; #endif #endif return ret; } /*****************************/ static int pcxLoadImage8 ___((char *fname, FILE *fp, PICINFO *pinfo, byte *hdr), (fname, fp, pinfo, hdr), (char *fname; FILE *fp; PICINFO *pinfo; byte *hdr;)) { /* load an image with at most 8 bits per pixel */ (void)fname; /**** pts ****/ byte *image; /* note: overallocation to make life easier... */ image = (byte *) malloc_byte((size_t) (pinfo->h + 1) * pinfo->w + 16); if (!image) FatalError("Can't alloc 'image' in pcxLoadImage8()"); xvbzero((char *) image, (size_t) ((pinfo->h+1) * pinfo->w + 16)); switch (hdr[PCX_BPP]) { case 1: case 2: case 4: case 8: pcxLoadRaster(fp, image, hdr[PCX_BPP], hdr, pinfo->w, pinfo->h); break; default: free(image); return_pcxError(fname, "Unsupported # of bits per plane."); } pinfo->pic = image; return 1; } /*****************************/ static int pcxLoadImage24 ___((char *fname, FILE *fp, PICINFO *pinfo, byte *hdr), (fname, fp, pinfo, hdr), (char *fname; FILE *fp; PICINFO *pinfo; byte *hdr;)) { byte *pix, *pic24; int c; unsigned i, j, w, h, cnt, planes, bperlin, nbytes; #if 0 /***** pts ****/ int maxv; /* ImageMagick does not have one */ byte scale[256]; #endif (void)fname; /**** pts ****/ w = pinfo->w; h = pinfo->h; planes = (int) hdr[PCX_PLANES]; bperlin = hdr[PCX_BPRL] + ((int) hdr[PCX_BPRH]<<8); /* allocate 24-bit image */ pic24 = (byte *) malloc_byte((size_t) w*h*planes); if (!pic24) FatalError("couldn't malloc 'pic24'"); xvbzero((char *) pic24, (size_t) w*h*planes); #if 0 /**** pts ****/ maxv = 0; #endif pix = pinfo->pic = pic24; i = 0; /* planes, in this while loop */ j = 0; /* bytes per line, in this while loop */ nbytes = bperlin*h*planes; while (nbytes > 0 && (c = MACRO_GETC(fp)) != EOF) { if (c>=0xC0) { /* have a rep. count */ cnt = c & 0x3F; c = MACRO_GETC(fp); if (c == EOF) { MACRO_GETC(fp); break; } } else cnt = 1; #if 0 /**** pts ****/ if (c > maxv) maxv = c; #endif while (cnt-- > 0) { if (j < w) { *pix = c; pix += planes; } j++; nbytes--; if (j == bperlin) { j = 0; if (++i < planes) { pix -= (w*planes)-1; /* next plane on this line */ } else { pix -= (planes-1); /* start of next line, first plane */ i = 0; } } } } #if 0 /**** pts ****/ /* scale all RGB to range 0-255, if they aren't */ if (maxv<255) { for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv; for (i=0, pix=pic24; i=0xC0) { /* have a rep. count */ cnt = b & 0x3F; b = MACRO_GETC(fp); if (b == EOF) { MACRO_GETC(fp); return; } } else cnt = 1; for (i=0; i>6)&3)*pmask; *image++|=((b>>4)&3)*pmask; *image++|=((b>>2)&3)*pmask; *image++|=((b )&3)*pmask; break; case 4: /**** pts ****/ *image++|=((b>>4)&15)*pmask; *image++|=((b )&15)*pmask; break; default: *image++=(byte)b; } bcnt++; if (bcnt == bperlin) { /* end of a line reached */ bcnt = 0; if (--pleft==0) { /* moved to next row */ pleft=hdr[PCX_PLANES]; pmask=1; image -= pad; oldimage = image; row++; if (row >= h) return; /* done */ } else { /* next plane, same row */ image = oldimage; pmask<<=depth; } } } } } #if 0 /**** pts ****/ /*******************************************/ static int pcxError(fname,st) char *fname, *st; { SetISTR(ISTR_WARNING,"%s: %s", fname, st); return 0; } #endif static Image::Sampled *in_pcx_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { PICINFO pinfo_; return LoadPCX(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false), &pinfo_); } static Image::Loader::reader_t in_pcx_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return buf[PCX_ID]==0x0a && (unsigned char)buf[PCX_VER]<=5 && buf[PCX_ENC]==1 && buf[PCX_BPP]<=8 ? in_pcx_reader : 0; } #else #define in_pcx_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_PCX */ Image::Loader in_pcx_loader = { "PCX", in_pcx_checker, 0 }; /* __END__ */ sam2p-0.49.2/in_png.cpp0000644000175100017510000000374612211371426013017 0ustar ptspts/* * in_png.cpp -- read PNG (Portable Network Graphics, PNG is Not GIF) files with pngtopnm * by pts@fazekas.hu at Sun Apr 14 14:50:30 CEST 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_PNG #include "error.hpp" #include "gensio.hpp" #include "helpere.hpp" #include /* memchr() */ #include /* printf() */ static Image::Sampled *in_png_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const&) { // Error::sev(Error::EERROR) << "Cannot load PNG images yet." << (Error*)0; char const* cmd= #if 0 #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT "pngtopnm %S >%D\npngtopnm -alpha %S >>%D"; #else #if OS_COTY==COTY_UNIX "(pngtopnm <%S && pngtopnm -alpha <%S) >%D"; #else "pngtopnm %S >%D\npngtopnm -alpha %S >>%D"; #endif #endif #else /* Wed Feb 5 19:03:58 CET 2003 */ #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT "png22pnm -rgba %S >%D"; #else #if OS_COTY==COTY_UNIX #if 1 "(png22pnm -rgba %S || (pngtopnm <%S && pngtopnm -alpha <%S)) >%D"; #else /* Dat: not using this to suppress `sh: png22pnm: command not found', because * it would hide precious error messages printed by png22pnm. */ "((png22pnm -rgba %S 2>/dev/null)|| (pngtopnm <%S && pngtopnm -alpha <%S)) >%D"; #endif #else "png22pnm -rgba %S >%D"; #endif #endif #endif HelperE helper(cmd); /* Run external process pngtopnm */ Encoder::writeFrom(*(Filter::PipeE*)&helper, *(Filter::UngetFILED*)ufd); ((Filter::PipeE*)&helper)->vi_write(0,0); /* Signal EOF */ return helper.getImg(); } static Image::Loader::reader_t in_png_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return 0==memcmp(buf,"\211PNG\r\n\032\n",8) ? in_png_reader : 0; } #else #define in_png_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_PNG */ Image::Loader in_png_loader = { "PNG", in_png_checker, 0 }; sam2p-0.49.2/in_pnm.cpp0000644000175100017510000000554112211371426013020 0ustar ptspts/* * in_pnm.cpp -- read a NetPBM PNM bitmap file * by pts@fazekas.hu at Sat Mar 2 00:46:54 CET 2002 * */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_PNM #include "gensio.hpp" #include "input-pnm.ci" #include static Image::Sampled *in_pnm_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; #if 0 FILE *f=((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false); bitmap_type bitmap=pnm_load_image(f); #else Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; bitmap_type bitmap=pnm_load_image(ufdd); #endif /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); /* fwrite(BITMAP_BITS(bitmap), 1, (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap), stdout); */ ret=img; } else assert(0 && "invalid PNM depth"); delete [] BITMAP_BITS(bitmap); if (ufdd->vi_getcc()=='P') { ufdd->unread("P", 1); // Error::sev(Error::NOTICE) << "PNM: loading alpha after PNM: " // " ftell=" << ftell(f) << // " bytes=" << ((unsigned)bitmap.width*bitmap.height*bitmap.np) << (Error*)0; bitmap=pnm_load_image(ufdd); // fwrite(bitmap.bitmap,1,(unsigned)bitmap.width*bitmap.height*bitmap.np,stdout); /* Dat: black pixel is transparent */ if (BITMAP_PLANES(bitmap)!=1) Error::sev(Error::EERROR) << "PNM: alpha must be PBM or PGM" << (Error*)0; Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); delete [] BITMAP_BITS(bitmap); Image::Sampled *old=ret; // old->packPal(); /* automatically called */ if ((ret=old->addAlpha(img))!=old) { Error::sev(Error::NOTICE) << "PNM: loaded alpha after PNM" << (Error*)0; delete old; } else { Error::sev(Error::NOTICE) << "PNM: loaded alpha, but no transparent pixels" << (Error*)0; } } /* fclose(f); */ return ret; } static Image::Loader::reader_t in_pnm_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (buf[0]=='P' && (buf[1]>='1' && buf[1]<='6') && (buf[2]=='\t' || buf[2]==' ' || buf[2]=='\r' || buf[2]=='\n' || buf[2]=='#')) ? in_pnm_reader : 0; } #else #define in_pnm_checker NULLP #endif /* USE_IN_PNM */ Image::Loader in_pnm_loader = { "PNM", in_pnm_checker, 0 }; sam2p-0.49.2/in_ps.cpp0000644000175100017510000001760312211371426012652 0ustar ptspts/* * in_ps.cpp -- read PS and PDF files using GS * by pts@fazekas.hu at Tue Sep 30 12:33:11 CEST 2003 */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_PS || USE_IN_PDF #include "error.hpp" #include "gensio.hpp" #include "helpere.hpp" #include /* memchr() */ #include /* printf() */ #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT # define GS "gswin32c" #else # define GS "gs" #endif #endif /* USE_IN_PS || USE_IN_PDF */ /** Adds a Ghostscript invocation command. Works for both PS and PDF. */ static void add_gs_cmd(SimBuffer::B &cmd, SimBuffer::Flat const& hints) { cmd << GS " -r72 -q -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -dLastPage=1 -sDEVICE=pnmraw -dDELAYSAFER -dBATCH -dNOPAUSE -sOutputFile=%D "; char const *p=hints(), *r; /* Dat: hints ends by ',' '\0' */ // Files::FILEW(stdout) << hints << ";;\n"; while (*p!=',') p++; /* Dat: safe, because hints is assumed to start and end by ',' */ while (1) { assert(*p==','); if (*++p=='\0') break; if (p[0]=='g' && p[1]=='s' && p[2]=='=') { r=p+=3; while (*p!=',') p++; cmd.vi_write(r, p-r); /* Dat: -r... in here overrides -r72 above */ cmd << ' '; } else { while (*p!=',') p++; } } } #if USE_IN_PS /* !! -r144 and scale back..., also for PDF -- to enhance image quality */ #undef DO_KEEP_TEMP #define DO_KEEP_TEMP 0 static Image::Sampled *in_ps_reader_low(Image::Loader::UFD* ufd, char const*bboxline, SimBuffer::Flat const& hints) { SimBuffer::B mainfn; if (!Files::find_tmpnam(mainfn)) Error::sev(Error::EERROR) << "in_ps_reader" << ": tmpnam() failed" << (Error*)0; mainfn.term0(); #if DO_KEEP_TEMP printf("m: %s\n", mainfn()); #else Files::tmpRemoveCleanup(mainfn()); #endif FILE *f=fopen(mainfn(),"w"); fprintf(f, "%s", bboxline); /* vvv Dat: ignore extra calls to `showpage' */ fprintf(f, "/showpage [ currentdict /showpage {} /put load /showpage load ] cvx def\n"); fprintf(f, "_IFN (r) file cvx exec\nshowpage\n"); /* Dat: doesn't rely on GS to recognise EPSF-x.y comment, so works with both old and new gs */ // ^^^ !! DOS EPSF etc. instead of exec/run fclose(f); // Error::sev(Error::EERROR) << "Cannot load PS images yet." << (Error*)0; /* Dat: -dLastPage=1 has no effect, but we keep it for PDF compatibility */ /* !! keep only 1st page, without setpagedevice for PS files */ /* Dat: -dSAFER won't let me open the file with `/' under ESP Ghostscript 7.05.6 (2003-02-05) */ /* Imp: win9X command line too long? */ SimBuffer::B cmd; add_gs_cmd(cmd,hints); cmd << " -s_IFN=%S -- %*"; /*fprintf(stderr,"cmd:%s\n",cmd.term0()()); */ HelperE helper(cmd.term0()(), mainfn()); /* Run external process GS */ Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; int i=ufdd->vi_getcc(); if (i<0) Error::sev(Error::EERROR) << "in_ps_reader: Empty PostScript file." << (Error*)0; /* should never happen */ ((Filter::PipeE*)&helper)->vi_putcc(i); Encoder::writeFrom(*(Filter::PipeE*)&helper, *ufdd); ((Filter::PipeE*)&helper)->vi_write(0,0); /* Signal EOF */ #if !DO_KEEP_TEMP remove(mainfn()); #endif return helper.getImg(); } static Image::Sampled *in_ps_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const& hints) { /* Use the paper size (<> setpagedevice; a4; letter etc.) * set up by the PostScript file, or the system default paper size. */ return in_ps_reader_low(ufd, "", hints); } static Image::Sampled *in_eps_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const& hints) { /* Use the *BoundingBox if available, else use the paper size set up by * the EPS file, or the system default paper size. */ double llx=0.0, lly=0.0, urx=0.0, ury=0.0; Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; /* ^^^ SUXX: no warning for ufdd=ufdd */ /* SUXX: valgrind, checkergcc: no indication of segfault due to stack overflow inside fgetc() */ SimBuffer::B line; /* Imp: limit for max line length etc. */ #if 0 while ((line.clearFree(), ufdd->appendLine(line), line)) { line.term0(); printf("line: %s", line()); } #endif slen_t line0ofs; int had=0; while ((line0ofs=line.getLength(), ufdd->appendLine(line), line0ofs!=line.getLength())) { char const *thisline=line()+line0ofs; line.term0(); // printf("line: %s", thisline); if (thisline[0]=='\n' || thisline[0]=='\r') continue; /* empty line */ if (thisline[0]=='%' && thisline[1]=='!') continue; /* %!PS-... */ if (thisline[0]!='%' || thisline[1]!='%') break; /* non-ADSC comment */ if (had<3 && 4==sscanf(thisline+2, "ExactBoundingBox:%lg%lg%lg%lg", &llx, &lly, &urx, &ury)) had=3; else if (had<2 && 4==sscanf(thisline+2, "HiResBoundingBox:%lg%lg%lg%lg", &llx, &lly, &urx, &ury)) had=2; else if (had<1 && 4==sscanf(thisline+2, "BoundingBox:%lg%lg%lg%lg", &llx, &lly, &urx, &ury)) had=1; /* Dat: finds MetaPost hiresbbox after %%EndComments */ // printf("line: %s", line()+line0ofs); } ufdd->unread(line(), line.getLength()); line.clearFree(); char bboxline[400]; if (had!=0) { // fprintf(stderr, "bbox=[%"PTS_CFG_PRINTFGLEN"g %"PTS_CFG_PRINTFGLEN"g %"PTS_CFG_PRINTFGLEN"g %"PTS_CFG_PRINTFGLEN"g]\n", llx, lly, urx, ury); /* Dat: we must call translate _after_ setpagedevice (so it will take effect), at least with ESP Ghostscript 7.05.6 (2003-02-05); BUGFIX at Fri Aug 12 22:49:07 CEST 2005 */ sprintf(bboxline, "<>setpagedevice\n" /* removing /PageSize also cancels /a4, /a5 etc. */ /* we need `currentmatrix ... setpagedevice setmatrix' because * setpagedevice cancels the current transformation matrix so our * `translate' below would be canceled if the EPS file contains * `a5', `setpagedevice' etc. */ "/setpagedevice{matrix currentmatrix exch " "dup length dict copy dup /PageSize undef setpagedevice " "setmatrix}bind def\n" "%"PTS_CFG_PRINTFGLEN"g %"PTS_CFG_PRINTFGLEN"g translate\n" , urx-llx, ury-lly, -llx, -lly); } else { Error::sev(Error::WARNING) << "in_eps_reader: missing EPS bbox" << (Error*)0; bboxline[0]='\0'; } return in_ps_reader_low(ufd, bboxline, hints); } static Image::Loader::reader_t in_ps_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { if (0!=memcmp(buf,"%!PS-Adobe-",11)) return 0; char const *p=buf+11, *pend=buf+Image::Loader::MAGIC_LEN; while (p!=pend && *p!=' ' && *p!='\t') p++; while (p!=pend && (*p==' ' || *p=='\t')) p++; /* Imp: option to accept BoundingBox for non-EPS PS */ return (0==strncmp(p,"EPSF-",5)) ? in_eps_reader : in_ps_reader; /* ^^^ BUGFIX at Fri Nov 26 12:13:58 CET 2004 */ /* ^^^ BUGFIX again at Thu Jan 6 10:25:54 CET 2005 */ } #else #define in_ps_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_PS */ Image::Loader in_ps_loader = { "PS", in_ps_checker, 0 }; #if USE_IN_PDF static Image::Sampled *in_pdf_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const& hints) { // Error::sev(Error::EERROR) << "Cannot load PDF images yet." << (Error*)0; SimBuffer::B cmd; add_gs_cmd(cmd,hints); cmd << " -- %S"; /* Dat: -dSAFER won't let me open the file with `/' under ESP Ghostscript 7.05.6 (2003-02-05) */ /* Imp: win9X command line too long? */ fprintf(stderr, "gs_cmd=(%s)\n", cmd.term0()()); HelperE helper(cmd.term0()()); /* Run external process GS */ Encoder::writeFrom(*(Filter::PipeE*)&helper, *(Filter::UngetFILED*)ufd); ((Filter::PipeE*)&helper)->vi_write(0,0); /* Signal EOF */ return helper.getImg(); } static Image::Loader::reader_t in_pdf_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return 0==memcmp(buf,"%PDF-",5) ? in_pdf_reader : 0; } #else #define in_pdf_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_PDF */ Image::Loader in_pdf_loader = { "PDF", in_pdf_checker, 0 }; sam2p-0.49.2/pts_defl.c0000644000175100017510000041272612211371426013007 0ustar ptspts#define DUMMY \ set -ex; \ "${CC:-gcc}" -DNDEBUG=1 -DPTS_DEFL_MAIN -O3 -ansi \ -Wall -W -Wstrict-prototypes -Wtraditional -Wnested-externs -Winline \ -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \ -Wmissing-declarations pts_defl.c -o flateenc; \ exit /* * pts_defl.c -- C source file ZIP compression ripped from linux-2.6.8.1 * by pts@fazekas.hu at Tue Jan 18 15:19:06 CET 2005 * * This ZIP compression (ZIP == PostScript /FlateEncode compression filter * (ZLIB RFC 1950)) routine has been ripped from the Linux kernel 2.6.8.1 * (directory lib/zlib_deflate), which has been ripped from ZLIB 1.1.3 * * To have a UNIX filter program (stdin -> stdout), compile zipfilt.c * * Dat: the exported symbols are: zlib_deflate zlib_deflateEnd * zlib_deflateInit_ zlib_deflateInit2_ zlib_deflateParams * zlib_deflate_workspacesize * */ /* ---- by pts */ /* +++ deflate.c */ /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in ftp://ds.internic.net/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ #if 0 /**** pts ****/ # include #endif /**** pts ****/ #if OBJDEP /* sam2p */ # warning PROVIDES: pts_defl #endif #if HAVE_CONFIG2_H /* sam2p */ # include "config2.h" #endif /* #include */ /* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-1998 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id: pts_defl.c,v 1.6 2008/08/28 20:16:47 pts Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H #if 0 /**** pts ****/ # include #else # include "pts_defl.h" #endif #if 0 /**** pts ****/ # include # include # include #endif /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.1.3, July 9th, 1998 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ /*#include */ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1998 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id: pts_defl.c,v 1.6 2008/08/28 20:16:47 pts Exp $ */ /*#ifndef _ZCONF_H*/ /*#define _ZCONF_H*/ #ifndef NULLP /**** pts ****/ #define NULLP ((void*)0) /* Imp: g++, with const */ #endif #if 0 /**** pts ****/ /* Dat: `inline' is not ANSI C */ # define ZINLINE inline #else # define ZINLINE #endif #define ZSTATIC static /**** pts ****/ /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # define MAX_MEM_LEVEL 8 #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* Type declarations */ typedef unsigned char Byte; /* 8 bits */ typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ typedef void *voidp; /*#endif*/ /* _ZCONF_H */ /* end of linux/zconf.h */ #if 0 #define ZLIB_VERSION "1.1.3" #endif /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ #if 0 struct zlib_internal_state; /**** pts ****/ /* Dat: was: internal_state */ typedef struct z_stream_s { Byte *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Byte *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULLP if no error */ struct zlib_internal_state *state; /* not visible by applications */ void *workspace; /* memory allocated for this stream */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return NULLP if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ #endif typedef z_stream *z_streamp; /* constants */ #if 0 #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_PACKET_FLUSH 2 #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #endif #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #if 0 #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ #endif #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ /* basic functions */ extern const char * zlib_zlibVersion (void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ extern int zlib_deflate_workspacesize (void); /* Returns the number of bytes that needs to be allocated for a per- stream workspace. A pointer to this number of bytes should be returned in stream->workspace before calling zlib_deflateInit(). */ /* extern int deflateInit (z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to NULLP, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ extern int zlib_deflate (z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least 0.1% larger than avail_in plus 12 bytes. If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update data_type if it can make a good guess about the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULLP), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). */ extern int zlib_deflateEnd (z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ extern int zlib_inflate_workspacesize (void); /* Returns the number of bytes that needs to be allocated for a per- stream workspace. A pointer to this number of bytes should be returned in stream->workspace before calling zlib_inflateInit(). */ /* extern int zlib_inflateInit (z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, and workspace must be initialized before by the caller. If next_in is not NULLP and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to NULLP, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ extern int zlib_inflate (z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may some introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_SYNC_FLUSH and Z_FINISH, but the current implementation actually flushes as much output as possible anyway. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call. If a preset dictionary is needed at this point (see inflateSetDictionary below), inflate sets strm-adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULLP), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then call inflateSync to look for a good compression block. */ extern int zlib_inflateEnd (z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* extern int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string match). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ extern int zlib_deflateSetDictionary (z_streamp strm, const Byte *dictionary, uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. Upon return of this function, strm->adler is set to the Adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULLP dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ extern int zlib_deflateCopy (z_streamp dest, z_streamp source); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULLP). msg is left unchanged in both source and destination. */ extern int zlib_deflateReset (z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULLP). */ extern int zlib_deflateParams (z_streamp strm, int level, int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ /* extern int inflateInit2 (z_streamp strm, int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memLevel). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ extern int zlib_inflateSetDictionary (z_streamp strm, const Byte *dictionary, uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the Adler32 value returned by this call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULLP dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect Adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ extern int zlib_inflateSync (z_streamp strm); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ extern int zlib_inflateReset (z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULLP). */ extern int zlib_inflateIncomp (z_stream *strm); /* This function adds the data at next_in (avail_in bytes) to the output history without performing any output. There must be no pending output, and the decompressor must be expecting to see the start of a block. Calling this function is equivalent to decompressing a stored block containing the data at next_in (except that the data is not output). */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ extern int zlib_deflateInit_ (z_streamp strm, int level, const char *version, int stream_size); extern int zlib_inflateInit_ (z_streamp strm, const char *version, int stream_size); extern int zlib_deflateInit2_ (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); extern int zlib_inflateInit2_ (z_streamp strm, int windowBits, const char *version, int stream_size); #if 0 /**** pts ****/ #define zlib_deflateInit(strm, level) \ zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define zlib_inflateInit(strm) \ zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define zlib_inflateInit2(strm, windowBits) \ zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #endif #if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) struct zlib_internal_state {int dummy;}; /* hack for buggy compilers */ #endif extern const char * zlib_zError (int err); extern int zlib_inflateSyncPoint (z_streamp z); extern const uLong * zlib_get_crc_table (void); /**** pts ****/ #define max(a,b) ((a)<(b) ? (b) : (a)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ /* Common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif /* functions */ typedef uLong (*check_func) (uLong check, const Byte *buf, uInt len); /* checksum functions */ #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULLP, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, NULLP, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ static ZINLINE uLong zlib_adler32(uLong adler, const Byte *buf, uInt len) { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == NULLP) return 1L; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } #endif /* _Z_UTIL_H */ /* end of zutil.h */ /* #include "defutil.h" */ #define Assert(err, str) #define Trace(dummy) #define Tracev(dummy) #define Tracecv(err, dummy) #define Tracevv(dummy) #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } tree_desc; typedef ush Pos; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct deflate_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Byte *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Byte *pending_out; /* next pending byte to output to the stream */ int pending; /* nb of bytes in the pending buffer */ int noheader; /* suppress zlib header and adler32 */ Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Byte *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Pos *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Pos *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uch *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ush *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ ulg compressed_len; /* total bit length of compressed file */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG_ZLIB ulg bits_sent; /* bit length of the compressed data */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } deflate_state; typedef struct deflate_workspace { /* State memory for the deflator */ deflate_state deflate_memory; Byte window_memory[2 * (1 << MAX_WBITS)]; Pos prev_memory[1 << MAX_WBITS]; Pos head_memory[1 << (MAX_MEM_LEVEL + 7)]; char overlay_memory[(1 << (MAX_MEM_LEVEL + 6)) * (sizeof(ush)+2)]; } deflate_workspace; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ ZSTATIC void zlib_tr_init (deflate_state *s); ZSTATIC int zlib_tr_tally (deflate_state *s, unsigned dist, unsigned lc); ZSTATIC ulg zlib_tr_flush_block (deflate_state *s, char *buf, ulg stored_len, int eof); ZSTATIC void zlib_tr_align (deflate_state *s); ZSTATIC void zlib_tr_stored_block (deflate_state *s, char *buf, ulg stored_len, int eof); ZSTATIC void zlib_tr_stored_type_only (deflate_state *); /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ static ZINLINE unsigned bi_reverse(unsigned code, /* the value to invert */ int len) /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ static ZINLINE void bi_flush(deflate_state *s) { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ static ZINLINE void bi_windup(deflate_state *s) { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG_ZLIB s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* end of defutil.h */ #if USE_ZLIB_MEM # include /* memcpy(), memset() */ # define zmemcpy(a,b,c) memcpy(a,b,c) # define zmemset(a,b,c) memset(a,b,c) #else static void *zmemcpy(void * dest,const void *src,unsigned count) { char *tmp = (char *) dest; char const *s = (char const*) src; while (count--) *tmp++ = *s++; return dest; } static void *zmemset(void * s,int c,unsigned count) { char *xs = (char *) s; while (count--) *xs++ = c; return s; } #endif /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) (deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ static void fill_window (deflate_state *s); static block_state deflate_stored (deflate_state *s, int flush); static block_state deflate_fast (deflate_state *s, int flush); static block_state deflate_slow (deflate_state *s, int flush); static void lm_init (deflate_state *s); static void putShortMSB (deflate_state *s, uInt b); static void flush_pending (z_streamp strm); static int read_buf (z_streamp strm, Byte *buf, unsigned size); static uInt longest_match (deflate_state *s, IPos cur_match); #ifdef DEBUG_ZLIB static void check_match (deflate_state *s, IPos start, IPos match, int length); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; static const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int zlib_deflateInit_( z_streamp strm, int level, const char *version, int stream_size ) { return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int zlib_deflateInit2_( z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size ) { deflate_state *s; int noheader = 0; static char my_version[] = ZLIB_VERSION; deflate_workspace *mem; ush *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == NULLP || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == NULLP) return Z_STREAM_ERROR; strm->msg = (char*)NULLP; /**** pts ****/ if (level == Z_DEFAULT_COMPRESSION) level = 6; mem = (deflate_workspace *) strm->workspace; if (windowBits < 0) { /* undocumented feature: suppress zlib header */ noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } s = (deflate_state *) &(mem->deflate_memory); strm->state = (struct zlib_internal_state *)s; s->strm = strm; s->data_type=strm->data_type; /**** pts ****/ /* BUGFIX at Tue Jan 18 16:01:08 CET 2005 */ /* Imp: report this bugfix to the Linux kernel */ s->noheader = noheader; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Byte *) mem->window_memory; s->prev = (Pos *) mem->prev_memory; s->head = (Pos *) mem->head_memory; s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ush *) mem->overlay_memory; s->pending_buf = (uch *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return zlib_deflateReset(strm); } #if 0 /**** pts ****/ /* ========================================================================= */ int zlib_deflateSetDictionary( z_streamp strm, const Byte *dictionary, uInt dictLength ) { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == NULLP || strm->state == NULLP || dictionary == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (s->status != INIT_STATE) return Z_STREAM_ERROR; strm->adler = zlib_adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > MAX_DIST(s)) { length = MAX_DIST(s); #ifndef USE_DICT_HEAD dictionary += dictLength - length; /* use the tail of the dictionary */ #endif } zmemcpy((char *)s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } #endif /* ========================================================================= */ int zlib_deflateReset( z_streamp strm ) { deflate_state *s; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; strm->total_in = strm->total_out = 0; strm->msg = (char*)NULLP; strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->noheader < 0) { s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ } s->status = s->noheader ? BUSY_STATE : INIT_STATE; strm->adler = 1; s->last_flush = Z_NO_FLUSH; zlib_tr_init(s); lm_init(s); return Z_OK; } #if 0 /**** pts ****/ /* ========================================================================= */ int zlib_deflateParams( z_streamp strm, int level, int strategy ) { deflate_state *s; compress_func func; int err = Z_OK; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if (func != configuration_table[level].func && strm->total_in != 0) { /* Flush the last buffer: */ err = zlib_deflate(strm, Z_PARTIAL_FLUSH); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } #endif /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ static void putShortMSB( deflate_state *s, uInt b ) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ static void flush_pending( z_streamp strm ) { deflate_state *s = (deflate_state *) strm->state; unsigned len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; if (strm->next_out != NULLP) { zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; } s->pending_out += len; strm->total_out += len; strm->avail_out -= len; s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } /* ========================================================================= */ int zlib_deflate( z_streamp strm, int flush ) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == NULLP || strm->state == NULLP || flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } s = (deflate_state *) strm->state; if ((strm->next_in == NULLP && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { return Z_STREAM_ERROR; } if (strm->avail_out == 0) return Z_BUF_ERROR; s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the zlib header */ if (s->status == INIT_STATE) { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags = (s->level-1) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = 1L; } /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUFF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { return Z_BUF_ERROR; } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { return Z_BUF_ERROR; } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { zlib_tr_align(s); } else if (flush == Z_PACKET_FLUSH) { /* Output just the 3-bit `stored' block type value, but not a zero length. */ zlib_tr_stored_type_only(s); } else { /* FULL_FLUSH or SYNC_FLUSH */ zlib_tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->noheader) return Z_STREAM_END; /* Write the zlib trailer (adler32) */ putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ s->noheader = -1; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int zlib_deflateEnd( z_streamp strm ) { int status; deflate_state *s; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; status = s->status; if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } strm->state = (struct zlib_internal_state*)NULLP; /**** pts ****/ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } #if 0 /**** pts ****/ /* ========================================================================= * Copy the source state to the destination state. */ int zlib_deflateCopy ( z_streamp dest, z_streamp source ) { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ush *overlay; deflate_workspace *mem; if (source == NULLP || dest == NULLP || source->state == NULLP) { return Z_STREAM_ERROR; } ss = (deflate_state *) source->state; *dest = *source; mem = (deflate_workspace *) dest->workspace; ds = &(mem->deflate_memory); dest->state = (struct zlib_internal_state *) ds; *ds = *ss; ds->strm = dest; ds->window = (Byte *) mem->window_memory; ds->prev = (Pos *) mem->prev_memory; ds->head = (Pos *) mem->head_memory; overlay = (ush *) mem->overlay_memory; ds->pending_buf = (uch *) overlay; zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif } #endif /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ static int read_buf( z_streamp strm, Byte *buf, unsigned size ) { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (!((deflate_state *)(strm->state))->noheader) { strm->adler = zlib_adler32(strm->adler, strm->next_in, len); } zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ static void lm_init( deflate_state *s ) { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; } /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ static uInt longest_match( deflate_state *s, IPos cur_match /* current match */ ) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Byte *scan = s->window + s->strstart; /* current string */ register Byte *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Pos *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Byte *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ush*)scan; register ush scan_end = *(ush*)(scan+best_len-1); #else register Byte *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ush*)(match+best_len-1) != scan_end || *(ush*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ush*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return best_len; return s->lookahead; } #ifdef DEBUG_ZLIB /* =========================================================================== * Check that the match at match_start is indeed a match. */ static void check_match( deflate_state *s, IPos start, IPos match, int length ) { /* check that the match is indeed a match */ if (memcmp((char *)s->window + match, (char *)s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ static void fill_window( deflate_state *s ) { register unsigned n, m; register Pos *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) */ more--; /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ } else if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy((char *)s->window, (char *)s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, eof) { \ zlib_tr_flush_block(s, (s->block_start >= 0L ? \ (char *)&s->window[(unsigned)s->block_start] : \ (char *)/****pts****/NULLP), \ (ulg)((long)s->strstart - s->block_start), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, eof) { \ FLUSH_BLOCK_ONLY(s, eof); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ static block_state deflate_stored( deflate_state *s, int flush ) { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ static block_state deflate_fast( deflate_state *s, int flush ) { IPos hash_head = NIL; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); bflush = zlib_tr_tally(s, s->strstart - s->match_start, s->match_length - MIN_MATCH); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in hash table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); bflush = zlib_tr_tally (s, 0, s->window[s->strstart]); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ static block_state deflate_slow( deflate_state *s, int flush ) { IPos hash_head = NIL; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR))) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); bflush = zlib_tr_tally(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); if (zlib_tr_tally (s, 0, s->window[s->strstart-1])) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); zlib_tr_tally (s, 0, s->window[s->strstart-1]); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } int zlib_deflate_workspacesize(void) { return sizeof(deflate_workspace); } /* +++ trees.c */ /* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ /* #include "deflate.h" */ #if 0 /**** pts ****/ # include # include "defutil.h" # ifdef DEBUG_ZLIB # include # endif #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; static const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; static const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; static const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ static ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see zlib_tr_init * below). */ static ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ static uch dist_code[512]; /* distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ static uch length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ static int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ static int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULLP */ const int *extra_bits; /* extra bits for each code or NULLP */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; static static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; static static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; static static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ static void tr_static_init (void); static void init_block (deflate_state *s); static void pqdownheap (deflate_state *s, ct_data *tree, int k); static void gen_bitlen (deflate_state *s, tree_desc *desc); static void gen_codes (ct_data *tree, int max_code, ush *bl_count); static void build_tree (deflate_state *s, tree_desc *desc); static void scan_tree (deflate_state *s, ct_data *tree, int max_code); static void send_tree (deflate_state *s, ct_data *tree, int max_code); static int build_bl_tree (deflate_state *s); static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); static void compress_block (deflate_state *s, ct_data *ltree, ct_data *dtree); static void set_data_type (deflate_state *s); static unsigned bi_reverse (unsigned value, int length); static void bi_windup (deflate_state *s); static void bi_flush (deflate_state *s); static void copy_block (deflate_state *s, char *buf, unsigned len, int header); #ifndef DEBUG_ZLIB # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG_ZLIB */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif #define d_code(dist) \ ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. dist_code[256] and dist_code[257] are never * used. */ /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG_ZLIB static void send_bits (deflate_state *s, int value, int length); static void send_bits( deflate_state *s, int value, /* value to send */ int length /* number of bits */ ) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (value << s->bi_valid); put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG_ZLIB */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (val << s->bi_valid);\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG_ZLIB */ /* =========================================================================== * Initialize the various 'constant' tables. In a multi-threaded environment, * this function may be called by two threads concurrently, but this is * harmless since both invocations do exactly the same thing. */ static void tr_static_init(void) { static int static_init_done; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; } /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ ZSTATIC void zlib_tr_init( deflate_state *s ) { tr_static_init(); s->compressed_len = 0L; s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG_ZLIB s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ static void init_block( deflate_state *s ) { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ static void pqdownheap( deflate_state *s, ct_data *tree, /* the tree to restore */ int k /* node to move down */ ) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ static void gen_bitlen( deflate_state *s, tree_desc *desc /* the tree descriptor */ ) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const int *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ static void gen_codes( ct_data *tree, /* the tree to decorate */ int max_code, /* largest code with non zero frequency */ ush *bl_count /* number of codes at each bit length */ ) { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch) (max(s->depth[n], s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ static void scan_tree( deflate_state *s, ct_data *tree, /* the tree to be scanned */ int max_code /* and its largest code of non zero frequency */ ) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ static void send_tree( deflate_state *s, ct_data *tree, /* the tree to be scanned */ int max_code /* and its largest code of non zero frequency */ ) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ static int build_bl_tree( deflate_state *s ) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ static void send_all_trees( deflate_state *s, int lcodes, /* number of codes for each tree */ int dcodes, /* number of codes for each tree */ int blcodes /* number of codes for each tree */ ) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ ZSTATIC void zlib_tr_stored_block( deflate_state *s, char *buf, /* input block */ ulg stored_len, /* length of input block */ int eof /* true if this is the last block for a file */ ) { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* Send just the `stored block' type code without any length bytes or data. */ ZSTATIC void zlib_tr_stored_type_only( deflate_state *s ) { send_bits(s, (STORED_BLOCK << 1), 3); bi_windup(s); s->compressed_len = (s->compressed_len + 3) & ~7L; } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ ZSTATIC void zlib_tr_align( deflate_state *s ) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ ZSTATIC ulg zlib_tr_flush_block( deflate_state *s, char *buf, /* input block, or NULLP if too old */ ulg stored_len, /* length of input block */ int eof /* true if this is the last block for a file */ ) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is ascii or binary */ if (s->data_type == Z_UNKNOWN) set_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute first the block length in bytes*/ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } /* If compression failed and this is the first and last block, * and if the .zip file can be seeked (to rewrite the local header), * the whole file is transformed into a stored file: */ #ifdef STORED_FILE_OK # ifdef FORCE_STORED_FILE if (eof && s->compressed_len == 0L) { /* force stored file */ # else if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { # endif /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (char*)0) error ("block vanished"); copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ s->compressed_len = stored_len << 3; s->method = STORED; } else #endif /* STORED_FILE_OK */ #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULLP is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ zlib_tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); s->compressed_len += 3 + s->static_len; } else { send_bits(s, (DYN_TREES<<1)+eof, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); s->compressed_len += 3 + s->opt_len; } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); init_block(s); if (eof) { bi_windup(s); s->compressed_len += 7; /* align on byte boundary */ } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); return s->compressed_len >> 3; } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ ZSTATIC int zlib_tr_tally( deflate_state *s, unsigned dist, /* distance of matched string */ unsigned lc /* match length-MIN_MATCH or unmatched char (if dist==0) */ ) { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "zlib_tr_tally: bad match"); s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0xfff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ static void compress_block( deflate_state *s, ct_data *ltree, /* literal tree */ ct_data *dtree /* distance tree */ ) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Set the data type to ASCII or BINARY, using a crude approximation: * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * IN assertion: the fields freq of dyn_ltree are set and the total of all * frequencies does not exceed 64K (to fit in an int on 16 bit machines). */ static void set_data_type( deflate_state *s ) { int n = 0; unsigned ascii_freq = 0; unsigned bin_freq = 0; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ static void copy_block( deflate_state *s, char *buf, /* the input data */ unsigned len, /* its length */ int header /* true if block header must be written */ ) { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG_ZLIB s->bits_sent += 2*16; #endif } #ifdef DEBUG_ZLIB s->bits_sent += (ulg)len<<3; #endif /* bundle up the put_byte(s, *buf++) calls */ zmemcpy(&s->pending_buf[s->pending], buf, len); s->pending += len; } /* end of deftree.c */ /* ---- by pts */ #if PTS_DEFL_MAIN /* * Usage: flateenc [-] < > * is one of: 0: no compression; 1: low & fast; 9: high & slow */ #include "pts_defl.h" #include /* read(), write() */ #include #include /* abort() */ int main(int argc, char **argv) { char ibuf[4096], obuf[6000]; /* Dat: 4096->6000 should be enough */ char workspace[sizeof(deflate_workspace)]; /* Dat: as returned by zlib_deflate_workspacesize in ZLIB 1.1.3 */ int got, zgot; /** Compression level: 0..9 or Z_DEFAULT_COMPRESSION */ int level=Z_DEFAULT_COMPRESSION; z_stream zs; (void)argc; if (argv && argv[0] && argv[1] && argv[1][0]=='-' && argv[1][1]>='0' && argv[1][1]<='9') level=argv[1][1]-'0'; /* printf("ws=%d\n", zlib_deflate_workspacesize()); */ if (zlib_deflate_workspacesize()+(unsigned)00 && got!=write(1, zs.next_out-got, got)) abort(); } if (0!=got) abort(); do { /* flush all output */ zs.next_in=NULL; zs.avail_in=0; zs.next_out=obuf; zs.avail_out=sizeof(obuf); if (Z_STREAM_END!=(zgot=zlib_deflate(&zs, Z_FINISH)) && Z_OK!=zgot) abort(); #ifdef DEBUG_PTS_DEFL fprintf(stderr, "ai=%d ao=%d flush\n", zs.avail_in, zs.avail_out); #endif got=sizeof(obuf)-zs.avail_out; if (got>0 && got!=write(1, zs.next_out-got, got)) abort(); } while (zgot==Z_OK); if (Z_OK!=zlib_deflateEnd(&zs)) abort(); return 0; } #endif sam2p-0.49.2/pts_defl.h0000644000175100017510000000716512211371426013011 0ustar ptspts/* * pts_defl.h -- C header file ZIP compression ripped from linux-2.6.8.1 * by pts@fazekas.hu at Tue Jan 18 15:19:06 CET 2005 * * This ZIP compression (ZIP == PostScript /FlateEncode compression filter * (ZLIB RFC 1950)) routine has been ripped from the Linux kernel 2.6.8.1 * (directory lib/zlib_deflate), which has been ripped from ZLIB 1.1.3 * * This is a minimal .h file, to avoid namespace pollution. * See more in the beginning of pts_defl.c * For documentation comments, see pts_defl.c * */ #ifndef PTS_DEFL_H #define PTS_DEFL_H #define PTS_DEFL_RIPPED_ZLIB 1 /** Must be at least zlib_deflate_workspacesize(): 267946 on Linux i386 */ #define ZLIB_DEFLATE_WORKSPACESIZE_MIN 270000 #define ZLIB_VERSION "1.1.3" #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_PACKET_FLUSH 2 #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ struct zlib_internal_state; /**** pts ****/ /* Dat: was: internal_state */ typedef struct z_stream_s { unsigned char *next_in; /* next input byte */ unsigned int avail_in; /* number of bytes available at next_in */ unsigned long total_in; /* total nb of input bytes read so far */ unsigned char *next_out; /* next output byte should be put there */ unsigned int avail_out; /* remaining free space at next_out */ unsigned long total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULLP if no error */ struct zlib_internal_state *state; /* not visible by applications */ void *workspace; /* memory allocated for this stream */ int data_type; /* best guess about the data type: ascii or binary */ unsigned long adler; /* adler32 value of the uncompressed data */ unsigned long reserved; /* reserved for future use */ } z_stream; #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif EXTERN_C int zlib_deflate_workspacesize (void); EXTERN_C int zlib_deflate (z_stream* strm, int flush); EXTERN_C int zlib_deflateEnd (z_stream* strm); EXTERN_C int zlib_deflateParams (z_stream* strm, int level, int strategy); EXTERN_C int zlib_deflateInit_ (z_stream* strm, int level, const char *version, int stream_size); EXTERN_C int zlib_deflateInit2_ (z_stream* strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); #define zlib_deflateInit(strm, level) \ zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #endif sam2p-0.49.2/in_tga.cpp0000644000175100017510000000346112211371426013000 0ustar ptspts/* * in_tga.cpp -- read a Truevision Targa TGA file * by pts@fazekas.hu at Sat Mar 2 00:49:35 CET 2002 * */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #include "gensio.hpp" /* Filter::UngetFILED */ #if USE_IN_TGA #include "input-tga.ci" /* defines tga_load_image */ static Image::Sampled *in_tga_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; bitmap_type bitmap=tga_load_image(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else assert(0 && "invalid TGA depth"); delete [] BITMAP_BITS(bitmap); return ret; } static Image::Loader::reader_t in_tga_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { /* vvv Unfortunately not all targa images have that footer */ /* return 0==memcmp(bufend+Image::Loader::MAGIC_LEN-18, "TRUEVISION-XFILE", 16) */ /* vvv 30..127: Aladdin Ghostscript adds 58 bytes of header */ return (unsigned char)buf[0]>=30 && (unsigned char)buf[0]<=63 && (unsigned char)buf[1]<=11 && ((unsigned char)buf[16]<=8 || (unsigned char)buf[16]==24) ? in_tga_reader : 0; } #else #define in_tga_checker NULLP #endif /* USE_IN_XPM */ Image::Loader in_tga_loader = { "TGA", in_tga_checker, 0 }; sam2p-0.49.2/in_tiff.cpp0000644000175100017510000000437112211371426013156 0ustar ptspts/* * in_tiff.cpp -- read TIFF (Tag Image File Format) files with tif22pnm * by pts@fazekas.hu at Sun Apr 14 14:50:30 CEST 2002 */ /* Imp: get docs about the TIFF format, and rewrite this from scratch */ /* Imp: use xviff.c */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_TIFF #include "error.hpp" #include "gensio.hpp" #include "helpere.hpp" #include /* memchr() */ #include /* printf() */ static Image::Sampled *in_tiff_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { // Error::sev(Error::EERROR) << "Cannot load TIFF images yet." << (Error*)0; // HelperE helper("tifftopnm %S"); /* Cannot extract alpha channel */ // HelperE helper("tif22pnm -rgba %S"); /* tif22pnm <= 0.07 */ char const *cmd= #if OS_COTY==COTY_WIN9X || OS_COTY==COTY_WINNT #if 0 /* unsafe if both tifftopnm and png22pnm exist */ "tifftopnm <%S >%D\ntif22pnm -rgba %S pnm: %D"; /* slow but safe */ #else "tif22pnm -rgba %S pnm:"; #endif #else #if OS_COTY==COTY_UNIX #if 1 "(tif22pnm -rgba %S pnm: || tifftopnm %S)"; #else /* Dat: not using this to suppress `sh: tif22pnm: command not found', because * it would hide precious error messages printed by tif22pnm. */ "((tif22pnm -rgba %S pnm: 2>/dev/null)|| tifftopnm %S)"; #endif #else "tif22pnm -rgba %S pnm:"; /* Wants to seek in the file. */ #endif #endif HelperE helper(cmd); Encoder::writeFrom(*(Filter::PipeE*)&helper, *(Filter::UngetFILED*)ufd); ((Filter::PipeE*)&helper)->vi_write(0,0); /* Signal EOF */ return helper.getImg(); } static Image::Loader::reader_t in_tiff_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { /* MM\x00\x2a: TIFF image data, big-endian * II\x2a\x00: TIFF image data, little-endian * The second word of TIFF files is the TIFF version number, 42, which has * never changed. The TIFF specification recommends testing for it. */ return (0==memcmp(buf,"MM\x00\x2a",4) || 0==memcmp(buf,"II\x2a\x00",4)) ? in_tiff_reader : 0; } #else #define in_tiff_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_XPM */ Image::Loader in_tiff_loader = { "TIFF", in_tiff_checker, 0 }; sam2p-0.49.2/in_xpm.cpp0000644000175100017510000003413412212351433013027 0ustar ptspts/* * in_xpm.cpp -- read an XPM file * by pts@math.bme.hu at Fri Mar 1 09:56:54 CET 2002 */ /* Imp: test this code with various xpm files! */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_XPM #if OBJDEP # warning REQUIRES: mapping.o #endif #ifndef USE_BIG_MEMORY #define USE_BIG_MEMORY 0 #endif #include "mapping.hpp" #include "error.hpp" #include "xpmc.h" #include /* memchr() */ #include "gensio.hpp" #define USGE(a,b) ((unsigned char)(a))>=((unsigned char)(b)) #if 0 /** @return true iff params are different strings (not respecting case) */ static int my_strcase_neq(char *s1, char *s2) { while ((USGE(*s1,'A') && USGE('Z',*s1) ? *s1+'a'-'A' : *s1) == (USGE(*s2,'A') && USGE('Z',*s2) ? *s2+'a'-'A' : *s2)) { if (*s1=='\0') return 0; s1++; s2++; } return 1; } #endif #define my_strcase_neq(s1,s2) GenBuffer::nocase_strcmp(s1,s2) /** @ return RGB long */ static Image::Sampled::rgb_t parse_rgb(char const*s) { unsigned v=0, len; Image::Sampled::rgb_t ret; if (!s || !*s) return 0x2000000; /* not found */ // fprintf(stderr, "'%s'\n", s); if (*s=='#') { /* an #RRGGBB web-style color spec; or #RRRRGGGGBBBB */ unsigned dif=0; ++s; while (dif<13 && (USGE(5,(s[dif]|32)-'a') || USGE(9,s[dif]-'0'))) dif++; /* find at most 13 hex digits */ if (s[dif]!='\0' || (dif!=12 && dif!=6)) return 0x2000000; /* not found, spec length error */ dif=(dif==12) ? 3 : 1; // shr=24; while (shr!=0) { ret= (Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<20; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<16; s+=dif; /* ignore lower two hex digits of 16-bit sample value */ ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<12; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<8; s+=dif; /* ignore lower two hex digits of 16-bit sample value */ ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<4; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' ); return ret; } /* vvv 223==255-32: ignore case when hashing */ char const *p=s; while (*p!='\0') v=xpmColors_mul*v+(223&*(unsigned char const*)p++); p=xpmColors_dat+xpmColors_ofs[(v&65535)%xpmColors_mod]; while (*p!='\0') { len=strlen(p); if (0==my_strcase_neq(p,s)) { p+=len; ret=(((Image::Sampled::rgb_t)((unsigned char const*)p)[1])<<16)+ (((Image::Sampled::rgb_t)((unsigned char const*)p)[2])<<8)+ (((Image::Sampled::rgb_t)((unsigned char const*)p)[3])); return (ret==0x30201) ? 0x1000000 : ret; /* transparent color */ } p+=len+4; } return 0x2000000; /* not found */ } class XPMTok { public: /* Imp: report line numbers on errors */ BEGIN_STATIC_ENUM1(int) T_NO_UNGOT=-1, T_COMMA=257 /* The comma token, outside strings. */ END_STATIC_ENUM() /* XPM states */ BEGIN_STATIC_ENUM1(char) ST_OUT=0, /* outside s string */ ST_STR=1, /* inside a string */ ST_EOF=2 /* EOF */ END_STATIC_ENUM() int getcc(); /** Reads an unsigned int. */ Image::Sampled::dimen_t getDimen(); Image::Sampled::rgb_t getColor(); void read(char *buf, unsigned len); inline void readInStr(char *buf, unsigned len); inline XPMTok(FILE *f_): f(f_), state(ST_OUT), ungot(T_NO_UNGOT) {} inline void ungetcc(int c) { if (c>=0) ungot=c; } void getComma(); protected: FILE *f; /** Current state. */ char state; int ungot; }; int XPMTok::getcc() { int i; if (ungot>=0 /*T_NO_UNGOT<0*/) { i=ungot; ungot=T_NO_UNGOT; return i; } /* Imp: ignore C and C++ style comments (so we won't recognise strings inside comments) */ switch (state) { case ST_OUT: st_out: while (1) { switch ((i=MACRO_GETC(f))) { case -1: state=ST_EOF; return -1; case ',': return T_COMMA; case '"': state=ST_STR; goto st_str; default: /* ignore outside strings */ break; } } case ST_STR: st_str: i=MACRO_GETC(f); if (i==-1) { ue: Error::sev(Error::EERROR) << "XPM: unexpected EOF" << (Error*)0; } else if (i=='"') { state=ST_OUT; goto st_out; } else if (i=='\\') { if ((i=MACRO_GETC(f))==-1) goto ue; if (i=='\n') goto st_str; /* Imp: handle octal, hexadecimal, \n etc. */ } return i&255; default: return -1; } } Image::Sampled::dimen_t XPMTok::getDimen() { Image::Sampled::dimen_t ret=0, bak; int i; while ((i=getcc())==' ' || i=='\t') ; if (USGE(i,'0') && USGE('9',i)) { ret=i-'0'; while (USGE((i=getcc()),'0') && USGE('9',i)) { bak=ret; ret=ret*10+(i-'0'); if (ret/10!=bak) Error::sev(Error::EERROR) << "XPM: dimen overflow" << (Error*)0; } ungetcc(i); return ret; } else Error::sev(Error::EERROR) << "XPM: dimen expected" << (Error*)0; return 0; /*notreached*/ } void XPMTok::getComma() { if (getcc()!=T_COMMA) Error::sev(Error::EERROR) << "XPM: comma expected at " << ftell(f) << (Error*)0; } void XPMTok::read(char *buf, unsigned len) { int i; while (len--!=0) { i=getcc(); // fprintf(stderr,"i=%d\n", i); if (i>=0 && i<=255) *buf++=i; else Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; } } void XPMTok::readInStr(char *buf, unsigned len) { /* Dat: this is OK noew */ // assert(state==ST_STR); assert(ungot<0); param_assert(len>=1); if (state!=ST_STR) { len--; goto real; } int i; while (len--!=0) { if ((i=MACRO_GETC(f))>=0 && i<=255 && i!='"' && i!='\\') *buf++=i; else { assert(i>=0); ungetc(i,f); real: i=getcc(); // fprintf(stderr,"i=%d\n", i); if (i>=0 && i<=255) *buf++=i; else Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; } } } Image::Sampled::rgb_t XPMTok::getColor() { static char tmp[32]; int i; while ((i=getcc())==' ' || i=='\t') ; if (i=='g') { at_g: i=getcc(); if (i!='4') ungetcc(i); goto at_col; } else if (i=='c' || i=='m' || i=='b' || i=='s') { at_col: while ((i=getcc())==' ' || i=='\t') ; char *p=tmp, *pend=tmp+sizeof(tmp)-1; while (i>=33 && i<=126) { if (p==pend) goto cexp; /* color name too long */ *p++=i; i=getcc(); } *p='\0'; if (i==' ' || i=='\t') { /* Maybe another color will come */ while ((i=getcc())==' ' || i=='\t') ; if (i=='g') goto at_g; else if (i=='c' || i=='m' || i=='b' || i=='s') goto at_col; } if (i!=T_COMMA) goto cexp; Image::Sampled::rgb_t ret=parse_rgb(tmp); if (ret==0x2000000) Error::sev(Error::EERROR) << "XPM: unknown color: " << tmp << (Error*)0; return ret; } else { cexp: Error::sev(Error::EERROR) << "XPM: color expected" << (Error*)0; } return 0; /*notreached*/ } static Image::Sampled *in_xpm_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { // Error::sev(Error::EERROR) << "Cannot load XPM images yet." << (Error*)0; XPMTok tok(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); Image::Sampled::dimen_t wd=tok.getDimen(); Image::Sampled::dimen_t ht=tok.getDimen(); Image::Sampled::dimen_t colors=tok.getDimen(); Image::Sampled::dimen_t cpp=tok.getDimen(); /* chars per pixel */ /* width height ncolors cpp [x_hot y_hot] */ int i; /* multiple purpose */ while ((i=tok.getcc())==' ' || i=='\t' || USGE(9,i-'0')) ; tok.ungetcc(i); tok.getComma(); // Error::sev(Error::DEBUG) << "wd="<setTransp(transp); } else { ret=new Image::RGB(wd,ht,8); if (transp!=colors) Error::sev(Error::WARNING) << "XPM: too many colors, transparency blacked" << (Error*)0; } outbuf=ret->getRowbeg(); if (cpp==1) { /* Easy job: make an Indexed image; defer .packPal() */ assert(colors<=256); signed short bin[256], s; memset(bin, 255, sizeof(bin)); /* Make bin[*]=-1 */ for (i=0;(unsigned)isetPal(i, rgb[i]); bin[(unsigned char)tab[i]]=i; } assert(p==pend); while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { if ((i=tok.getcc())<0 || i>255) Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; if ((s=bin[i])<0) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=s; } } #if USE_BIG_MEMORY } else if (cpp==2 && colors<=256) { /* Similarly easy job: make an Indexed image; defer .packPal() */ signed short *bin=new short[65536], s; memset(bin, 255, sizeof(*bin) * 65536); /* Make bin[*]=-1 */ for (i=0,p=tab; (unsigned)isetPal(i, rgb[i]); bin[(p[0]<<8)+p[1]]=i; } assert(p==pend); while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { tok.readInStr(pend,2); if ((s=bin[(pend[0]<<8)+pend[1]])<0) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=s; } } delete [] bin; } else if (cpp==2 && colors<=65535) { Image::Sampled::rgb_t rgb1; unsigned short *bin=new unsigned short[65536], s; memset(bin, 255, sizeof(*bin) * 65536); /* Make bin[*]=max */ for (i=0,p=tab; (unsigned)igetRlen(); outbuf!=p; ) { tok.readInStr(pend,2); if ((s=bin[(pend[0]<<8)+pend[1]])==(unsigned short)-1) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=(rgb1=rgb[s])>>16; *outbuf++=rgb1>>8; *outbuf++=rgb1; } } delete [] bin; #endif /* USE_BIG_MEMORY */ } else { /* Now comes the slow, but general solution */ #if USE_IN_XPM_MAPPING /* use Mapping */ if (colors<=256) { Mapping::H h(1); char c; /* vvv `c' might become negative, but it is harmless */ for (p=tab,pend=tab+cpp*colors,c=0; p!=pend; p+=cpp,c++) h.set(p, cpp, &c); /* every color-string should be unique; but no error message if it isn't */ while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { tok.readInStr(pend,cpp); if (NULLP==(pend=h.get(pend, cpp))) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=*pend; } } } else { /* most general case with Mapping */ if (transp!=colors) Error::sev(Error::WARNING) << "XPM: too many colors, transparency blacked" << (Error*)0; /* Dat: reading a JPEG downsampled to a 256-color XPM takes 3000 ms * with Mapping, and 31000 ms without mapping. Nice speed increase. */ Mapping::H h(3); char tmpcol[3]; for (p=tab,pend=tab+cpp*colors,rp=rgb; p!=pend; p+=cpp,rp++) { tmpcol[0]=rp[0]>>16; tmpcol[1]=rp[0]>>8; tmpcol[2]=rp[0]; h.set(p, cpp, tmpcol); /* every color-string should be unique; but no error message if it isn't */ } while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; outbuf+=3) { tok.readInStr(pend,cpp); if (NULLP==(pend=h.get(pend, cpp))) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; memcpy(outbuf, pend, 3); } } } #else /* don't USE_IN_XPM_MAPPING */ Image::Sampled::dimen_t lastcol=0, x; p=tab; /* cache pointer for the last color (lastcol) */ if (colors<=256) { assert(cpp>1); for (lastcol=0;lastcolsetPal(lastcol, rgb[lastcol]); lastcol=0; while (ht--!=0) { // putchar('.'); tok.getComma(); for (x=0;x256 */ while (ht--!=0) { tok.getComma(); for (x=0;x>16; *outbuf++=rgb[lastcol]>>8; *outbuf++=rgb[lastcol]; } } } #endif } delete [] tab; delete [] rgb; /* Dat: we don't check for EOF. Imp: emit a warning? */ // Error::sev(Error::DEBUG) << "rp[-1]=" << rp[-1] << (Error*)0; // while (-1!=(i=tok.getcc())) { putchar(i); } /* fclose((FILE*)file_); */ return ret; } static Image::Loader::reader_t in_xpm_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (0==memcmp(buf, "/* XPM */", 9)) ? in_xpm_reader : 0; } #else # define in_xpm_checker NULLP #endif /* USE_IN_XPM */ Image::Loader in_xpm_loader = { "XPM", in_xpm_checker, 0 }; sam2p-0.49.2/out_gif.cpp0000644000175100017510000002211712211371426013172 0ustar ptspts/* out_gif.cpp * by pts@fazekas.hu at Sat Mar 23 11:02:36 CET 2002 */ #include "image.hpp" #if USE_OUT_GIF #include #include /**** pts ****/ #ifdef __cplusplus # define AALLOC(var,len,itemtype) var=new itemtype[len] # define AFREE(expr) delete [] (expr) #else # include /* malloc(), free() */ # define AALLOC(var,len,itemtype) var=(itemtype*)malloc(len*sizeof(itemtype)); # define AFREE(expr) free((expr)) #endif #define HasLZW HAVE_LZW /* Imp: or USE_BUILTIN_LZW? */ #define True true #define False false /* The code of GIFEncodeImage is based on an early version of ImageMagick. */ static unsigned int GIFEncodeImage(GenBuffer::Writable& out, char const*ppbeg, register char const*ppend, const unsigned int data_size) { #define MaxCode(number_bits) ((1 << (number_bits))-1) #define MaxHashTable 5003 #define MaxGIFBits 12 #if defined(HasLZW) #define MaxGIFTable (1 << MaxGIFBits) #else #define MaxGIFTable max_code #endif #define GIFOutputCode(code) \ { \ /* \ Emit a code. \ */ \ if (bits > 0) \ datum|=((long) code << bits); \ else \ datum=(long) code; \ bits+=number_bits; \ while (bits >= 8) \ { \ /* \ Add a character to current packet. \ */ \ packet[byte_count++]=(unsigned char) (datum & 0xff); \ if (byte_count >= 254) \ { \ packet[-1]=byte_count; \ out.vi_write((char*)packet-1, byte_count+1); \ byte_count=0; \ } \ datum>>=8; \ bits-=8; \ } \ if (free_code > max_code) \ { \ number_bits++; \ if (number_bits == MaxGIFBits) \ max_code=MaxGIFTable; \ else \ max_code=MaxCode(number_bits); \ } \ } int bits, byte_count, i, next_pixel, number_bits; long datum; register int displacement, k; register char const*pp; short clear_code, end_of_information_code, free_code, *hash_code, *hash_prefix, index, max_code, waiting_code; unsigned char *packet, *hash_suffix; /* Allocate encoder tables. */ AALLOC(packet,257,unsigned char); AALLOC(hash_code,MaxHashTable,short); AALLOC(hash_prefix,MaxHashTable,short); AALLOC(hash_suffix,MaxHashTable,unsigned char); if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) || (hash_prefix == (short *) NULL) || (hash_suffix == (unsigned char *) NULL)) return(False); packet++; /* Now: packet-1 == place for byte_count */ /* Initialize GIF encoder. */ number_bits=data_size; max_code=MaxCode(number_bits); clear_code=((short) 1 << (data_size-1)); end_of_information_code=clear_code+1; free_code=clear_code+2; byte_count=0; datum=0; bits=0; for (i=0; i < MaxHashTable; i++) hash_code[i]=0; GIFOutputCode(clear_code); /* Encode pixels. */ /**** pts ****/ pp=ppbeg; waiting_code=*(unsigned char const*)pp++; /* unsigned char BUGFIX at Sun Dec 8 13:17:00 CET 2002 */ while (pp!=ppend) { /* Probe hash table. */ index=*(unsigned char const*)pp++; k=(int) ((int) index << (MaxGIFBits-8))+waiting_code; if (k >= MaxHashTable) k-=MaxHashTable; #if defined(HasLZW) if (hash_code[k] > 0) { if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index)) { waiting_code=hash_code[k]; continue; } if (k == 0) displacement=1; else displacement=MaxHashTable-k; next_pixel=False; for ( ; ; ) { k-=displacement; if (k < 0) k+=MaxHashTable; if (hash_code[k] == 0) break; if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index)) { waiting_code=hash_code[k]; next_pixel=True; break; } } if (next_pixel != False) /* pacify VC6.0 */ continue; } #endif GIFOutputCode(waiting_code); // printf("wc=%u\n", waiting_code); if (free_code < MaxGIFTable) { hash_code[k]=free_code++; hash_prefix[k]=waiting_code; hash_suffix[k]=index; } else { /* Fill the hash table with empty entries. */ for (k=0; k < MaxHashTable; k++) hash_code[k]=0; /* Reset compressor and issue a clear code. */ free_code=clear_code+2; GIFOutputCode(clear_code); number_bits=data_size; max_code=MaxCode(number_bits); } waiting_code=index; #if 0 /**** pts ****/ if (QuantumTick(i,image) && (image->previous == (Image2 *) NULL)) ProgressMonitor(SaveImageText,i,image->packets); #endif } /* Flush out the buffered code. */ GIFOutputCode(waiting_code); GIFOutputCode(end_of_information_code); if (bits > 0) { /* Add a character to current packet. */ packet[byte_count++]=(unsigned char) (datum & 0xff); if (byte_count >= 254) { packet[-1]=byte_count; out.vi_write((char*)packet-1, byte_count+1); byte_count=0; } } /* Flush accumulated data. */ if (byte_count > 0) { packet[-1]=byte_count; out.vi_write((char*)packet-1, byte_count+1); } /* Free encoder memory. */ AFREE(hash_suffix); AFREE(hash_prefix); AFREE(hash_code); AFREE(packet-1); return pp==ppend; } /** This isn't a complete GIF writer. For example, it doesn't support * animation or multiple sub-images. But it supports transparency and * compression. Only works when . The user should call * packPal() first to ensure img->getBpc()==8, and to get a minimal palette. */ void out_gif_write(GenBuffer::Writable& out, Image::Indexed *img) { /* Tested and proven to work at Sat Mar 23 13:11:41 CET 2002 */ unsigned i, c, bits_per_pixel; signed transp; char hd[19]; assert(img->getBpc()==8); /* 1 palette entry == 8 bits */ transp=img->getTransp(); memcpy(hd, transp!=-1 ? "GIF89a" : "GIF87a", 6); i=img->getWd(); hd[6]=i; hd[7]=i>>8; i=img->getHt(); hd[8]=i; hd[9]=i>>8; // transp=-1; /* With this, transparency will be ignored */ c=img->getNcols(); bits_per_pixel=1; while (((c-1)>>bits_per_pixel)!=0) bits_per_pixel++; /* ^^^ (c-1) BUGFIX at Mon Oct 20 15:18:24 CEST 2003 */ /* 63 -> 6, 64 -> 6, 65 -> 7 */ // if (bits_per_pixel>1) bits_per_pixel--; /* BUGFIX at Wed Apr 30 15:55:27 CEST 2003 */ /* BUGFIX at Mon Oct 20 15:18:14 CEST 2003 */ // fprintf(stderr, "GIF89 write transp=%d ncols=%d bpp=%d\n", transp, c, bits_per_pixel); assert(1<=bits_per_pixel && bits_per_pixel<=8); c=3*((1<getHeadp(), img->getRowbeg()-img->getHeadp()); /* write colormap */ if (c!=0) { char *padding=new char[(unsigned char)c]; /* BUGFIX at Fri Oct 17 18:05:09 CEST 2003 */ memset(padding, '\0', (unsigned char)c); /* Not automatic! */ out.vi_write(padding, (unsigned char)c); delete [] padding; } if (transp!=-1) { /* Write Graphics Control extension. Only GIF89a */ hd[0]=0x21; hd[1]=(char)0xf9; hd[2]=0x04; hd[3]=transp!=-1; /* dispose==0 */ hd[4]=hd[5]=0; /* delay==0 */ hd[6]=transp; /* transparent color index -- or 255 */ hd[7]=0; out.vi_write(hd, 8); } /* Write image header */ hd[8]=','; hd[ 9]=hd[10]=0; /* left */ hd[11]=hd[12]=0; /* top */ i=img->getWd(); hd[13]=i; hd[14]=i>>8; i=img->getHt(); hd[15]=i; hd[16]=i>>8; hd[17]=0; /* no interlace, no local colormap, no bits in local colormap */ if ((c=bits_per_pixel)<2) c=4; hd[18]=c; /* compression bits_per_pixel */ out.vi_write(hd+8, 11); #if 0 printf("GIFEncodeImage out r r+%u %u; off=%u\n", img->getRlen()*img->getHt(), c+1, img->getRowbeg()-img->getHeadp()); FILE *f=fopen("tjo.dat","wb"); fprintf(f, "P6 %u %u 255\n", img->getWd(), img->getHt()); // fwrite(img->getRowbeg(), 1, img->getRlen()*img->getHt(), f); for (unsigned u=0; ugetRlen()*img->getHt(); u++) { char *p=img->getHeadp()+3* *(unsigned char*)(img->getRowbeg()+u); putc(p[0],f); putc(p[1],f); putc(p[2],f); } #endif i=GIFEncodeImage(out, img->getRowbeg(), img->getRowbeg()+img->getRlen()*img->getHt(), c+1); #if 0 { char buf[500000]; FILE *f=fopen("tjo.dat","rb"); int got=fread(buf, 1, sizeof(buf), f); assert(got==486109); assert(got==img->getRlen()*img->getHt()); i=GIFEncodeImage(out, buf, buf+img->getRlen()*img->getHt(), c+1); } #endif assert(i!=0); /* Write trailer */ hd[0]=0; hd[1]=';'; out.vi_write(hd, 2); } #else #include void out_gif_write(GenBuffer::Writable&, Image::Indexed *) { assert(0); abort(); } #endif sam2p-0.49.2/crc32.c0000644000175100017510000001367612211371426012124 0ustar ptspts/* crc32.c -- compute the CRC-32 of a data stream * Ripped from the zip sources: * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* $Id: crc32.c,v 1.2 2002/12/11 14:01:52 pts Exp $ */ #ifdef __GNUC__ #pragma implementation #endif #if OBJDEP # warning PROVIDES: crc32 #endif /*#include "zip.h"*/ /* #ifndef USE_ZLIB */ #include "crc32.h" #define ZCONST PTS_const #ifdef CRC32 # undef CRC32 #endif #define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) #define DO1(buf) crc = CRC32(crc, *(unsigned char ZCONST*)buf++) #define DO2(buf) DO1(buf); DO1(buf) #define DO4(buf) DO2(buf); DO2(buf) #define DO8(buf) DO4(buf); DO4(buf) #undef NO_UNROLLED_LOOPS #define local static #define ulg unsigned PTS_INT32_T #define uch unsigned char #define extent slen_t #ifndef NULL #define NULL ((void*)0) #endif #ifndef near #define near #endif #ifndef ___ /**** pts ****/ #if defined(__STDC__) || defined(__cplusplus) # define _(args) args # define ___(arg2s,arg1s,argafter) arg2s /* Dat: no direct comma allowed in args :-( */ #else # define _(args) () # define ___(arg2s,arg1s,argafter) arg1s argafter /* Dat: no direct comma allowed in args :-( */ #endif #endif /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ local ZCONST ulg near crc_table[] = { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL }; /* ========================================================================= */ ulg crc32 ___((register ulg crc, register ZCONST char *buf, extent len),(crc, buf, len),( register ulg crc; /* crc shift register */ register ZCONST char *buf; /* pointer to bytes to pump through */ extent len; /* number of bytes in buf[] */ /* Run a set of bytes through the crc shift register. If buf is a NULL pointer, then initialize the crc shift register contents instead. Return the current crc in either case. */ )) { /* register ulg near *crc_table; */ if (buf == NULLP) return crc /*0L*/; /* crc_table = get_crc_table(); */ crc = crc ^ 0xffffffffUL; #ifndef NO_UNROLLED_LOOPS while (len >= 8) { DO8(buf); len -= 8; } #endif if (len) do { DO1(buf); } while (--len); return crc ^ 0xffffffffUL; /* (instead of ~c for 64-bit machines) */ } /* #endif */ /* !USE_ZLIB */ /* __EOF__ */ sam2p-0.49.2/crc32.h0000644000175100017510000000117412211371426012117 0ustar ptspts/* crc32.c -- Calculate CRC-32 for GZIP + PNG */ #ifndef CRC32_H #define CRC32_H 1 #ifdef __GNUC__ #pragma interface #endif #include "config2.h" #define CRC32_INITIAL ((unsigned PTS_INT32_T)0) /** Usage: * unsigned PTS_INT32_T crc=CRC32_INITIAL; * crc=crc32(crc, "alma", 4); * crc=crc32(crc, "korte", 5); * ... * putchar( (char)(crc & 0xff) ); * putchar( (char)((crc >> 8) & 0xff) ); * putchar( (char)((crc >> 16) & 0xff) ); * putchar( (char)((crc >> 24) & 0xff) ); */ extern #ifdef __cplusplus "C" #endif unsigned PTS_INT32_T crc32 _((unsigned PTS_INT32_T oldcrc, char PTS_const *s, slen_t slen)); #endif /* CRC32_H */ sam2p-0.49.2/cgif.h0000644000175100017510000002231312211371426012111 0ustar ptspts/* cgif.h -- a merge of some GIF-decoding files from giflib by E.S.Raymond * by pts@fazekas.hu at Wed Feb 27 13:18:04 CET 2002 The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /****************************************************************************** * In order to make life a little bit easier when using the GIF file format, * * this library was written, and which does all the dirty work... * * * * Written by Gershon Elber, Jun. 1989 * * Hacks by Eric S. Raymond, Sep. 1992 * ******************************************************************************* * History: * * 14 Jun 89 - Version 1.0 by Gershon Elber. * * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). * * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp) * * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) ******************************************************************************/ #ifndef CGIF_H #define CGIF_H #ifdef __GNUC__ #pragma interface #endif #include "config2.h" /* PTS_const */ #define GIF_LIB_VERSION " Version 3.0, " #define GIF_ERROR 0 #define GIF_OK 1 #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif /* NULL */ #if _MSC_VER > 1000 # undef __PROTOTYPES__ # define __PROTOTYPES__ 1 # pragma warning(disable: 4127) /* conditional expression is constant */ # pragma warning(disable: 4244) /* =' : conversion from 'int ' to 'unsigned char ', possible loss of data */ #endif /* at Wed Dec 11 15:33:22 CET 2002 */ /* #define USE_CGIF_FDOPEN 1 */ #undef USE_CGIF_FDOPEN #ifdef __cplusplus class CGIF { public: #define EXTERN static #else #define EXTERN extern #endif typedef int GifBooleanType; typedef unsigned char GifPixelType; typedef unsigned char * GifRowType; typedef unsigned char GifByteType; #define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg) #define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); } #ifdef SYSV #define VoidPtr char * #else #define VoidPtr void * #endif /* SYSV */ typedef struct GifColorType { GifByteType Red, Green, Blue; } GifColorType; typedef struct ColorMapObject { int ColorCount; int BitsPerPixel; GifColorType *Colors; /* on malloc(3) heap */ } ColorMapObject; typedef struct GifImageDesc { int Left, Top, Width, Height, /* Current image dimensions. */ Interlace; /* Sequential/Interlaced lines. */ ColorMapObject *ColorMap; /* The local color map */ } GifImageDesc; struct SavedImage; typedef struct GifFileType { int SWidth, SHeight, /* Screen dimensions. */ SColorResolution, /* How many colors can we generate? */ SBackGroundColor; /* I hope you understand this one... */ ColorMapObject *SColorMap; /* NULL if not exists. */ int ImageCount; /* Number of current image */ /*GifImageDesc Image; */ /* Block describing current image */ struct SavedImage *SavedImages; /* Use this to accumulate file state */ VoidPtr Private; /* Don't mess with this! */ } GifFileType; typedef enum { UNDEFINED_RECORD_TYPE, SCREEN_DESC_RECORD_TYPE, IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */ EXTENSION_RECORD_TYPE, /* Begin with '!' */ TERMINATE_RECORD_TYPE /* Begin with ';' */ } GifRecordType; /****************************************************************************** * GIF89 extension function codes * ******************************************************************************/ #define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ #define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */ #define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ #define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ /****************************************************************************** * O.K., here are the routines one can access in order to decode GIF file: * * (GIF_LIB file DGIF_LIB.C). * ******************************************************************************/ EXTERN GifFileType *DGifOpenFileName(const char *GifFileName); #if USE_CGIF_FDOPEN EXTERN GifFileType *DGifOpenFileHandle(int GifFileHandle); #endif EXTERN GifFileType *DGifOpenFILE(void/*FILE*/ *f); EXTERN int DGifSlurp(GifFileType *GifFile); EXTERN int DGifGetScreenDesc(GifFileType *GifFile); EXTERN int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType); EXTERN int DGifGetImageDesc(GifFileType *GifFile); EXTERN int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen); EXTERN int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel); EXTERN int DGifGetComment(GifFileType *GifFile, char *GifComment); EXTERN int DGifGetExtension(GifFileType *GifFile, int *GifExtCode, GifByteType **GifExtension); EXTERN int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension); EXTERN int DGifGetCode(GifFileType *GifFile, int *GifCodeSize, GifByteType **GifCodeBlock); EXTERN int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock); EXTERN int DGifGetLZCodes(GifFileType *GifFile, int *GifCode); EXTERN int DGifCloseFile(GifFileType *GifFile); #define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ #define D_GIF_ERR_READ_FAILED 102 #define D_GIF_ERR_NOT_GIF_FILE 103 #define D_GIF_ERR_NO_SCRN_DSCR 104 #define D_GIF_ERR_NO_IMAG_DSCR 105 #define D_GIF_ERR_NO_COLOR_MAP 106 #define D_GIF_ERR_WRONG_RECORD 107 #define D_GIF_ERR_DATA_TOO_BIG 108 #define D_GIF_ERR_NOT_ENOUGH_MEM 109 #define D_GIF_ERR_CLOSE_FAILED 110 #define D_GIF_ERR_NOT_READABLE 111 #define D_GIF_ERR_IMAGE_DEFECT 112 #define D_GIF_ERR_EOF_TOO_SOON 113 /****************************************************************************** * O.K., here are the routines from GIF_LIB file GIF_ERR.C. * ******************************************************************************/ EXTERN void PrintGifError(void); EXTERN PTS_const char *GetGifError(void); EXTERN int GifLastError(void); /***************************************************************************** * * Everything below this point is new after version 1.2, supporting `slurp * mode' for doing I/O in two big belts with all the image-bashing in core. * *****************************************************************************/ /****************************************************************************** * Color Map handling from ALLOCGIF.C * ******************************************************************************/ EXTERN ColorMapObject *MakeMapObject(int ColorCount, GifColorType *ColorMap); EXTERN void FreeMapObject(ColorMapObject *Object); /****************************************************************************** * Support for the in-core structures allocation (slurp mode). * ******************************************************************************/ /* This is the in-core version of an extension record */ typedef struct { /** Extension code: * 0xf9 Graphics Control extension (not stored!) * 0xfe Comment extension * 0xff Netscape Loop extension (not stored!) * .... ??? */ int code; int ByteCount; /**** pts ****/ GifByteType *Bytes; /* on malloc(3) heap */ } ExtensionBlock; /* This holds an image header, its unpacked raster bits, and extensions */ typedef struct SavedImage { GifImageDesc ImageDesc; /**** pts ****/ GifPixelType *RasterBits; /* on malloc(3) heap */ int ExtensionBlockCount; ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */ /**** pts ****/ /** from Graphics Control extension: 0..63 */ unsigned char dispose; /** from Graphics Control extension: 0..65535 */ unsigned short delay; /** from Graphics Control extension: transparency index: -1 or 0..255 */ signed short transp; /** from Netscape Loop extension: iteration count: 0..65535 */ unsigned short iter; } SavedImage; EXTERN void MakeExtension(SavedImage *New, int Function); EXTERN int AddExtensionBlock(SavedImage *New, int Len, GifByteType ExtData[]); EXTERN void FreeExtension(SavedImage *Image); EXTERN SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom); EXTERN void FreeSavedImages(GifFileType *GifFile); #ifdef __cplusplus static int _GifError; }; #else extern int _GifError; #endif #endif /* CGIF_H */ sam2p-0.49.2/cols2.pl0000644000175100017510000002322512211371426012412 0ustar ptspts#! /bin/sh -- eval '(exit $?0)' && eval 'PERL_BADLANG=x;export PERL_BADLANG;: \ ;exec perl -x -S -- "$0" ${1+"$@"};#'if 0; eval 'setenv PERL_BADLANG x;exec perl -x -S -- "$0" $argv:q;#'.q #!perl -w +($0=~/(.*)/s);do$1;die$@if$@;__END__+if 0; # Don't touch/remove lines 1--7: http://www.inf.bme.hu/~pts/Magic.Perl.Header # # cols2.pl -- create a read-only C hash table from hash function # by pts@fazekas.hu at Fri Mar 1 09:24:46 CET 2002 # minor VC6.0 updates at Thu Dec 12 19:01:06 CET 2002 # BEGIN{$^W=1} BEGIN { eval { require integer; import integer } } BEGIN { eval { require strict ; import strict } } my @L=( # imagemagick's ColorList.h [ "None", 3, 2, 1 ], [ "AliceBlue", 240, 248, 255 ], [ "AntiqueWhite", 250, 235, 215 ], [ "Aquamarine", 50, 191, 193 ], [ "Azure", 240, 255, 255 ], [ "Beige", 245, 245, 220 ], [ "Bisque", 255, 228, 196 ], [ "Black", 0, 0, 0 ], [ "BlanchedAlmond", 255, 235, 205 ], [ "Blue", 0, 0, 255 ], [ "BlueViolet", 138, 43, 226 ], [ "Brown", 165, 42, 42 ], [ "burlywood", 222, 184, 135 ], [ "CadetBlue", 95, 146, 158 ], [ "chartreuse", 127, 255, 0 ], [ "chocolate", 210, 105, 30 ], [ "Coral", 255, 114, 86 ], [ "CornflowerBlue", 34, 34, 152 ], [ "cornsilk", 255, 248, 220 ], [ "Cyan", 0, 255, 255 ], [ "DarkGoldenrod", 184, 134, 11 ], [ "DarkGreen", 0, 86, 45 ], [ "DarkKhaki", 189, 183, 107 ], [ "DarkOliveGreen", 85, 86, 47 ], [ "DarkOrange", 255, 140, 0 ], [ "DarkOrchid", 139, 32, 139 ], [ "DarkSalmon", 233, 150, 122 ], [ "DarkSeaGreen", 143, 188, 143 ], [ "DarkSlateBlue", 56, 75, 102 ], [ "DarkSlateGray", 47, 79, 79 ], [ "DarkTurquoise", 0, 166, 166 ], [ "DarkViolet", 148, 0, 211 ], [ "DeepPink", 255, 20, 147 ], [ "DeepSkyBlue", 0, 191, 255 ], [ "DimGray", 84, 84, 84 ], [ "DodgerBlue", 30, 144, 255 ], [ "Firebrick", 142, 35, 35 ], [ "FloralWhite", 255, 250, 240 ], [ "ForestGreen", 80, 159, 105 ], [ "gainsboro", 220, 220, 220 ], [ "GhostWhite", 248, 248, 255 ], [ "Gold", 218, 170, 0 ], [ "Goldenrod", 239, 223, 132 ], [ "Gray", 126, 126, 126 ], [ "Green", 0, 255, 0 ], [ "GreenYellow", 173, 255, 47 ], [ "honeydew", 240, 255, 240 ], [ "HotPink", 255, 105, 180 ], [ "IndianRed", 107, 57, 57 ], [ "ivory", 255, 255, 240 ], [ "Khaki", 179, 179, 126 ], [ "lavender", 230, 230, 250 ], [ "LavenderBlush", 255, 240, 245 ], [ "LawnGreen", 124, 252, 0 ], [ "LemonChiffon", 255, 250, 205 ], [ "LightBlue", 176, 226, 255 ], [ "LightCoral", 240, 128, 128 ], [ "LightCyan", 224, 255, 255 ], [ "LightGoldenrod", 238, 221, 130 ], [ "LightGoldenrodYellow", 250, 250, 210 ], [ "LightGray", 168, 168, 168 ], [ "LightPink", 255, 182, 193 ], [ "LightSalmon", 255, 160, 122 ], [ "LightSeaGreen", 32, 178, 170 ], [ "LightSkyBlue", 135, 206, 250 ], [ "LightSlateBlue", 132, 112, 255 ], [ "LightSlateGray", 119, 136, 153 ], [ "LightSteelBlue", 124, 152, 211 ], [ "LightYellow", 255, 255, 224 ], [ "LimeGreen", 0, 175, 20 ], [ "linen", 250, 240, 230 ], [ "Magenta", 255, 0, 255 ], [ "Maroon", 143, 0, 82 ], [ "MediumAquamarine", 0, 147, 143 ], [ "MediumBlue", 50, 50, 204 ], [ "MediumForestGreen", 50, 129, 75 ], [ "MediumGoldenrod", 209, 193, 102 ], [ "MediumOrchid", 189, 82, 189 ], [ "MediumPurple", 147, 112, 219 ], [ "MediumSeaGreen", 52, 119, 102 ], [ "MediumSlateBlue", 106, 106, 141 ], [ "MediumSpringGreen", 35, 142, 35 ], [ "MediumTurquoise", 0, 210, 210 ], [ "MediumVioletRed", 213, 32, 121 ], [ "MidnightBlue", 47, 47, 100 ], [ "MintCream", 245, 255, 250 ], [ "MistyRose", 255, 228, 225 ], [ "moccasin", 255, 228, 181 ], [ "NavajoWhite", 255, 222, 173 ], [ "Navy", 35, 35, 117 ], [ "NavyBlue", 35, 35, 117 ], [ "OldLace", 253, 245, 230 ], [ "OliveDrab", 107, 142, 35 ], [ "Orange", 255, 135, 0 ], [ "OrangeRed", 255, 69, 0 ], [ "Orchid", 239, 132, 239 ], [ "PaleGoldenrod", 238, 232, 170 ], [ "PaleGreen", 115, 222, 120 ], [ "PaleTurquoise", 175, 238, 238 ], [ "PaleVioletRed", 219, 112, 147 ], [ "PapayaWhip", 255, 239, 213 ], [ "PeachPuff", 255, 218, 185 ], [ "peru", 205, 133, 63 ], [ "Pink", 255, 181, 197 ], [ "Plum", 197, 72, 155 ], [ "PowderBlue", 176, 224, 230 ], [ "purple", 160, 32, 240 ], [ "Red", 255, 0, 0 ], [ "RosyBrown", 188, 143, 143 ], [ "RoyalBlue", 65, 105, 225 ], [ "SaddleBrown", 139, 69, 19 ], [ "Salmon", 233, 150, 122 ], [ "SandyBrown", 244, 164, 96 ], [ "SeaGreen", 82, 149, 132 ], [ "seashell", 255, 245, 238 ], [ "Sienna", 150, 82, 45 ], [ "SkyBlue", 114, 159, 255 ], [ "SlateBlue", 126, 136, 171 ], [ "SlateGray", 112, 128, 144 ], [ "snow", 255, 250, 250 ], [ "SpringGreen", 65, 172, 65 ], [ "SteelBlue", 84, 112, 170 ], [ "Tan", 222, 184, 135 ], [ "Thistle", 216, 191, 216 ], [ "tomato", 255, 99, 71 ], [ "Transparent", 0, 0, 1 ], [ "Turquoise", 25, 204, 223 ], [ "Violet", 156, 62, 206 ], [ "VioletRed", 243, 62, 150 ], [ "Wheat", 245, 222, 179 ], [ "White", 255, 255, 255 ], [ "WhiteSmoke", 245, 245, 245 ], [ "Yellow", 255, 255, 0 ], [ "YellowGreen", 50, 216, 56 ], [ "Gray0", 0, 0, 0 ], [ "Gray1", 3, 3, 3 ], [ "Gray10", 26, 26, 26 ], [ "Gray100", 255, 255, 255 ], [ "Gray11", 28, 28, 28 ], [ "Gray12", 31, 31, 31 ], [ "Gray13", 33, 33, 33 ], [ "Gray14", 36, 36, 36 ], [ "Gray15", 38, 38, 38 ], [ "Gray16", 41, 41, 41 ], [ "Gray17", 43, 43, 43 ], [ "Gray18", 46, 46, 46 ], [ "Gray19", 48, 48, 48 ], [ "Gray2", 5, 5, 5 ], [ "Gray20", 51, 51, 51 ], [ "Gray21", 54, 54, 54 ], [ "Gray22", 56, 56, 56 ], [ "Gray23", 59, 59, 59 ], [ "Gray24", 61, 61, 61 ], [ "Gray25", 64, 64, 64 ], [ "Gray26", 66, 66, 66 ], [ "Gray27", 69, 69, 69 ], [ "Gray28", 71, 71, 71 ], [ "Gray29", 74, 74, 74 ], [ "Gray3", 8, 8, 8 ], [ "Gray30", 77, 77, 77 ], [ "Gray31", 79, 79, 79 ], [ "Gray32", 82, 82, 82 ], [ "Gray33", 84, 84, 84 ], [ "Gray34", 87, 87, 87 ], [ "Gray35", 89, 89, 89 ], [ "Gray36", 92, 92, 92 ], [ "Gray37", 94, 94, 94 ], [ "Gray38", 97, 97, 97 ], [ "Gray39", 99, 99, 99 ], [ "Gray4", 10, 10, 10 ], [ "Gray40", 102, 102, 102 ], [ "Gray41", 105, 105, 105 ], [ "Gray42", 107, 107, 107 ], [ "Gray43", 110, 110, 110 ], [ "Gray44", 112, 112, 112 ], [ "Gray45", 115, 115, 115 ], [ "Gray46", 117, 117, 117 ], [ "Gray47", 120, 120, 120 ], [ "Gray48", 122, 122, 122 ], [ "Gray49", 125, 125, 125 ], [ "Gray5", 13, 13, 13 ], [ "Gray50", 127, 127, 127 ], [ "Gray51", 130, 130, 130 ], [ "Gray52", 133, 133, 133 ], [ "Gray53", 135, 135, 135 ], [ "Gray54", 138, 138, 138 ], [ "Gray55", 140, 140, 140 ], [ "Gray56", 143, 143, 143 ], [ "Gray57", 145, 145, 145 ], [ "Gray58", 148, 148, 148 ], [ "Gray59", 150, 150, 150 ], [ "Gray6", 15, 15, 15 ], [ "Gray60", 153, 153, 153 ], [ "Gray61", 156, 156, 156 ], [ "Gray62", 158, 158, 158 ], [ "Gray63", 161, 161, 161 ], [ "Gray64", 163, 163, 163 ], [ "Gray65", 166, 166, 166 ], [ "Gray66", 168, 168, 168 ], [ "Gray67", 171, 171, 171 ], [ "Gray68", 173, 173, 173 ], [ "Gray69", 176, 176, 176 ], [ "Gray7", 18, 18, 18 ], [ "Gray70", 179, 179, 179 ], [ "Gray71", 181, 181, 181 ], [ "Gray72", 184, 184, 184 ], [ "Gray73", 186, 186, 186 ], [ "Gray74", 189, 189, 189 ], [ "Gray75", 191, 191, 191 ], [ "Gray76", 194, 194, 194 ], [ "Gray77", 196, 196, 196 ], [ "Gray78", 199, 199, 199 ], [ "Gray79", 201, 201, 201 ], [ "Gray8", 20, 20, 20 ], [ "Gray80", 204, 204, 204 ], [ "Gray81", 207, 207, 207 ], [ "Gray82", 209, 209, 209 ], [ "Gray83", 212, 212, 212 ], [ "Gray84", 214, 214, 214 ], [ "Gray85", 217, 217, 217 ], [ "Gray86", 219, 219, 219 ], [ "Gray87", 222, 222, 222 ], [ "Gray88", 224, 224, 224 ], [ "Gray89", 227, 227, 227 ], [ "Gray9", 23, 23, 23 ], [ "Gray90", 229, 229, 229 ], [ "Gray91", 232, 232, 232 ], [ "Gray92", 235, 235, 235 ], [ "Gray93", 237, 237, 237 ], [ "Gray94", 240, 240, 240 ], [ "Gray95", 242, 242, 242 ], [ "Gray96", 245, 245, 245 ], [ "Gray97", 247, 247, 247 ], [ "Gray98", 250, 250, 250 ], [ "Gray99", 252, 252, 252 ], ); # quote all [^!-~]|[^\\ sub cq($) { # @return param octal-quoted as a C source string my $S=$_[0]; $S=~s@([\\"])@\\$1@g; $S=~s@([^!-~])@sprintf"\\%03o",ord$1@ge; $S=~s@\\([0-7][0-7][0-7])(?=[0-9])@\\$1""@g; # pacify VC6.0 warning $S } my @P; sub hash0($) { my $N=0; for(split'',$_[0][0]) { $N=$N*95+(223&ord); } $N&=65535; $N%=1109; push @{$P[$N]}, $_[0]; } @P=(); for (@L) { hash0($_); } # my $S=""; # die @P; print STDERR "Collisions:\n"; for (@P) { print STDERR "X@$_.\n" if defined($_) and $#$_>=1 } print STDERR "---\n"; my $S="\000"; # contains strings my $H=""; # contains the hash table indices, offsets to $S for (@P) { if (defined($_)) { $H.=length($S).","; for (@$_) { # $S.=$_->[0]."#".$_->[1].",".$_->[2].",".$_->[3].";" $S.=$_->[0]."\000".chr($_->[1]).chr($_->[2]).chr($_->[3]); } # substr($S,-1,1)="\000"; $S.="\000"; } else { $H.="0,"; } # print STDERR "X@$_.\n" if defined($_) and $#$_>=1 } } $S=~s@\000\Z(?!\n)@@; print "#define xpmColors_mul 95\n"; print "#define xpmColors_mod 1109\n"; print "unsigned short xpmColors_ofs[]={$H};\n"; print "char xpmColors_dat[]=\"".cq($S)."\";\n"; # 357, 2048 # 189, 3457 # 175, 3823 # 973 (222), 1993 # 751 (22), 1997 # 439 (2), 2053 # 79 (222222), 1229 # 539 (22222), 1201 # 287 (222), 1163 sam2p-0.49.2/in_pnm.cpp0000644000175100017510000000554112211371426013020 0ustar ptspts/* * in_pnm.cpp -- read a NetPBM PNM bitmap file * by pts@fazekas.hu at Sat Mar 2 00:46:54 CET 2002 * */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_PNM #include "gensio.hpp" #include "input-pnm.ci" #include static Image::Sampled *in_pnm_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; #if 0 FILE *f=((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false); bitmap_type bitmap=pnm_load_image(f); #else Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; bitmap_type bitmap=pnm_load_image(ufdd); #endif /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); /* fwrite(BITMAP_BITS(bitmap), 1, (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap), stdout); */ ret=img; } else assert(0 && "invalid PNM depth"); delete [] BITMAP_BITS(bitmap); if (ufdd->vi_getcc()=='P') { ufdd->unread("P", 1); // Error::sev(Error::NOTICE) << "PNM: loading alpha after PNM: " // " ftell=" << ftell(f) << // " bytes=" << ((unsigned)bitmap.width*bitmap.height*bitmap.np) << (Error*)0; bitmap=pnm_load_image(ufdd); // fwrite(bitmap.bitmap,1,(unsigned)bitmap.width*bitmap.height*bitmap.np,stdout); /* Dat: black pixel is transparent */ if (BITMAP_PLANES(bitmap)!=1) Error::sev(Error::EERROR) << "PNM: alpha must be PBM or PGM" << (Error*)0; Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); delete [] BITMAP_BITS(bitmap); Image::Sampled *old=ret; // old->packPal(); /* automatically called */ if ((ret=old->addAlpha(img))!=old) { Error::sev(Error::NOTICE) << "PNM: loaded alpha after PNM" << (Error*)0; delete old; } else { Error::sev(Error::NOTICE) << "PNM: loaded alpha, but no transparent pixels" << (Error*)0; } } /* fclose(f); */ return ret; } static Image::Loader::reader_t in_pnm_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (buf[0]=='P' && (buf[1]>='1' && buf[1]<='6') && (buf[2]=='\t' || buf[2]==' ' || buf[2]=='\r' || buf[2]=='\n' || buf[2]=='#')) ? in_pnm_reader : 0; } #else #define in_pnm_checker NULLP #endif /* USE_IN_PNM */ Image::Loader in_pnm_loader = { "PNM", in_pnm_checker, 0 }; sam2p-0.49.2/xpmc.h0000644000175100017510000002116112211371426012150 0ustar ptspts#define xpmColors_mul 95 #define xpmColors_mod 1109 unsigned short xpmColors_ofs[]={0,0,0,1,0,0,0,0,0,0,0,0,15,0,43,0,0,0,0,0,0,0,65,0,0,0,84,0,0,0,0,0,96,0,0,0,0,0,0,0,113,0,0,0,0,0,0,0,0,0,0,129,140,151,162,173,199,210,221,232,243,0,254,0,0,0,0,268,0,0,0,0,282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,296,0,310,0,0,0,0,0,0,0,0,0,0,0,0,0,329,0,0,0,0,0,0,0,0,343,352,0,0,0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,0,0,0,382,0,0,0,0,0,0,0,0,0,0,0,391,402,413,424,435,446,457,468,479,490,0,0,0,0,0,0,0,0,0,501,0,516,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,525,0,0,0,0,0,0,540,0,557,0,0,0,568,0,0,576,0,0,0,0,0,0,0,0,0,0,594,0,0,0,0,0,607,0,0,0,0,0,0,0,0,0,0,0,0,0,0,623,634,645,656,667,678,689,700,711,722,0,0,733,0,0,0,743,0,0,0,0,0,0,0,0,0,0,0,0,763,0,0,0,0,771,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,785,0,0,0,794,0,0,0,0,0,0,0,0,806,816,0,0,0,0,833,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,842,853,864,875,886,897,908,919,930,941,0,952,0,0,0,0,0,966,0,0,0,0,0,0,0,0,0,980,0,0,0,0,0,0,989,0,0,1011,0,1026,0,0,0,0,0,0,0,0,0,1041,1056,0,0,1066,0,0,0,0,0,1075,1090,0,1106,0,1120,0,0,0,1134,0,0,0,0,0,1148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1167,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1214,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1228,0,0,0,0,0,0,1241,1255,0,0,0,0,1265,1279,0,0,0,0,0,0,0,0,0,1293,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1312,0,0,0,0,0,0,0,0,0,0,0,0,0,1324,0,1333,0,1345,0,0,0,0,0,0,0,0,0,0,1359,0,0,0,1370,0,0,0,0,1387,1405,0,0,1418,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1436,0,0,0,1450,0,0,0,1461,0,0,0,0,1482,0,1497,0,0,0,0,0,0,0,1511,0,0,0,0,0,0,0,0,0,1527,0,0,0,0,0,0,0,0,0,1541,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1560,1571,1582,1593,1604,1615,1626,1637,1648,1659,0,0,0,0,0,0,0,0,0,0,0,1670,0,0,1685,0,0,0,0,0,1699,0,0,0,0,0,0,0,1710,0,0,0,0,0,0,1721,0,0,0,0,0,0,0,0,0,0,0,1739,1748,0,0,0,0,0,0,1758,0,1776,0,1788,0,0,0,0,0,0,0,0,0,1806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1831,1857,1868,1879,1890,1901,1912,1923,1934,1945,0,0,0,0,0,0,0,1956,0,0,0,0,0,0,0,0,0,0,0,0,0,1969,0,0,0,0,0,0,0,1979,0,0,0,0,0,0,1994,0,2004,0,0,0,0,0,2015,0,0,0,0,0,0,0,0,0,0,0,0,2033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2049,0,0,0,0,2067,2078,2089,2100,2111,2122,2133,2144,2155,2166,0,0,0,0,2177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2190,2209,2225,0,0,0,0,0,0,0,2241,0,2256,0,0,0,0,2267,0,2286,0,2297,0,0,0,0,0,0,0,0,0,0,0,2312,0,0,0,0,0,0,0,0,0,0,0,0,2328,0,0,0,0,0,0,0,0,0,0,2340,0,0,0,2358,0,0,0,2372,2383,2394,2405,2432,2443,2464,2488,2499,2510,2521,2538,0,0,0,0,0,0,0,2558,2568,0,0,0,0,0,0,0,0,0,0,2583,0,0,0,2603,0,0,0,0,0,0,2623,0,0,0,2635,0,2649,0,0,0,2663,2673,2683,2693,2703,2713,2723,2733,2743,2753,0,0,0,0,0,0,2763,2777,0,0,0,0,2790,2809,0,0,0,0,2826,0,2841,2851,0,0,0,0,0,0,0,0,0,0,0,2862,2873,2884,2895,2906,2917,2928,2939,2950,2961,0,2972,0,0,2981,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2994,}; char xpmColors_dat[]="\000LawnGreen\000|\374\000\000SlateGray\000p\200\220WhiteSmoke\000\365\365\365\000MediumForestGreen\000""2\201K\000LightSlateGray\000w\210\231\000Magenta\000\377\000\377\000DarkSeaGreen\000\217\274\217\000ForestGreen\000P\237i\000Gray60\000\231\231\231\000Gray61\000\234\234\234\000Gray62\000\236\236\236\000Gray63\000\241\241\241\000GreenYellow\000\255\377/Gray64\000\243\243\243\000Gray65\000\246\246\246\000Gray66\000\250\250\250\000Gray67\000\253\253\253\000Gray68\000\255\255\255\000Gray69\000\260\260\260\000PaleGreen\000s\336x\000chocolate\000\322i\036\000DarkKhaki\000\275\267k\000PeachPuff\000\377\332\271\000DarkOliveGreen\000UV/\000LightCyan\000\340\377\377\000Blue\000\000\000\377\000NavajoWhite\000\377\336\255\000AliceBlue\000\360\370\377\000Gold\000\332\252\000\000Gray70\000\263\263\263\000Gray71\000\265\265\265\000Gray72\000\270\270\270\000Gray73\000\272\272\272\000Gray74\000\275\275\275\000Gray75\000\277\277\277\000Gray76\000\302\302\302\000Gray77\000\304\304\304\000Gray78\000\307\307\307\000Gray79\000\311\311\311\000GhostWhite\000\370\370\377\000peru\000\315\205?\000DarkSalmon\000\351\226z\000MidnightBlue\000//d\000Salmon\000\351\226z\000Tan\000\336\270\207\000DarkSlateGray\000/OO\000moccasin\000\377\344\265\000LightYellow\000\377\377\340\000Gray80\000\314\314\314\000Gray81\000\317\317\317\000Gray82\000\321\321\321\000Gray83\000\324\324\324\000Gray84\000\326\326\326\000Gray85\000\331\331\331\000Gray86\000\333\333\333\000Gray87\000\336\336\336\000Gray88\000\340\340\340\000Gray89\000\343\343\343\000Azure\000\360\377\377\000MediumSlateBlue\000jj\215\000Red\000\377\000\000\000VioletRed\000\363>\226\000Plum\000\305H\233\000SkyBlue\000r\237\377\000linen\000\372\360\346\000AntiqueWhite\000\372\353\327\000Navy\000##u\000Gray90\000\345\345\345\000Gray91\000\350\350\350\000Gray92\000\353\353\353\000Gray93\000\355\355\355\000Gray94\000\360\360\360\000Gray95\000\362\362\362\000Gray96\000\365\365\365\000Gray97\000\367\367\367\000Gray98\000\372\372\372\000Gray99\000\374\374\374\000OliveDrab\000k\216#\000LightBlue\000\260\342\377\000None\000\003\002\001\000MediumSpringGreen\000#\216#\000BlueViolet\000\212+\342\000MediumBlue\000""22\314\000PapayaWhip\000\377\357\325\000Brown\000\245**\000Pink\000\377\265\305\000chartreuse\000\177\377\000\000SpringGreen\000A\254A\000RoyalBlue\000Ai\341\000Goldenrod\000\357\337\204\000Turquoise\000\031\314\337\000LightGoldenrod\000\356\335\202\000NavyBlue\000##u\000MediumSeaGreen\000""4wf\000PowderBlue\000\260\340\346\000LimeGreen\000\000\257\024\000honeydew\000\360\377\360\000LightPink\000\377\266\301\000ivory\000\377\377\360\000OrangeRed\000\377E\000\000SteelBlue\000Tp\252\000LightSteelBlue\000|\230\323\000Gray100\000\377\377\377\000Gray\000~~~\000DimGray\000TTT\000gainsboro\000\334\334\334\000tomato\000\377cG\000LemonChiffon\000\377\372\315\000DarkGoldenrod\000\270\206\013\000SeaGreen\000R\225\204\000DarkTurquoise\000\000\246\246\000Firebrick\000\216##\000Yellow\000\377\377\000\000MediumAquamarine\000\000\223\217\000DodgerBlue\000\036\220\377\000CadetBlue\000_\222\236\000YellowGreen\000""2\330""8\000SlateBlue\000~\210\253\000LightSlateBlue\000\204p\377\000Gray10\000\032\032\032\000Gray11\000\034\034\034\000Gray12\000\037\037\037\000Gray13\000!!!\000Gray14\000$$$\000Gray15\000&&&\000Gray16\000)))\000Gray17\000+++\000Gray18\000...\000Gray19\000""000\000DarkOrange\000\377\214\000\000LightGray\000\250\250\250\000Orange\000\377\207\000\000Sienna\000\226R-\000PaleVioletRed\000\333p\223\000snow\000\377\372\372\000Coral\000\377rV\000PaleGoldenrod\000\356\350\252\000OldLace\000\375\365\346\000PaleTurquoise\000\257\356\356\000LightGoldenrodYellow\000\372\372\322\000DeepSkyBlue\000\000\277\377Gray20\000""333\000Gray21\000""666\000Gray22\000""888\000Gray23\000;;;\000Gray24\000===\000Gray25\000@@@\000Gray26\000BBB\000Gray27\000EEE\000Gray28\000GGG\000Gray29\000JJJ\000seashell\000\377\365\356\000Black\000\000\000\000\000DarkViolet\000\224\000\323\000Wheat\000\365\336\263\000Violet\000\234>\316\000LightSeaGreen\000\040\262\252\000FloralWhite\000\377\372\360\000LavenderBlush\000\377\360\365\000Gray30\000MMM\000Gray31\000OOO\000Gray32\000RRR\000Gray33\000TTT\000Gray34\000WWW\000Gray35\000YYY\000Gray36\000\\\\\\\000Gray37\000^^^\000Gray38\000aaa\000Gray39\000ccc\000DeepPink\000\377\024\223\000Green\000\000\377\000White\000\377\377\377\000LightSalmon\000\377\240z\000Transparent\000\000\000\001\000DarkOrchid\000\213\040\213\000purple\000\240\040\360\000BlanchedAlmond\000\377\353\315\000Orchid\000\357\204\357\000LightCoral\000\360\200\200\000SaddleBrown\000\213E\023\000Thistle\000\330\277\330\000DarkSlateBlue\000""8Kf\000burlywood\000\336\270\207\000Gray40\000fff\000Gray41\000iii\000Gray42\000kkk\000MediumPurple\000\223p\333Gray43\000nnn\000Gray44\000ppp\000Maroon\000\217\000RGray45\000sss\000IndianRed\000k99Gray46\000uuu\000Gray47\000xxx\000Gray48\000zzz\000Gray49\000}}}\000MediumOrchid\000\275R\275\000MediumVioletRed\000\325\040y\000Khaki\000\263\263~\000SandyBrown\000\364\244`\000MediumGoldenrod\000\321\301f\000MediumTurquoise\000\000\322\322\000HotPink\000\377i\264\000MistyRose\000\377\344\341\000MintCream\000\365\377\372\000Gray0\000\000\000\000\000Gray1\000\003\003\003\000Gray2\000\005\005\005\000Gray3\000\010\010\010\000Gray4\000\012\012\012\000Gray5\000\015\015\015\000Gray6\000\017\017\017\000Gray7\000\022\022\022\000Gray8\000\024\024\024\000Gray9\000\027\027\027\000RosyBrown\000\274\217\217\000cornsilk\000\377\370\334\000CornflowerBlue\000\"\"\230\000LightSkyBlue\000\207\316\372\000Aquamarine\000""2\277\301\000Beige\000\365\365\334\000Bisque\000\377\344\304\000Gray50\000\177\177\177\000Gray51\000\202\202\202\000Gray52\000\205\205\205\000Gray53\000\207\207\207\000Gray54\000\212\212\212\000Gray55\000\214\214\214\000Gray56\000\217\217\217\000Gray57\000\221\221\221\000Gray58\000\224\224\224\000Gray59\000\226\226\226\000Cyan\000\000\377\377\000lavender\000\346\346\372\000DarkGreen\000\000V-"; sam2p-0.49.2/in_xpm.cpp0000644000175100017510000003413412212351433013027 0ustar ptspts/* * in_xpm.cpp -- read an XPM file * by pts@math.bme.hu at Fri Mar 1 09:56:54 CET 2002 */ /* Imp: test this code with various xpm files! */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #if USE_IN_XPM #if OBJDEP # warning REQUIRES: mapping.o #endif #ifndef USE_BIG_MEMORY #define USE_BIG_MEMORY 0 #endif #include "mapping.hpp" #include "error.hpp" #include "xpmc.h" #include /* memchr() */ #include "gensio.hpp" #define USGE(a,b) ((unsigned char)(a))>=((unsigned char)(b)) #if 0 /** @return true iff params are different strings (not respecting case) */ static int my_strcase_neq(char *s1, char *s2) { while ((USGE(*s1,'A') && USGE('Z',*s1) ? *s1+'a'-'A' : *s1) == (USGE(*s2,'A') && USGE('Z',*s2) ? *s2+'a'-'A' : *s2)) { if (*s1=='\0') return 0; s1++; s2++; } return 1; } #endif #define my_strcase_neq(s1,s2) GenBuffer::nocase_strcmp(s1,s2) /** @ return RGB long */ static Image::Sampled::rgb_t parse_rgb(char const*s) { unsigned v=0, len; Image::Sampled::rgb_t ret; if (!s || !*s) return 0x2000000; /* not found */ // fprintf(stderr, "'%s'\n", s); if (*s=='#') { /* an #RRGGBB web-style color spec; or #RRRRGGGGBBBB */ unsigned dif=0; ++s; while (dif<13 && (USGE(5,(s[dif]|32)-'a') || USGE(9,s[dif]-'0'))) dif++; /* find at most 13 hex digits */ if (s[dif]!='\0' || (dif!=12 && dif!=6)) return 0x2000000; /* not found, spec length error */ dif=(dif==12) ? 3 : 1; // shr=24; while (shr!=0) { ret= (Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<20; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<16; s+=dif; /* ignore lower two hex digits of 16-bit sample value */ ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<12; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<8; s+=dif; /* ignore lower two hex digits of 16-bit sample value */ ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' )<<4; s++; ret|=(Image::Sampled::rgb_t)( USGE(9,*s-'0') ? *s-'0' : 10+(*s|32)-'a' ); return ret; } /* vvv 223==255-32: ignore case when hashing */ char const *p=s; while (*p!='\0') v=xpmColors_mul*v+(223&*(unsigned char const*)p++); p=xpmColors_dat+xpmColors_ofs[(v&65535)%xpmColors_mod]; while (*p!='\0') { len=strlen(p); if (0==my_strcase_neq(p,s)) { p+=len; ret=(((Image::Sampled::rgb_t)((unsigned char const*)p)[1])<<16)+ (((Image::Sampled::rgb_t)((unsigned char const*)p)[2])<<8)+ (((Image::Sampled::rgb_t)((unsigned char const*)p)[3])); return (ret==0x30201) ? 0x1000000 : ret; /* transparent color */ } p+=len+4; } return 0x2000000; /* not found */ } class XPMTok { public: /* Imp: report line numbers on errors */ BEGIN_STATIC_ENUM1(int) T_NO_UNGOT=-1, T_COMMA=257 /* The comma token, outside strings. */ END_STATIC_ENUM() /* XPM states */ BEGIN_STATIC_ENUM1(char) ST_OUT=0, /* outside s string */ ST_STR=1, /* inside a string */ ST_EOF=2 /* EOF */ END_STATIC_ENUM() int getcc(); /** Reads an unsigned int. */ Image::Sampled::dimen_t getDimen(); Image::Sampled::rgb_t getColor(); void read(char *buf, unsigned len); inline void readInStr(char *buf, unsigned len); inline XPMTok(FILE *f_): f(f_), state(ST_OUT), ungot(T_NO_UNGOT) {} inline void ungetcc(int c) { if (c>=0) ungot=c; } void getComma(); protected: FILE *f; /** Current state. */ char state; int ungot; }; int XPMTok::getcc() { int i; if (ungot>=0 /*T_NO_UNGOT<0*/) { i=ungot; ungot=T_NO_UNGOT; return i; } /* Imp: ignore C and C++ style comments (so we won't recognise strings inside comments) */ switch (state) { case ST_OUT: st_out: while (1) { switch ((i=MACRO_GETC(f))) { case -1: state=ST_EOF; return -1; case ',': return T_COMMA; case '"': state=ST_STR; goto st_str; default: /* ignore outside strings */ break; } } case ST_STR: st_str: i=MACRO_GETC(f); if (i==-1) { ue: Error::sev(Error::EERROR) << "XPM: unexpected EOF" << (Error*)0; } else if (i=='"') { state=ST_OUT; goto st_out; } else if (i=='\\') { if ((i=MACRO_GETC(f))==-1) goto ue; if (i=='\n') goto st_str; /* Imp: handle octal, hexadecimal, \n etc. */ } return i&255; default: return -1; } } Image::Sampled::dimen_t XPMTok::getDimen() { Image::Sampled::dimen_t ret=0, bak; int i; while ((i=getcc())==' ' || i=='\t') ; if (USGE(i,'0') && USGE('9',i)) { ret=i-'0'; while (USGE((i=getcc()),'0') && USGE('9',i)) { bak=ret; ret=ret*10+(i-'0'); if (ret/10!=bak) Error::sev(Error::EERROR) << "XPM: dimen overflow" << (Error*)0; } ungetcc(i); return ret; } else Error::sev(Error::EERROR) << "XPM: dimen expected" << (Error*)0; return 0; /*notreached*/ } void XPMTok::getComma() { if (getcc()!=T_COMMA) Error::sev(Error::EERROR) << "XPM: comma expected at " << ftell(f) << (Error*)0; } void XPMTok::read(char *buf, unsigned len) { int i; while (len--!=0) { i=getcc(); // fprintf(stderr,"i=%d\n", i); if (i>=0 && i<=255) *buf++=i; else Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; } } void XPMTok::readInStr(char *buf, unsigned len) { /* Dat: this is OK noew */ // assert(state==ST_STR); assert(ungot<0); param_assert(len>=1); if (state!=ST_STR) { len--; goto real; } int i; while (len--!=0) { if ((i=MACRO_GETC(f))>=0 && i<=255 && i!='"' && i!='\\') *buf++=i; else { assert(i>=0); ungetc(i,f); real: i=getcc(); // fprintf(stderr,"i=%d\n", i); if (i>=0 && i<=255) *buf++=i; else Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; } } } Image::Sampled::rgb_t XPMTok::getColor() { static char tmp[32]; int i; while ((i=getcc())==' ' || i=='\t') ; if (i=='g') { at_g: i=getcc(); if (i!='4') ungetcc(i); goto at_col; } else if (i=='c' || i=='m' || i=='b' || i=='s') { at_col: while ((i=getcc())==' ' || i=='\t') ; char *p=tmp, *pend=tmp+sizeof(tmp)-1; while (i>=33 && i<=126) { if (p==pend) goto cexp; /* color name too long */ *p++=i; i=getcc(); } *p='\0'; if (i==' ' || i=='\t') { /* Maybe another color will come */ while ((i=getcc())==' ' || i=='\t') ; if (i=='g') goto at_g; else if (i=='c' || i=='m' || i=='b' || i=='s') goto at_col; } if (i!=T_COMMA) goto cexp; Image::Sampled::rgb_t ret=parse_rgb(tmp); if (ret==0x2000000) Error::sev(Error::EERROR) << "XPM: unknown color: " << tmp << (Error*)0; return ret; } else { cexp: Error::sev(Error::EERROR) << "XPM: color expected" << (Error*)0; } return 0; /*notreached*/ } static Image::Sampled *in_xpm_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { // Error::sev(Error::EERROR) << "Cannot load XPM images yet." << (Error*)0; XPMTok tok(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); Image::Sampled::dimen_t wd=tok.getDimen(); Image::Sampled::dimen_t ht=tok.getDimen(); Image::Sampled::dimen_t colors=tok.getDimen(); Image::Sampled::dimen_t cpp=tok.getDimen(); /* chars per pixel */ /* width height ncolors cpp [x_hot y_hot] */ int i; /* multiple purpose */ while ((i=tok.getcc())==' ' || i=='\t' || USGE(9,i-'0')) ; tok.ungetcc(i); tok.getComma(); // Error::sev(Error::DEBUG) << "wd="<setTransp(transp); } else { ret=new Image::RGB(wd,ht,8); if (transp!=colors) Error::sev(Error::WARNING) << "XPM: too many colors, transparency blacked" << (Error*)0; } outbuf=ret->getRowbeg(); if (cpp==1) { /* Easy job: make an Indexed image; defer .packPal() */ assert(colors<=256); signed short bin[256], s; memset(bin, 255, sizeof(bin)); /* Make bin[*]=-1 */ for (i=0;(unsigned)isetPal(i, rgb[i]); bin[(unsigned char)tab[i]]=i; } assert(p==pend); while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { if ((i=tok.getcc())<0 || i>255) Error::sev(Error::EERROR) << "XPM: data expected" << (Error*)0; if ((s=bin[i])<0) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=s; } } #if USE_BIG_MEMORY } else if (cpp==2 && colors<=256) { /* Similarly easy job: make an Indexed image; defer .packPal() */ signed short *bin=new short[65536], s; memset(bin, 255, sizeof(*bin) * 65536); /* Make bin[*]=-1 */ for (i=0,p=tab; (unsigned)isetPal(i, rgb[i]); bin[(p[0]<<8)+p[1]]=i; } assert(p==pend); while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { tok.readInStr(pend,2); if ((s=bin[(pend[0]<<8)+pend[1]])<0) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=s; } } delete [] bin; } else if (cpp==2 && colors<=65535) { Image::Sampled::rgb_t rgb1; unsigned short *bin=new unsigned short[65536], s; memset(bin, 255, sizeof(*bin) * 65536); /* Make bin[*]=max */ for (i=0,p=tab; (unsigned)igetRlen(); outbuf!=p; ) { tok.readInStr(pend,2); if ((s=bin[(pend[0]<<8)+pend[1]])==(unsigned short)-1) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=(rgb1=rgb[s])>>16; *outbuf++=rgb1>>8; *outbuf++=rgb1; } } delete [] bin; #endif /* USE_BIG_MEMORY */ } else { /* Now comes the slow, but general solution */ #if USE_IN_XPM_MAPPING /* use Mapping */ if (colors<=256) { Mapping::H h(1); char c; /* vvv `c' might become negative, but it is harmless */ for (p=tab,pend=tab+cpp*colors,c=0; p!=pend; p+=cpp,c++) h.set(p, cpp, &c); /* every color-string should be unique; but no error message if it isn't */ while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; ) { tok.readInStr(pend,cpp); if (NULLP==(pend=h.get(pend, cpp))) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; *outbuf++=*pend; } } } else { /* most general case with Mapping */ if (transp!=colors) Error::sev(Error::WARNING) << "XPM: too many colors, transparency blacked" << (Error*)0; /* Dat: reading a JPEG downsampled to a 256-color XPM takes 3000 ms * with Mapping, and 31000 ms without mapping. Nice speed increase. */ Mapping::H h(3); char tmpcol[3]; for (p=tab,pend=tab+cpp*colors,rp=rgb; p!=pend; p+=cpp,rp++) { tmpcol[0]=rp[0]>>16; tmpcol[1]=rp[0]>>8; tmpcol[2]=rp[0]; h.set(p, cpp, tmpcol); /* every color-string should be unique; but no error message if it isn't */ } while (ht--!=0) { tok.getComma(); for (p=outbuf+ret->getRlen(); outbuf!=p; outbuf+=3) { tok.readInStr(pend,cpp); if (NULLP==(pend=h.get(pend, cpp))) Error::sev(Error::EERROR) << "XPM: unpaletted color" << (Error*)0; memcpy(outbuf, pend, 3); } } } #else /* don't USE_IN_XPM_MAPPING */ Image::Sampled::dimen_t lastcol=0, x; p=tab; /* cache pointer for the last color (lastcol) */ if (colors<=256) { assert(cpp>1); for (lastcol=0;lastcolsetPal(lastcol, rgb[lastcol]); lastcol=0; while (ht--!=0) { // putchar('.'); tok.getComma(); for (x=0;x256 */ while (ht--!=0) { tok.getComma(); for (x=0;x>16; *outbuf++=rgb[lastcol]>>8; *outbuf++=rgb[lastcol]; } } } #endif } delete [] tab; delete [] rgb; /* Dat: we don't check for EOF. Imp: emit a warning? */ // Error::sev(Error::DEBUG) << "rp[-1]=" << rp[-1] << (Error*)0; // while (-1!=(i=tok.getcc())) { putchar(i); } /* fclose((FILE*)file_); */ return ret; } static Image::Loader::reader_t in_xpm_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { return (0==memcmp(buf, "/* XPM */", 9)) ? in_xpm_reader : 0; } #else # define in_xpm_checker NULLP #endif /* USE_IN_XPM */ Image::Loader in_xpm_loader = { "XPM", in_xpm_checker, 0 }; sam2p-0.49.2/in_tga.cpp0000644000175100017510000000346112211371426013000 0ustar ptspts/* * in_tga.cpp -- read a Truevision Targa TGA file * by pts@fazekas.hu at Sat Mar 2 00:49:35 CET 2002 * */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #include "gensio.hpp" /* Filter::UngetFILED */ #if USE_IN_TGA #include "input-tga.ci" /* defines tga_load_image */ static Image::Sampled *in_tga_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; bitmap_type bitmap=tga_load_image(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else assert(0 && "invalid TGA depth"); delete [] BITMAP_BITS(bitmap); return ret; } static Image::Loader::reader_t in_tga_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) { /* vvv Unfortunately not all targa images have that footer */ /* return 0==memcmp(bufend+Image::Loader::MAGIC_LEN-18, "TRUEVISION-XFILE", 16) */ /* vvv 30..127: Aladdin Ghostscript adds 58 bytes of header */ return (unsigned char)buf[0]>=30 && (unsigned char)buf[0]<=63 && (unsigned char)buf[1]<=11 && ((unsigned char)buf[16]<=8 || (unsigned char)buf[16]==24) ? in_tga_reader : 0; } #else #define in_tga_checker NULLP #endif /* USE_IN_XPM */ Image::Loader in_tga_loader = { "TGA", in_tga_checker, 0 }; sam2p-0.49.2/minips.cpp0000644000175100017510000011047412212351433013036 0ustar ptspts/* * minips.cpp * by pts@fazekas.hu at Sat Mar 9 21:33:35 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "minips.hpp" #include "error.hpp" #include "gensio.hpp" #if USE_DICT_MAPPING #if OBJDEP # warning REQUIRES: mapping.o #endif #include "mapping.hpp" #endif #include /* sscanf() */ #include /* memset() */ static inline bool is_ps_white(char c) { return c=='\n' || c=='\r' || c=='\t' || c==' ' || c=='\f' || c=='\0'; } static inline bool is_ps_name(char c) { /* Dat: we differ from PDF since we do not treat the hashmark (`#') special * in names. * Dat: we differ from PostScript since we accept names =~ /[!-~]/ */ return c>='!' && c<='~' && c!='/' && c!='%' && c!='{' && c!='}' && c!='<' && c!='>' && c!='[' && c!=']' && c!='(' && c!=')'; /* Dat: PS avoids: /{}<>()[]% \n\r\t\000\f\040 */ } /** @param b: assume null-terminated @return true on erro * @return false on error */ static inline bool toInteger(SimBuffer::Flat const&b, signed long &ret) { int n=0; /* BUGFIX?? found by __CHECKER__ */ // b.term0(); return sscanf(b(), "%li%n", &ret, &n)<1 || b[n]!='\0'; } static inline bool toHex(char const*s, unsigned long &ret) { int n=0; return sscanf(s, "%lx%n", &ret, &n)<1 || s[n]!='\0'; } static inline bool toHex3(char const*s, char ret[3]) { unsigned long l; if (toHex(s, l)) return true; ret[0]=((l>>8)&15)*17; ret[1]=((l>>4)&15)*17; ret[2]=(l&15)*17; return false; } static inline bool toHex6(char const*s, char ret[3]) { unsigned long l; if (toHex(s, l)) return true; ret[0]=(l>>16)&255; ret[1]=(l>>8)&255; ret[2]=l&255; return false; } /** @param b: assume null-terminated @return true on error */ static inline bool toReal(SimBuffer::Flat const&b, double &ret) { int n; char c; // b.term0(); /* Dat: glibc accepts "12e", "12E", "12e+" and "12E-" */ return sscanf(b(), "%lf%n", &ret, &n)<1 || (c=b[n-1])=='e' || c=='E' || c=='+' || c=='-' || b[n]!='\0'; } /** This is not correct if blen cuts the real number into two strings. * @param b: assume null-terminated @return true on error */ static inline bool toReal(char const *b, slen_t blen, double &ret) { int n; char c; // b.term0(); /* Dat: glibc accepts "12e", "12E", "12e+" and "12E-" */ return sscanf(b, "%lf%n", &ret, &n)<1 || (c=b[n-1])=='e' || c=='E' || c=='+' || c=='-' || (slen_t)n!=blen; } MiniPS::Tokenizer::Tokenizer(GenBuffer::Readable& in_): in(in_), ungot(NO_UNGOT) { } int MiniPS::Tokenizer::yylex() { int c=0; /* dummy initialization */ bool hi; unsigned hv; slen_t nest, len; signed long l; double d; Real::metric_t metric; char saved; if (ungot==EOFF) return EOFF; if (ungot!=NO_UNGOT) { c=ungot; ungot=NO_UNGOT; goto again; } again_getcc: c=in.vi_getcc(); again: switch (c) { case -1: eof: return ungot=EOFF; case '\n': case '\r': case '\t': case ' ': case '\f': case '\0': goto again_getcc; case '%': /* one-line comment */ while ((c=in.vi_getcc())!='\n' && c!='\r' && c!=-1) ; if (c==-1) goto eof; goto again_getcc; case '{': case '[': return '['; case '}': case ']': return ']'; case ')': goto err; case '>': if (in.vi_getcc()!='>') goto err; return '>'; case '<': if ((c=in.vi_getcc())==-1) { uf_hex: Error::sev(Error::EERROR) << "miniPS: unfinished hexstr" << (Error*)0; } if (c=='<') return '<'; if (c=='~') Error::sev(Error::EERROR) << "miniPS: a85str unsupported" << (Error*)0; tv.bb=&b; b.clear(); hi=true; while (c!='>') { if ((hv=b.hexc2n(c))!=16) { if (hi) { b << (char)(hv<<4); hi=false; } else { b.end_()[-1]|=hv; hi=true; } } else if (!is_ps_white(c)) Error::sev(Error::EERROR) << "miniPS: syntax error in hexstr" << (Error*)0; if ((c=in.vi_getcc())==-1) goto uf_hex; } /* This is correct even if an odd number of hex digits have arrived */ return '('; case '(': tv.bb=&b; b.clear(); nest=1; while ((c=in.vi_getcc())!=-1) { redo: if (c==')' && --nest==0) return '('; if (c!='\\') { if (c=='(') nest++; b << (char)c; continue; } /* read a backslash */ switch (c=in.vi_getcc()) { case -1: goto uf_str; case 'n': b << '\n'; break; case 'r': b << '\r'; break; case 't': b << '\t'; break; case 'b': b << '\010'; break; /* \b and \a conflict between -ansi and -traditional */ case 'f': b << '\f'; break; default: if (c<'0' || c>'7') { b << (char)c; break; } hv=c-'0'; /* read at most 3 octal chars */ if ((c=in.vi_getcc())==-1) goto uf_str; if (c<'0' || c>'7') { b << (char)hv; goto redo; } hv=8*hv+(c-'0'); if ((c=in.vi_getcc())==-1) goto uf_str; if (c<'0' || c>'7') { b << (char)hv; goto redo; } b << (char)(8*hv+(c-'0')); } /* SWITCH */ } /* WHILE */ uf_str: Error::sev(Error::EERROR) << "miniPS: unfinished str" << (Error*)0; case '/': /* fall-through, b will begin with '/' */ default: /* /nametype, /integertype or /realtype */ tv.bb=&b; b.clear(); b.clear(); b << (char)c; while ((c=in.vi_getcc())!=-1 && is_ps_name(c)) b << (char)c; ungot=c==-1?EOFF:c; if (b[0]=='/') return '/'; b.term0(); /* Dat: we don't support base-n number such as `16#100' == 256 in PostScript */ if (!toInteger(b, l)) { tv.i=l; return '1'; } /* Dat: call toInteger _before_ toReal */ // if (!toReal(b, tv.d)) { fprintf(stderr,"%f;\n", tv.d); } /* assert(tv.bb!=NULLP); */ len=b.getLength(); if (!toReal(b, d)) { /* tv.bb is also valid */ tv.r=new Real(d, b(), len); return '.'; } if (len>2 && (metric=Real::str2metric(b()+len-2))!=Real::ME_COUNT) { saved=b[len-2]; b[len-2]='\0'; if (!toReal(b, d)) { tv.r=new Real(d, b(), len-2); tv.r->setMetric(metric); return ':'; /* Real with metric */ } b[len-2]=saved; } return 'E'; /* /nametype */ } err: Error::sev(Error::EERROR) << "miniPS: syntax error" << (Error*)0; goto again_getcc; /* notreached */ } /* --- */ #if 0 inline static unsigned typerr() { assert(0); return 0; } #endif unsigned MiniPS::getType(VALUE v) { return (v&1)!=0 ? T_INTEGER : v+0U>Qmax_+0U ? RVALUE(v)->getType() : v==Qnull ? T_NULL+0/*avoid gcc-3.0 ld bug*/ : T_BOOLEAN; } char const* MiniPS::getTypeStr(unsigned u) { static char const* strs[]= { (char const*)NULLP, "null", "boolean", "integer", "real", "string", "array", "dict", "name", "Ename", "void" }; // return strs[getType(v)]; return strs[u]; } void MiniPS::delete0(VALUE v) { if (isDirect(v)) return; Value *vp=RVALUE(v); unsigned ty=vp->getType(); if (ty==T_DICT) RDICT(v)->free(); else if (ty==T_ARRAY) RARRAY(v)->free(); else if (ty==T_VOID) ; else if (vp->hasPtr()) delete [] vp->begin_(); delete vp; /* BUGFIX at Sat Sep 7 12:50:13 CEST 2002 */ } void MiniPS::dump(VALUE v, unsigned indent) { Files::FILEW sout(stdout); dump(sout, v, indent); } void MiniPS::dump(GenBuffer::Writable& out_, VALUE v, unsigned indent) { if (v==Qnull) out_ << "null"; else if (v==Qtrue) out_ << "true"; else if (v==Qfalse) out_ << "false"; else if ((v&1)!=0) out_ << (v/2); /* prints a signed integer */ else { Value *vp=RVALUE(v); unsigned ty=vp->getType(); if (ty==T_STRING) { SimBuffer::Static s((char*)vp->begin_(), vp->getLength()); SimBuffer::B b; b.appendDumpPS(s, true); out_ << b; } else if (ty==T_SNAME || ty==T_ENAME) { out_.vi_write((char*)vp->begin_(), vp->getLength()); } else if (ty==T_REAL) { RREAL(v)->dump(out_); } else if (ty==T_ARRAY) { if (!vp->isDumping()) { /* Imp: thread-safe locking */ RARRAY(v)->dump(out_, indent); } else out_ << "[...]"; } else if (ty==T_DICT) { if (!vp->isDumping()) { /* Imp: thread-safe locking */ RDICT(v)->dump(out_, indent); } else out_ << "<<...>>"; } else assert(0 && "unknown MiniPS type"); } } /* --- */ /* Sat Sep 7 12:30:19 CEST 2002 */ const double MiniPS::Real::me_factor[MiniPS::Real::ME_COUNT]={ 1.0L, /* 1 bp = 1 bp (big point) */ 72.0L, /* 1 in = 72 bp (inch) */ 72.0L/72.27, /* 1 pt = 72/72.27 bp (point) */ 12.0L*72.0/72.27, /* 1 pc = 12*72/72.27 bp (pica) */ 1238.0L/1157.0*72.0/72.27, /* 1 dd = 1238/1157*72/72.27 bp (didot point) [about 1.06601110141206 bp] */ 12.0L*1238.0/1157.0*72.0/72.27, /* 1 cc = 12*1238/1157*72/72.27 bp (cicero) */ 72.0L/72.27/65536.0, /* 1 sp = 72/72.27/65536 bp (scaled point) */ 72.0L/2.54, /* 1 cm = 72/2.54 bp (centimeter) */ 7.2L/2.54, /* 1 mm = 7.2/2.54 bp (millimeter) */ }; /* Sat Sep 7 12:30:19 CEST 2002 */ char const* const MiniPS::Real::me_psfactor[MiniPS::Real::ME_COUNT]={ "", /* 1 bp = 1 bp (big point) */ " 72 mul", /* 1 in = 72 bp (inch) */ " 72 mul 72.27 div", /* 1 pt = 72/72.27 bp (point) */ " 864 mul 72.27 div", /* 1 pc = 12*72/72.27 bp (pica) */ " 891.36 mul 836.164 div", /* 1 dd = 1238/1157*72/72.27 bp (didot point) [about 1.06601110141206 bp] */ " 10696.32 mul 836.164 div", /* 1 cc = 12*1238/1157*72/72.27 bp (cicero) */ " 0.72 mul 47362.8672 div", /* 1 sp = 72/72.27/65536 bp (scaled point) */ " 72 mul 2.54 div", /* 1 cm = 72/2.54 bp (centimeter) */ " 720 mul 254 div", /* 1 mm = 7.2/2.54 bp (millimeter) */ }; MiniPS::Real::Real(double d_, char const*ptr_, ii_t len_): d(d_), metric(0), dumpPS(false) { ty=T_REAL; char *p=new char[len_+1]; memcpy(ptr=p, ptr_, len=len_); p[len_]='\0'; } void MiniPS::Real::dump(GenBuffer::Writable &out_, bool dumpPS_force) { char buf[64]; /* Imp: should be enough?? */ if (metric!=0 && (dumpPS_force || dumpPS)) { sprintf(buf, "%"PTS_CFG_PRINTFGLEN"g%s", d, me_psfactor[metric]); } else { sprintf(buf, "%"PTS_CFG_PRINTFGLEN"g", d*me_factor[metric]); } out_ << buf; } MiniPS::Real::metric_t MiniPS::Real::str2metric(char const str[2]) { switch (str[0]) { case 'b': if (str[1]=='p') return ME_bp; break; case 'i': if (str[1]=='n') return ME_in; break; case 'p': if (str[1]=='t') return ME_pt; if (str[1]=='c') return ME_pc; break; case 'd': if (str[1]=='d') return ME_dd; break; case 'c': if (str[1]=='c') return ME_cc; if (str[1]=='m') return ME_cm; break; case 's': if (str[1]=='p') return ME_sp; break; case 'm': if (str[1]=='m') return ME_mm; break; } return ME_COUNT; } bool MiniPS::Real::isDimen(char const *str) { double d; slen_t len=strlen(str); if (!toReal(str, len, d)) return true; return len>2 && str2metric(str+len-2)!=ME_COUNT && !toReal(str, len-2, d); } MiniPS::String::String(char const*ptr_, ii_t len_) { char *p=new char[len_+1]; memcpy(ptr=p, ptr_, len=len_); p[len_]='\0'; ty=T_STRING; } void MiniPS::String::replace(char const*ap, slen_t alen, char const*bp, slen_t blen) { char *p=new char[alen+blen+1]; memcpy(p, ap, alen); memcpy(p+alen, bp, blen); p[alen+blen]='\0'; delete [] (char*)ptr; ptr=p; } MiniPS::Sname::Sname(char const*ptr_, ii_t len_) { param_assert(len_>=1 && ptr_[0]=='/'); char *p=new char[len_+1]; memcpy(ptr=p, ptr_, len=len_); p[len_]='\0'; ty=T_SNAME; } bool MiniPS::Sname::equals(Sname const&other) { return len==other.len && 0==memcmp(ptr, other.ptr, len); } bool MiniPS::Sname::equals(char const*other) { return 0==strcmp(1+(char*)ptr, other); } MiniPS::Ename::Ename(char const*ptr_, ii_t len_) { param_assert(len_>=1 && ptr_[0]!='/'); char *p=new char[len_+1]; memcpy(ptr=p, ptr_, len=len_); p[len_]='\0'; ty=T_ENAME; } bool MiniPS::Ename::equals(Ename const&other) { return len==other.len && 0==memcmp(ptr, other.ptr, len); } bool MiniPS::Ename::equals(char const*other, slen_t otherlen) { return (slen_t)len==otherlen && 0==memcmp(ptr, other, otherlen); } bool MiniPS::Ename::equals(char const*other) { return 0==strcmp((char*)ptr, other); } MiniPS::Array::Array() { alloced=16; ptr=new VALUE[alloced=16]; len=0; ty=T_ARRAY; } void MiniPS::Array::free() { VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) delete0(*p++); delete [] (VALUE*)ptr; } void MiniPS::Array::push(VALUE v) { if (len==alloced) extend(len+1); ((VALUE*)ptr)[len++]=v; } MiniPS::VALUE MiniPS::Array::get(ii_t index) { return (index<0 || index>=len) ? Qundef : ((VALUE*)ptr)[index]; } void MiniPS::Array::set(ii_t index, VALUE val) { param_assert(index>=0 && index=0); while (newlen>newalloced) newalloced<<=1; VALUE *newptr=new VALUE[newalloced]; memcpy(newptr, ptr, len*sizeof(VALUE)); delete [] (VALUE*)ptr; ptr=newptr; alloced=newalloced; /* len remains unchanged */ } void MiniPS::Array::getFirst(VALUE *&val) { if (len==0) { val=(VALUE*)NULLP; return; } val=(VALUE*)ptr; } void MiniPS::Array::getNext(VALUE *&val) { val++; if (len+(VALUE*)ptr==val) val=(VALUE*)NULLP; } #if USE_DICT_MAPPING MiniPS::Dict::Dict() { /* Sun Mar 24 21:02:41 CET 2002 */ ptr=(void*)new Mapping::H(sizeof(VALUE)+1); /* hash value format: a VALUE, and a flag (0 or 1) indicating touchedness */ len=0; /* meaningless */ ty=T_DICT; } void MiniPS::Dict::free() { char const*const* keyy; slen_t keylen; VALUE *val = 0; /* pacify gcc-4.2.1 by giving initial value */ bool touched; getFirst(keyy, keylen, val, touched); while (keyy!=(char const*const*)NULLP) { MiniPS::delete0(*val); getNext(keyy, keylen, val, touched); } delete (Mapping::H*)ptr; } void MiniPS::Dict::put(char const*key, VALUE val) { put(key,strlen(key),val); } MiniPS::VALUE MiniPS::Dict::push(char const*keys, slen_t keylen, VALUE val) { if (keys[0]=='/') { keys++; keylen--; } char *has=((Mapping::H*)ptr)->get(keys,keylen); VALUE ret=Qundef; if (has!=(char const*)NULLP) { memcpy(&ret, has, sizeof(VALUE)); // printf("found=/%s.\n", keys); /* No delete0(); deliberately. */ memcpy(has, &val, sizeof(VALUE)); has[sizeof(VALUE)]=0; } else { char tmp[sizeof(VALUE)+1]; memcpy(tmp, &val, sizeof(VALUE)); tmp[sizeof(VALUE)]=0; ((Mapping::H*)ptr)->set(keys,keylen,tmp); } return ret; } void MiniPS::Dict::put(char const*keys, slen_t keylen, VALUE val) { if (keys[0]=='/') { keys++; keylen--; } char *has=((Mapping::H*)ptr)->get(keys,keylen); if (has!=NULLP) { VALUE ret=Qundef; memcpy(&ret, has, sizeof(VALUE)); MiniPS::delete0(ret); memcpy(has, &val, sizeof(VALUE)); has[sizeof(VALUE)]=0; } else { char tmp[sizeof(VALUE)+1]; memcpy(tmp, &val, sizeof(VALUE)); tmp[sizeof(VALUE)]=0; ((Mapping::H*)ptr)->set(keys,keylen,tmp); } } MiniPS::VALUE MiniPS::Dict::get(char const*keys, slen_t keylen) { if (keys[0]=='/') { keys++; keylen--; } char *has=((Mapping::H*)ptr)->get(keys,keylen); VALUE ret=Qundef; if (has!=NULLP) memcpy(&ret, has, sizeof(VALUE)); return ret; } MiniPS::VALUE MiniPS::Dict::get1(char const*keys, slen_t keylen) { if (keys[0]=='/') { keys++; keylen--; } char *has=((Mapping::H*)ptr)->get(keys,keylen); VALUE ret=Qundef; if (has!=NULLP) { memcpy(&ret, has, sizeof(VALUE)); has[sizeof(VALUE)]=1; } return ret; } void MiniPS::Dict::untouch(char const*keys, slen_t keylen) { if (keys[0]=='/') { keys++; keylen--; } char *has=((Mapping::H*)ptr)->get(keys,keylen); if (has!=NULLP) has[sizeof(VALUE)]=0; } void MiniPS::Dict::getFirst(char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched) { char *has; // key=(char const*const*)NULLP;return; ((Mapping::H*)ptr)->getFirst(key, keylen, has); if (key==(char const*const*)NULLP) return; val=PTS_align_cast(VALUE*,has); touched=has[sizeof(VALUE)]!=0; } void MiniPS::Dict::getNext (char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched) { char *has; ((Mapping::H*)ptr)->getNext(key, keylen, has); if (key==(char const*const*)NULLP) return; val=PTS_align_cast(VALUE*,has); touched=has[sizeof(VALUE)]!=0; } void MiniPS::Dict::dump(GenBuffer::Writable &out_, unsigned indent, bool dump_delimiters) { dumping=true; slen_t len=((Mapping::H*)ptr)->getLength(); if (len==0) { if (dump_delimiters) out_ << "<<>>"; } else { char const*const* keyy; slen_t keylen; VALUE *val = 0; /* pacify gcc-4.2.1 by giving initial value */ bool touched; indent+=2; char *spaces=new char[indent]; memset(spaces, ' ', indent); // spaces[indent]='\n'; if (dump_delimiters) out_ << "<< % " << len << " key(s)\n"; getFirst(keyy, keylen, val, touched); while (keyy!=(char const*const*)NULLP) { out_.vi_write(spaces, indent); out_.vi_putcc('/'); out_.vi_write(*keyy, keylen); /* Imp: PDF #...-quoting */ out_ << " "; MiniPS::dump(out_, *val, indent); out_.vi_putcc('\n'); getNext(keyy, keylen, val, touched); } if (dump_delimiters) { out_.vi_write(spaces, indent-=2); out_ << ">>"; } } dumping=false; } void MiniPS::Dict::extend(ii_t) {} #else /* a MiniPS::Dict implementation with linear search */ MiniPS::Dict::Dict() { alloced=16; ptr=new VALUE[alloced=16]; len=0; ty=T_DICT; } void MiniPS::Dict::free() { VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) delete0(*p++); delete [] (VALUE*)ptr; } void MiniPS::Dict::put(char const*key, VALUE val) { return put(key,strlen(key),val); } MiniPS::VALUE MiniPS::Dict::push(char const*keys, slen_t keylen, VALUE val) { // param_assert(key[0]=='/'); if (keys[0]=='/') { keys++; keylen--; } VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { if (MiniPS::RENAME(p[0]&~1)->equals(key,keylen)) { VALUE v=p[1]; p[1]=val; return v; } p+=2; } if (len==alloced) extend(len+2); ((VALUE*)ptr)[len++]=(MiniPS::VALUE)new Ename(keys,keylen); ((VALUE*)ptr)[len++]=val; return Qundef; } void MiniPS::Dict::put(char const*keys, slen_t keylen, VALUE val) { // param_assert(key[0]=='/'); if (keys[0]=='/') { keys++; keylen--; } //void MiniPS::Dict::put(VALUE key, VALUE val) { //param_assert(MiniPS::getType(key)==T_ENAME); VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { if (MiniPS::RENAME(p[0]&~1)->equals(keys,keylen)) { MiniPS::delete0(p[1]); p[1]=val; return; } p+=2; } if (len==alloced) extend(len+2); ((VALUE*)ptr)[len++]=(MiniPS::VALUE)new Ename(keys,keylen); ((VALUE*)ptr)[len++]=val; } MiniPS::VALUE MiniPS::Dict::get(char const*key, slen_t keylen) { if (key[0]=='/') { key++; keylen--; } VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { //printf("for=%s trying=%s.\n", key, MiniPS::RENAME(p[0]&~1)->begin_()); if (MiniPS::RENAME(p[0]&~1)->equals(key, keylen)) return p[1]; p+=2; } return Qundef; } MiniPS::VALUE MiniPS::Dict::get1(char const*key, slen_t keylen) { if (key[0]=='/') { key++; keylen--; } VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { //printf("for=%s trying=%s.\n", key, MiniPS::RENAME(p[0]&~1)->begin_()); if (MiniPS::RENAME(p[0]&~1)->equals(key,keylen)) { /* dirty, black magic */ p[0]|=1; return p[1]; } p+=2; } return Qundef; } void MiniPS::Dict::untouch(char const*key, slen_t keylen) { if (key[0]=='/') { key++; keylen--; } VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { if (MiniPS::RENAME(p[0]&~1)->equals(key,keylen)) { p[0]&=~1; return; } p+=2; } } void MiniPS::Dict::getFirst(char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched) { // assert(MiniPS::getType(((VALUE*)ptr)[0])==T_ENAME); if (len==0) { key=(char const*const*)NULLP; return; } assert(ptr!=NULLP); Ename *skey=(Ename*)(((VALUE*)ptr)[0]&~1); key=(char**)&skey->ptr; keylen=skey->len; val=((VALUE*)ptr)+1; touched=(((VALUE*)ptr)[0]&1)!=0; } void MiniPS::Dict::getNext (char const*const*& key, slen_t &keylen, VALUE *&val, bool &touched) { val+=2; if (len+(VALUE*)ptr==(VALUE*)val-1) { key=(char const*const*)NULLP; return; } Ename *skey=RENAME(val[-1]&~1); // assert(MiniPS::getType((VALUE)skey)==T_ENAME); key=(char**)&skey->ptr; keylen=skey->len; touched=(val[-1]&1)!=0; } #if 0 /* obsolete */ void MiniPS::Dict::getFirst(VALUE *&key, VALUE *&val) { if (len==0) { key=val=(VALUE*)NULLP; return; } assert(ptr!=NULLP); key=(VALUE*)ptr; val=key+1; } void MiniPS::Dict::getNext(VALUE *&key, VALUE *&val) { key+=2; if (len+(VALUE*)ptr==key) key=val=(VALUE*)NULLP; else val=key+1; } #endif void MiniPS::Dict::dump(GenBuffer::Writable &out_, unsigned indent, bool dump_delimiters) { assert(len>=0 && (len&1)==0); if (len==0) { if (dump_delimiters) out_ << "<<>>"; } else { indent+=2; char *spaces=new char[indent]; memset(spaces, ' ', indent); // spaces[indent]='\n'; if (dump_delimiters) out_ << "<< % " << (len/2) << " key(s)\n"; VALUE *p=(VALUE*)ptr, *pend=p+len; while (p!=pend) { out_.vi_write(spaces, indent); MiniPS::dump(out_, *p++, indent); out_ << " "; MiniPS::dump(out_, *p++, indent); /*if(p!=pend)*/ out_.vi_putcc('\n'); // out_ << "\n"; } if (dump_delimiters) { out_.vi_write(spaces, indent-=2); out_ << ">>"; } } } void MiniPS::Dict::extend(ii_t newlen) { if (newlen<=alloced) return; ii_t newalloced=alloced; assert(alloced>=0); while (newlen>newalloced) newalloced<<=1; VALUE *newptr=new VALUE[newalloced]; memcpy(newptr, ptr, len*sizeof(VALUE)); delete [] (VALUE*)ptr; ptr=newptr; alloced=newalloced; /* len remains unchanged */ } #endif /* --- */ MiniPS::Parser::Parser(char const *filename_) { FILE *ff; ff=(filename_[0]=='-' && filename_[1]=='\0')? stdin: fopen(filename_, "r"); /* not "rb" */ if (ff==NULLP) Error::sev(Error::EERROR) << "MiniPS::Parser: cannot open file: " << FNQ(filename_) << (Error*)0; f=(FILEP)ff; rd=new Files::FILER(ff); tok=new Tokenizer(*rd); master=(Parser*)NULLP; free_level=4; unread=Tokenizer::NO_UNGOT; depth=0; specRuns=(MiniPS::Dict*)NULLP; specRunsDelete=false; } MiniPS::Parser::Parser(FILEP f_) { f=f_; rd=new Files::FILER(PTS_align_cast(FILE*,f_)); tok=new Tokenizer(*rd); master=(Parser*)NULLP; free_level=3; unread=Tokenizer::NO_UNGOT; depth=0; specRuns=(MiniPS::Dict*)NULLP; specRunsDelete=false; } MiniPS::Parser::Parser(GenBuffer::Readable *rd_) { f=(FILEP)NULLP; rd=rd_; tok=new Tokenizer(*rd); master=(Parser*)NULLP; free_level=2; unread=Tokenizer::NO_UNGOT; depth=0; specRuns=(MiniPS::Dict*)NULLP; specRunsDelete=false; } MiniPS::Parser::Parser(Tokenizer *tok_) { master=(Parser*)NULLP; f=(FILEP)NULLP; rd=(GenBuffer::Readable*)NULLP; tok=tok_; master=(Parser*)NULLP; free_level=0; unread=Tokenizer::NO_UNGOT; depth=0; specRuns=(MiniPS::Dict*)NULLP; specRunsDelete=false; } MiniPS::Parser::Parser(Parser *master_) { f=(FILEP)NULLP; rd=(GenBuffer::Readable*)NULLP; tok=(Tokenizer*)NULLP; master=master_; free_level=1; unread=Tokenizer::NO_UNGOT; depth=0; specRuns=(MiniPS::Dict*)NULLP; specRunsDelete=false; } MiniPS::Parser::~Parser() { /* We delete the master here! */ if (master!=NULLP) delete master; /* recursive ~Parser() call */ if (free_level>=2) delete tok; if (free_level>=3) delete rd; if (free_level>=4) fclose(PTS_align_cast(FILE*,f)); if (specRunsDelete) delete0((VALUE)specRuns); } void MiniPS::Parser::addSpecRun(char const* filename_, GenBuffer::Readable *rd_) { if (specRuns==NULLP) { specRunsDelete=true; specRuns=new MiniPS::Dict(); } specRuns->put(filename_, (MiniPS::VALUE)new MiniPS::Void(rd_)); } void MiniPS::Parser::setSpecRuns(MiniPS::Dict *newSpecRuns) { if (newSpecRuns!=specRuns) { if (specRunsDelete) delete0((VALUE)specRuns); specRunsDelete=false; specRuns=newSpecRuns; } } void MiniPS::Parser::setDepth(unsigned depth_) { if (depth_>=MAX_DEPTH) Error::sev(Error::EERROR) << "MiniPS::Parser: `run' inclusion too deep" << (Error*)0; depth=depth_; } MiniPS::VALUE MiniPS::Parser::parse1(int closer, int sev) { char *beg=0; slen_t len=0; /* pacify g++-2.91 */ Real::metric_t metric; Real *r=0; /* pacify g++-2.91 */ VALUE v, w; if (master!=NULLP) { from_master: /* vvv EOF_ALLOWED means: the master cannot close our open '>' or ']' */ if ((v=master->parse1(EOF_ALLOWED, sev))!=Qundef) return v; delete0(v); delete master; master=(Parser*)NULLP; // fprintf(stderr, "closed master\n"); } // return parse1_real(closer); int i=0; if (unread!=Tokenizer::NO_UNGOT) { i=unread; unread=Tokenizer::NO_UNGOT; } else i=tok->yylex(); // fprintf(stderr, "i=%d i='%c'\n", i, i); switch (i) { case Tokenizer::EOFF: case ']': case '>': if (closer==i) return Qundef; /* EOF */ Error::sev((Error::level_t)sev) << "MiniPS::Parser: premature EOF (early closer: " << (int)i << ')' << (Error*)0; return Qerror; /* parse error */ case '(': { beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); VALUE v=(VALUE)new String(beg, len); /* Imp: resolve memory leak here */ i=tok->yylex(); beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); if (i!='E' || len!=3 || 0!=memcmp(beg,"run",3)) { unread=i; return v; } /* Process external file inclusion */ assert(master==NULLP); /* Imp: prevent infinite recursion */ if (specRuns!=NULLP && Qundef!=(w=specRuns->get(RSTRING(v)->begin_(), RSTRING(v)->getLength()))) { master=new Parser((GenBuffer::Readable*)RVOID(w)->getPtr()); } else { master=new Parser(RSTRING(v)->getCstr()); /* Open external file. */ } delete0(v); master->setDepth(depth+1); master->setSpecRuns(specRuns); goto from_master; } case '/': beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); return (VALUE)new Sname(beg, len); case ':': /* Real with metric */ return (VALUE)tok->lastTokVal().r; case '.': // fprintf(stderr, "d=%g\n", tok->lastTokVal().d); // fprintf(stderr, "b=(%s)\n", tok->lastTokVal().b()); // assert(tok->lastTokVal().bb!=NULLP); // beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); // r=new Real(tok->lastTokVal().d, beg, len); r=tok->lastTokVal().r; i=tok->yylex(); beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); if (i!='E' || len!=2 || (metric=Real::str2metric(beg))==Real::ME_COUNT) { unread=i; } else { r->setMetric(metric); } return (VALUE)r; case '1': i=tok->yylex(); beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); if (i!='E' || len!=2 || (metric=Real::str2metric(beg))==Real::ME_COUNT) { unread=i; return Qinteger(tok->lastTokVal().i); } else { /* integer with metric is auto-converted to Real */ r=new Real(tok->lastTokVal().i, beg, len); r->setMetric(metric); } return (VALUE)r; case 'E': { beg=tok->lastTokVal().bb->begin_(); len=tok->lastTokVal().bb->getLength(); // fprintf(stderr, "L=%d\n", bb->getLength()); // assert(0); tok->lastTokVal().bb->term0(); if (0==strcmp(beg,"true")) return Qtrue; if (0==strcmp(beg,"false")) return Qfalse; if (0==strcmp(beg,"null")) return Qnull; if (closer==EOF_ILLEGAL_POP && 0==strcmp(beg,"pop")) return Qpop; Error::sev((Error::level_t)sev) << "MiniPS::Parser: unknown Ename: " << (*tok->lastTokVal().bb) << (Error*)0; return Qerror; } case '[': { Array *ap=new Array(); VALUE v; while (Qundef!=(v=parse1(']', sev))) { if (v==Qerror) return Qerror; ap->push(v); } return (VALUE)ap; } case '<': { Dict *ap=new Dict(); VALUE key, val; while (1) { if (Qundef==(key=parse1('>', sev))) break; if (key==Qerror) return Qerror; if (getType(key)!=T_SNAME) { MiniPS::delete0(key); Error::sev(Error::EERROR) << "MiniPS::Parser: dict key must be a /name" << (Error*)0; return Qerror; } val=parse1(EOF_ILLEGAL_POP, sev); /* No EOF allowed here */ if (val==Qerror) { MiniPS::delete0(key); return Qerror; } if (val!=Qpop) { // if (Qundef!=ap->push(RSNAME(key)->begin_(),RSNAME(key)->getLength(),val)) Error::sev(Error::EERROR) << "MiniPS::Parser: duplicate dict key" << (Error*)0; /* ^^^ should free if non-fatal error */ if (Qundef!=(v=ap->push(RSNAME(key)->begin_(),RSNAME(key)->getLength(),val))) { Error::sev(Error::WARNING) << "MiniPS::Parser: overriding previous dict key: " << RSNAME(key)->begin_() << (Error*)0; MiniPS::delete0(v); } } MiniPS::delete0(key); } return (VALUE)ap; } default: assert(0); } return Qerror; /* NOTREACHED */ } void MiniPS::scanf_dict(VALUE job, bool show_warnings, ...) { va_list ap; Dict *dict=RDICT(job); char *key; unsigned ty; char hex3[3]; VALUE default_, *dst, got; if (getType(job)!=T_DICT) Error::sev(Error::EERROR) << "scanf_dict: dict expected" << (Error*)0; PTS_va_start(ap, show_warnings); // "InputFile", MiniPS::T_STRING, MiniPS::Qundef, &InputFile, // "OutputFile", MiniPS::T_STRING, MiniPS::Qundef, &OutputFile, // "Profile", MiniPS::T_ARRAY, MiniPS::Qundef, &Profiles, // NULLP while (NULLP!=(key=va_arg(ap, char*))) { slen_t keylen=strlen(key); if (*key=='/') key++; ty=va_arg(ap, unsigned); default_=va_arg(ap, VALUE); dst=va_arg(ap, VALUE*); got=(show_warnings) ? dict->get1(key,keylen) : dict->get(key,keylen); if (got==Qundef) { got = (ty==S_SENUM) ? RDICT(default_)->get(" ",1) /* get the default value */ : (ty==S_FUNC) ? ((VALUE(*)(VALUE))default_)(Qundef) : default_; if (got==Qundef) Error::sev(Error::EERROR) << "scanf_dict: required key missing: /" << key << (Error*)0; /* type of default value is unchecked deliberately */ } else switch (ty) { case S_RGBSTR: /* Dat: red is: (\377\0\0), (#f00), (#ff0000) */ if (getType(got)!=T_STRING || !( RSTRING(got)->getLength()==3 /* Imp: `transparent -red' shouldn't work */ || (RSTRING(got)->getLength()==4 && RSTRING(got)->begin_()[0]=='#' && !toHex3(RSTRING(got)->begin_()+1, hex3) && (got=(VALUE)new String(hex3, 3), true)) || (RSTRING(got)->getLength()==7 && RSTRING(got)->begin_()[0]=='#' && !toHex6(RSTRING(got)->begin_()+1, hex3) && (got=(VALUE)new String(hex3, 3), true)) || (RSTRING(got)->getLength()==6 && !toHex6(RSTRING(got)->begin_(), hex3) && (got=(VALUE)new String(hex3, 3), true)) )) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " must be an RGB color triplet" << (Error*)0; break; case S_SENUM: if (getType(got)!=T_SNAME) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " must be an enum value (name)" << (Error*)0; got=RDICT(default_)->get(RSNAME(got)->begin_(),RSNAME(got)->getLength()); if (got==Qundef) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " must be a valid enum value" << (Error*)0; break; case S_FUNC: got=((VALUE(*)(VALUE))default_)(got); if (got==Qundef) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " has invalid value" << (Error*)0; break; case S_UINTEGER: if ((got&1)==0 || gotgetBp()<=0) ) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " must be positive" << (Error*)0; break; default: if (getType(got)!=ty) Error::sev(Error::EERROR) << "scanf_dict: key /" << key << " must have type " << getTypeStr(ty) << (Error*)0; } *dst=got; } va_end(ap); if (show_warnings) { // VALUE *keyy, *val; char const*const* keyy; slen_t keylen; VALUE *val; bool touched = false; /* pacify gcc-4.2.1 by giving initial value */ dict->getFirst(keyy, keylen, val, touched); // fprintf(stderr, "> %p\n", keyy); PTS_va_start(ap, show_warnings); while (keyy!=(char const*const*)NULLP) { // fprintf(stderr, "untouch len=%u\n", keylen); // fprintf(stderr, "untouching key=(%s)\n", *keyy); if (!touched) Error::sev(Error::WARNING) << "scanf_dict: ignoring unknown key /" << SimBuffer::Static(*keyy,keylen) << (Error*)0; else dict->untouch(*keyy, keylen); /* undo get1 */ dict->getNext(keyy, keylen, val, touched); } va_end(ap); } } void MiniPS::setDumpPS(MiniPS::VALUE v, bool g) { /* Sat Sep 7 13:18:35 CEST 2002 */ if (getType(v)==T_REAL) RREAL(v)->setDumpPS(g); } bool MiniPS::isZero(MiniPS::VALUE v) { /* Sat Sep 7 15:12:54 CEST 2002 */ switch (getType(v)) { case T_REAL: return RREAL(v)->getBp()==0; case T_INTEGER: return int2ii(v)==0; } Error::sev(Error::EERROR) << "isZero: number expected" << (Error*)0; return false; /* NOTREACHED */ } bool MiniPS::isEq(MiniPS::VALUE v, double d) { double dif=0; switch (getType(v)) { case T_REAL: dif=RREAL(v)->getBp()-d; break; case T_INTEGER: dif=int2ii(v)-d; break; default: Error::sev(Error::EERROR) << "isEq: number expected" << (Error*)0; } if (dif<0.0) dif=-dif; /* fprintf(stderr,"dif=%g g=%d\n", dif, (dif<0.000001)); */ return (dif<0.000001); /* Imp: ... */ } void MiniPS::dumpScale(GenBuffer::Writable &out, VALUE v) { double d=0; ii_t ii; switch (getType(v)) { case T_REAL: d = RREAL(v)->getBp(); break; case T_INTEGER: d = int2ii(v); break; default: Error::sev(Error::EERROR) << "dumpScale: number expected" << (Error*)0; } if (d == -72.0) d = 72.0; ii = (ii_t)d / 72 * 72; if (d >= 0 && ii == d) { /* accurate nonnegative integer divisible by 72 */ out << (ii / 72); } else if (d < 0 && d == (ii_t)d && 72 % -(ii_t)d == 0) { out << (72 / -(ii_t)d); } else { d = d < 0 ? 72.0 / -d : d / 72.0; char buf[64]; /* Dat: enough */ sprintf(buf, "%"PTS_CFG_PRINTFGLEN"g", d); out << buf; } } void MiniPS::dumpAdd3(GenBuffer::Writable &out, MiniPS::VALUE m, MiniPS::VALUE a, MiniPS::VALUE b, MiniPS::VALUE c, MiniPS::VALUE sub, unsigned rounding) { long ll; /* Sat Sep 7 15:30:28 CEST 2002 */ bool no_real_real=true; double d=0, dd; long l=0; if ((getType(m)==T_REAL && (isEq(m, 72) || isEq(m, -72))) || /* Imp: not so exact comparison */ (getType(m)==T_INTEGER && isEq(m, -72))) m = Qinteger(72); MiniPS::VALUE t[5], *tt; t[0]=a; t[1]=m; t[2]=b; t[3]=c; t[4]=sub; for (tt=t;ttgetBp(); doadd: if (no_real_real) { d=l; no_real_real=false; } if (tt==t+1) { /* multiply by m/72 or 72/-m */ if (dd==0.0 || d==0.0) { no_real_real=true; l=0; d=0.0; } else d *= dd >= 0 ? dd / 72 : 72 / -dd; } else if (tt==t+4) d-=dd; else d+=dd; break; case T_INTEGER: ll=int2ii(*tt); if (tt==t+1) { /* multiply by m/72 or 72/-m */ if (ll >= 0 && ll % 72 == 0) l *= ll / 72; else if (ll < 0 && 72 % -ll == 0) l *= 72 / -ll; else { dd=ll; goto doadd; } } else if (tt==t+4) l-=ll; else l+=ll; break; default: Error::sev(Error::EERROR) << "dumpAdd3: numbers expected" << (Error*)0; } if (no_real_real) { out << l; return; } if (rounding!=0) { ll=(long)d; if ((double)ll=d); /* Imp: verify possible rounding errors */ out << (rounding>=2 && ll<0 ? 0 : ll); } else { char buf[64]; /* Dat: enough */ sprintf(buf, "%"PTS_CFG_PRINTFGLEN"g", d); out << buf; } } /* __END__ */ sam2p-0.49.2/rule.cpp0000644000175100017510000014012312212351433012500 0ustar ptspts/* * rule.cpp -- generic Rule handling * by pts@fazekas.hu at Fri Mar 15 21:13:47 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "rule.hpp" #include "error.hpp" #include /* strlen() */ bool Rule::Cache::isPDF() const { return 80<=FileFormat && FileFormat<100; } bool Rule::Cache::isPDFB() const { return 90<=FileFormat && FileFormat<100; } bool Rule::Cache::isIndexed() const { return SampleFormat==Image::SF_Indexed1 || SampleFormat==Image::SF_Indexed2 || SampleFormat==Image::SF_Indexed4 || SampleFormat==Image::SF_Indexed8; } bool Rule::Cache::isTransparentM() const { return SampleFormat==Image::SF_Mask || SampleFormat==Image::SF_Transparent2 || SampleFormat==Image::SF_Transparent4 || SampleFormat==Image::SF_Transparent8; } bool Rule::Cache::isOneBit() const { return SampleFormat==Image::SF_Mask || SampleFormat==Image::SF_Indexed1 || SampleFormat==Image::SF_Gray1; } #if 0 bool Rule::Cache::is8() const { return SampleFormat==Image::SF_Indexed1 || SampleFormat==Image::SF_Indexed2 || SampleFormat==Image::SF_Indexed4 || SampleFormat==Image::SF_Indexed8; } #endif bool Rule::Cache::isGray() const { return SampleFormat==Image::SF_Gray1 || SampleFormat==Image::SF_Gray2 || SampleFormat==Image::SF_Gray4 || SampleFormat==Image::SF_Gray8; } bool Rule::Cache::isRGB() const { return SampleFormat==Image::SF_Rgb1 || SampleFormat==Image::SF_Rgb2 || SampleFormat==Image::SF_Rgb4 || SampleFormat==Image::SF_Rgb8; } bool Rule::Cache::isBinSB() const { return TransferEncoding==TE_Binary || TransferEncoding==TE_MSBfirst || TransferEncoding==TE_LSBfirst; } bool Rule::Cache::isPS() const { return FileFormat>=100; } bool Rule::Cache::isPSL2() const { return FileFormat>=120; } bool Rule::Cache::isPSL3() const { return FileFormat>=130; } bool Rule::Cache::hasPredictor() const { return Predictor!=PR_None; } bool Rule::Cache::isDCTE() const { /* Dat: _not_ CO_JAI */ return Compression==CO_DCT || Compression==CO_IJG; } bool Rule::Cache::isZIPOK() const { return Compression!=CO_ZIP || ( FileFormat!=FF_PSL1 && FileFormat!=FF_PSLC && FileFormat!=FF_PSL2 && FileFormat!=FF_PDF10 && FileFormat!=FF_PDFB10 ); } static MiniPS::Dict *y_FileFormat=(MiniPS::Dict*)NULLP, *y_SampleFormat, *y_TransferEncoding, *y_Compression, *y_Scale; static class ValueDeleter { public: ~ValueDeleter() { MiniPS::delete0((MiniPS::VALUE)y_FileFormat); MiniPS::delete0((MiniPS::VALUE)y_SampleFormat); MiniPS::delete0((MiniPS::VALUE)y_TransferEncoding); MiniPS::delete0((MiniPS::VALUE)y_Compression); MiniPS::delete0((MiniPS::VALUE)y_Scale); } } value_deleter; static const slen_t SampleFormat_MAXLEN=32; static void init_dicts() { register MiniPS::Dict*y; /** TODO: Make this thread-safe. */ if (y_FileFormat!=NULLP) return; y=y_FileFormat=new MiniPS::Dict(); y->put("/PSL1", MiniPS::Qinteger(Rule::Cache::FF_PSL1)); y->put("/PSLC", MiniPS::Qinteger(Rule::Cache::FF_PSLC)); y->put("/PSL2", MiniPS::Qinteger(Rule::Cache::FF_PSL2)); y->put("/PSL3", MiniPS::Qinteger(Rule::Cache::FF_PSL3)); y->put("/PDFB1.0",MiniPS::Qinteger(Rule::Cache::FF_PDFB10)); y->put("/PDFB1.2",MiniPS::Qinteger(Rule::Cache::FF_PDFB12)); y->put("/PDF1.0", MiniPS::Qinteger(Rule::Cache::FF_PDF10)); y->put("/PDF1.2", MiniPS::Qinteger(Rule::Cache::FF_PDF12)); y->put("/GIF89a", MiniPS::Qinteger(Rule::Cache::FF_GIF89a)); y->put("/GIF", MiniPS::Qinteger(Rule::Cache::FF_GIF89a)); y->put("/Empty", MiniPS::Qinteger(Rule::Cache::FF_Empty)); y->put("/Meta", MiniPS::Qinteger(Rule::Cache::FF_Meta)); y->put("/PNM", MiniPS::Qinteger(Rule::Cache::FF_PNM)); y->put("/PAM", MiniPS::Qinteger(Rule::Cache::FF_PAM)); y->put("/PIP", MiniPS::Qinteger(Rule::Cache::FF_PIP)); y->put("/JPEG", MiniPS::Qinteger(Rule::Cache::FF_JPEG)); y->put("/JPG", MiniPS::Qinteger(Rule::Cache::FF_JPEG)); y->put("/TIFF", MiniPS::Qinteger(Rule::Cache::FF_TIFF)); y->put("/TIF", MiniPS::Qinteger(Rule::Cache::FF_TIFF)); y->put("/PNG", MiniPS::Qinteger(Rule::Cache::FF_PNG)); y->put("/XPM", MiniPS::Qinteger(Rule::Cache::FF_XPM)); y->put("/BMP", MiniPS::Qinteger(Rule::Cache::FF_BMP)); y->put("/XWD", MiniPS::Qinteger(Rule::Cache::FF_XWD)); y->put("/X11", MiniPS::Qinteger(Rule::Cache::FF_X11)); /* vvv strlen must be shorter then SampleFormat_MAXLEN */ y=y_SampleFormat=new MiniPS::Dict(); y->put("/Opaque", MiniPS::Qinteger(Image::SF_Opaque)); y->put("/Transparent", MiniPS::Qinteger(Image::SF_Transparent)); y->put("/Transparent2", MiniPS::Qinteger(Image::SF_Transparent2)); y->put("/Transparent4", MiniPS::Qinteger(Image::SF_Transparent4)); y->put("/Transparent8", MiniPS::Qinteger(Image::SF_Transparent8)); y->put("/Gray1", MiniPS::Qinteger(Image::SF_Gray1)); y->put("/Gray2", MiniPS::Qinteger(Image::SF_Gray2)); y->put("/Gray4", MiniPS::Qinteger(Image::SF_Gray4)); y->put("/Gray8", MiniPS::Qinteger(Image::SF_Gray8)); y->put("/Indexed1", MiniPS::Qinteger(Image::SF_Indexed1)); y->put("/Indexed2", MiniPS::Qinteger(Image::SF_Indexed2)); y->put("/Indexed4", MiniPS::Qinteger(Image::SF_Indexed4)); y->put("/Indexed8", MiniPS::Qinteger(Image::SF_Indexed8)); y->put("/Mask", MiniPS::Qinteger(Image::SF_Mask)); y->put("/Rgb1", MiniPS::Qinteger(Image::SF_Rgb1)); /* recommended */ y->put("/Rgb2", MiniPS::Qinteger(Image::SF_Rgb2)); y->put("/Rgb4", MiniPS::Qinteger(Image::SF_Rgb4)); y->put("/Rgb8", MiniPS::Qinteger(Image::SF_Rgb8)); y->put("/RGB1", MiniPS::Qinteger(Image::SF_Rgb1)); /* obsolete */ y->put("/RGB2", MiniPS::Qinteger(Image::SF_Rgb2)); y->put("/RGB4", MiniPS::Qinteger(Image::SF_Rgb4)); y->put("/RGB8", MiniPS::Qinteger(Image::SF_Rgb8)); y->put("/Asis", MiniPS::Qinteger(Image::SF_Asis)); y->put("/Bbox", MiniPS::Qinteger(Image::SF_Bbox)); y=y_TransferEncoding=new MiniPS::Dict(); y->put("/Binary", MiniPS::Qinteger(Rule::Cache::TE_Binary)); y->put("/ASCII", MiniPS::Qinteger(Rule::Cache::TE_ASCII)); y->put("/Hex", MiniPS::Qinteger(Rule::Cache::TE_Hex)); /* recommended */ y->put("/AHx", MiniPS::Qinteger(Rule::Cache::TE_Hex)); y->put("/ASCIIHex", MiniPS::Qinteger(Rule::Cache::TE_Hex)); y->put("/A85", MiniPS::Qinteger(Rule::Cache::TE_A85)); /* recommended */ y->put("/ASCII85", MiniPS::Qinteger(Rule::Cache::TE_A85)); y->put("/MSBfirst", MiniPS::Qinteger(Rule::Cache::TE_MSBfirst)); y->put("/LSBfirst", MiniPS::Qinteger(Rule::Cache::TE_LSBfirst)); y=y_Compression=new MiniPS::Dict(); y->put("/ ", MiniPS::Qinteger(Rule::Cache::CO_None)); /* default */ y->put("/None", MiniPS::Qinteger(Rule::Cache::CO_None)); /* recommended */ y->put("/LZW", MiniPS::Qinteger(Rule::Cache::CO_LZW)); /* recommended */ y->put("/ZIP", MiniPS::Qinteger(Rule::Cache::CO_ZIP)); /* recommended */ y->put("/Flate", MiniPS::Qinteger(Rule::Cache::CO_ZIP)); y->put("/Fl", MiniPS::Qinteger(Rule::Cache::CO_ZIP)); y->put("/RLE", MiniPS::Qinteger(Rule::Cache::CO_RLE)); /* recommended */ y->put("/RunLength", MiniPS::Qinteger(Rule::Cache::CO_RLE)); y->put("/RunLengthEncoded", MiniPS::Qinteger(Rule::Cache::CO_RLE)); y->put("/RL", MiniPS::Qinteger(Rule::Cache::CO_RLE)); y->put("/PackBits", MiniPS::Qinteger(Rule::Cache::CO_RLE)); y->put("/Fax", MiniPS::Qinteger(Rule::Cache::CO_Fax)); /* recommended */ y->put("/CCITTFax", MiniPS::Qinteger(Rule::Cache::CO_Fax)); y->put("/CCF", MiniPS::Qinteger(Rule::Cache::CO_Fax)); y->put("/DCT", MiniPS::Qinteger(Rule::Cache::CO_DCT)); /* recommended */ y->put("/JPEG",MiniPS::Qinteger(Rule::Cache::CO_IJG)); /* changed at Sun Jun 23 17:06:34 CEST 2002 */ y->put("/JPG", MiniPS::Qinteger(Rule::Cache::CO_IJG)); /* changed at Sun Jun 23 17:06:34 CEST 2002 */ y->put("/JFIF",MiniPS::Qinteger(Rule::Cache::CO_IJG)); /* changed at Sun Jun 23 17:06:34 CEST 2002 */ y->put("/IJG", MiniPS::Qinteger(Rule::Cache::CO_IJG)); /* recommended */ y->put("/JAI", MiniPS::Qinteger(Rule::Cache::CO_JAI)); /* recommended */ y=y_Scale=new MiniPS::Dict(); y->put("/ ", MiniPS::Qinteger(Rule::CacheHints::SC_None)); /* default */ y->put("/None", MiniPS::Qinteger(Rule::CacheHints::SC_None)); y->put("/OK", MiniPS::Qinteger(Rule::CacheHints::SC_OK)); y->put("/RotateOK",MiniPS::Qinteger(Rule::CacheHints::SC_RotateOK)); } Image::sf_t Rule::Cache::parseSampleFormat(char const*s, slen_t slen) { /* Tue Jul 2 13:48:12 CEST 2002 */ #if 0 /* BUGFIX for g++-3.4 (needs symbols __cxa_guard_acquire, __cxa_guard_release) */ static char rule_dummy=(init_dicts(),0); /* call once per process */ (void)rule_dummy; #else if (y_FileFormat==NULLP) init_dicts(); #endif while (slen!=0 && s[0]=='/') { s++; slen--; } if (slen<=0 || slen>=SampleFormat_MAXLEN) return Image::SF_max; char buf[SampleFormat_MAXLEN]; GenBuffer::tolower_memcpy(buf, s, slen); if (buf[0]>='a' && buf[0]<='z') buf[0]+='A'-'a'; /* capitalize 1st letter */ MiniPS::VALUE v=y_SampleFormat->get(buf, slen); return (Image::sf_t) (v==MiniPS::Qundef ? Image::SF_max : MiniPS::int2ii(v)); } char const* Rule::Cache::dumpFileFormat(ff_t FileFormat, co_t Compression) { switch (FileFormat) { case FF_eps: return Compression==CO_ZIP ? "PSL3" : "PSL2"; case FF_pdf: return Compression==CO_ZIP ? "PDF1.2" : "PDF1.0"; case FF_pdfb: return Compression==CO_ZIP ? "PDFB1.2" : "PDFB1.0"; case FF_PSL1: return "PSL1"; case FF_PSLC: return "PSLC"; case FF_PSL2: return "PSL2"; case FF_PSL3: return "PSL3"; case FF_PDFB10:return "PDFB1.0"; case FF_PDFB12:return "PDFB1.2"; case FF_PDF10: return "PDF1.0"; case FF_PDF12: return "PDF1.2"; case FF_GIF89a:return "GIF89a"; case FF_PNM: return "PNM"; case FF_PAM: return "PAM"; case FF_PIP: return "PIP"; case FF_Empty: return "Empty"; case FF_Meta: return "Meta"; case FF_JPEG: return "JPEG"; case FF_TIFF: return "TIFF"; case FF_PNG: return "PNG"; case FF_XPM: return "XPM"; case FF_BMP: return "BMP"; case FF_XWD: return "XWD"; case FF_X11: return "X11"; } return (char const*)NULLP; } char const* Rule::Cache::dumpTransferEncoding(te_t TransferEncoding) { switch (TransferEncoding) { case TE_Binary: return "Binary"; case TE_ASCII: return "ASCII"; case TE_Hex: return "Hex"; case TE_A85: return "A85"; case TE_MSBfirst:return "MSBfirst"; case TE_LSBfirst:return "LSBfirst"; } return (char const*)NULLP; } char const* Rule::Cache::dumpSampleFormat(Image::sf_t SampleFormat) { switch (SampleFormat) { case Image::SF_Opaque: return "Opaque"; case Image::SF_Transparent: return "Transparent"; case Image::SF_Gray1: return "Gray1"; case Image::SF_Indexed1: return "Indexed1"; case Image::SF_Mask: return "Mask"; case Image::SF_Transparent2: return "Transparent2"; case Image::SF_Gray2: return "Gray2"; case Image::SF_Indexed2: return "Indexed2"; case Image::SF_Transparent4: return "Transparent4"; case Image::SF_Rgb1: return "Rgb1"; case Image::SF_Gray4: return "Gray4"; case Image::SF_Indexed4: return "Indexed4"; case Image::SF_Transparent8: return "Transparent8"; case Image::SF_Rgb2: return "Rgb2"; case Image::SF_Gray8: return "Gray8"; case Image::SF_Indexed8: return "Indexed8"; case Image::SF_Rgb4: return "Rgb4"; case Image::SF_Rgb8: return "Rgb8"; case Image::SF_Asis: return "Asis"; case Image::SF_Bbox: return "Bbox"; } return (char const*)NULLP; } char const* Rule::Cache::dumpCompression(co_t Compression) { switch (Compression) { case CO_None:return "None"; case CO_LZW: return "LZW"; case CO_ZIP: return "ZIP"; case CO_RLE: return "RLE"; case CO_Fax: return "Fax"; case CO_DCT: return "DCT"; case CO_IJG: return "IJG"; case CO_JAI: return "JAI"; } return (char const*)NULLP; } char const* Rule::CacheHints::dumpScale(sc_t Scale) { switch (Scale) { case SC_None: return "None"; case SC_OK: return "OK"; case SC_RotateOK:return "RotateOK"; } return (char const*)NULLP; } /* Checks and recovers Predictor. Called by scanf_dict. * @return Qundef if param invalid * Qinteger(1) if param==Qundef * valid Qinteger otherwise */ static MiniPS::VALUE better_predictor(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(1) /* PR_None */ : v==MiniPS::Qinteger(1) || v==MiniPS::Qinteger(2) || v==MiniPS::Qinteger(45) || v==MiniPS::Qinteger(55) || ((v&1)!=0 && v>=MiniPS::Qinteger(10) && v<=MiniPS::Qinteger(15)) ? v : MiniPS::Qundef; } static MiniPS::VALUE better_xColors(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(0) : ((v&1)!=0 && v>=MiniPS::Qinteger(1) && v<=MiniPS::Qinteger(4)) ? v : MiniPS::Qundef; } static MiniPS::VALUE better_predictorBPC(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(0) : v==MiniPS::Qinteger(1) || v==MiniPS::Qinteger(2) || v==MiniPS::Qinteger(4) || v==MiniPS::Qinteger(8) ? v : MiniPS::Qundef; } static MiniPS::VALUE better_effort(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(-1) : ((v&1)!=0 && v>=MiniPS::Qinteger(-1) && v<=MiniPS::Qinteger(9)) ? v : MiniPS::Qundef; } static MiniPS::VALUE better_k(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(0) : ((v&1)!=0 && v>=MiniPS::Qinteger(-2)) ? v /* -2 means: positive value marking the image height */ : MiniPS::Qundef; } static MiniPS::VALUE better_quality(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(75) : ((v&1)!=0 && v>=MiniPS::Qinteger(0) && v<=MiniPS::Qinteger(100)) ? v : MiniPS::Qundef; } static MiniPS::VALUE better_colorTransform(MiniPS::VALUE v) { return v==MiniPS::Qundef ? MiniPS::Qinteger(3) : ((v&1)!=0 && v>=MiniPS::Qinteger(0) && v<=MiniPS::Qinteger(3)) ? v : MiniPS::Qundef; } void Rule::OutputRule::fromDict(MiniPS::VALUE dict_) { #if 0 /* BUGFIX for g++-3.4 (needs symbols __cxa_guard_acquire, __cxa_guard_release) */ static char rule_dummy=(init_dicts(),0); /* call once per process */ (void)rule_dummy; #else if (y_FileFormat==NULLP) init_dicts(); #endif MiniPS::VALUE dummy; (void)dummy; MiniPS::VALUE FileFormat, SampleFormat, WarningOK, TransferEncoding, Compression, Predictor, Transparent; MiniPS::VALUE PredictorColumns, PredictorColors, PredictorBPC, Effort, K, RecordSize, Quality, ColorTransform, TransferCPL, EncoderRows, EncoderColumns, EncoderBPL, EncoderColors, DCT, Scale; MiniPS::scanf_dict(dict_, /*show_warnings:*/true, "FileFormat", MiniPS::S_SENUM, y_FileFormat, &FileFormat, "SampleFormat", MiniPS::S_SENUM, y_SampleFormat, &SampleFormat, "WarningOK", MiniPS::T_BOOLEAN, MiniPS::Qtrue, &WarningOK, "TransferEncoding",MiniPS::S_SENUM, y_TransferEncoding, &TransferEncoding, "Compression", MiniPS::S_SENUM, y_Compression, &Compression, "Predictor", MiniPS::S_FUNC, better_predictor, &Predictor, "Transparent", MiniPS::S_RGBSTR, MiniPS::Qnull, &Transparent, /* force an RGB color transparent */ "Hints", MiniPS::T_DICT, MiniPS::Qnull, &dictHints, NULLP ); dict=(MiniPS::Dict*)dict_; cache.FileFormat=(Rule::Cache::ff_t)MiniPS::int2ii(FileFormat); cache.SampleFormat=(Image::sf_t)MiniPS::int2ii(SampleFormat); cache.WarningOK=(Rule::Cache::ff_t)WarningOK==MiniPS::Qtrue; cache.TransferEncoding=(Rule::Cache::te_t)MiniPS::int2ii(TransferEncoding); cache.Compression=(Rule::Cache::co_t)MiniPS::int2ii(Compression); cache.Predictor=(Rule::Cache::pr_t)MiniPS::int2ii(Predictor); cache.Transparent=0x1000000UL; /* No extra transparency */ if (Transparent!=MiniPS::Qnull) { unsigned char const*p=(unsigned char const*)(MiniPS::RSTRING(Transparent)->begin_()); cache.Transparent=(p[0]<<16)+(p[1]<<8)+p[2]; } //MiniPS::dump(Predictor); // fprintf(stderr,"cpred=%u\n", cache.Predictor); if ((MiniPS::VALUE)dictHints==MiniPS::Qnull) dict->put("/Hints", (MiniPS::VALUE)(dictHints=new MiniPS::Dict())); MiniPS::scanf_dict((MiniPS::VALUE)dictHints, /*show_warnings:*/true, "EncoderBPL", MiniPS::S_PINTEGER,MiniPS::Qinteger(0), &EncoderBPL, "EncoderColumns", MiniPS::S_PINTEGER,MiniPS::Qinteger(0), &EncoderColumns, "EncoderRows", MiniPS::S_PINTEGER,MiniPS::Qinteger(0), &EncoderRows, "EncoderColors", MiniPS::S_FUNC, better_xColors, &EncoderColors, "PredictorColumns",MiniPS::S_PINTEGER,MiniPS::Qinteger(0), &PredictorColumns, "PredictorColors", MiniPS::S_FUNC, better_xColors, &PredictorColors, "PredictorBPC", MiniPS::S_FUNC, better_predictorBPC, &PredictorBPC, "Effort", MiniPS::S_FUNC, better_effort, &Effort, "RecordSize", MiniPS::S_UINTEGER,MiniPS::Qinteger(0), &RecordSize, "K", MiniPS::S_FUNC, better_k, &K, "Quality", MiniPS::S_FUNC, better_quality, &Quality, "ColorTransform", MiniPS::S_FUNC, better_colorTransform, &ColorTransform, "TransferCPL", MiniPS::S_PINTEGER,MiniPS::Qinteger(78), &TransferCPL, "DCT", MiniPS::T_DICT, MiniPS::Qnull, &DCT, "Scale", MiniPS::S_SENUM, y_Scale, &Scale, "ImageDPI", MiniPS::S_NUMBER, MiniPS::Qinteger(72), &cacheHints.ImageDPI, "TopMargin", MiniPS::S_NUMBER, MiniPS::Qinteger(0), &cacheHints.TopMargin, "BottomMargin", MiniPS::S_NUMBER, MiniPS::Qinteger(0), &cacheHints.BottomMargin, "LeftMargin", MiniPS::S_NUMBER, MiniPS::Qinteger(0), &cacheHints.LeftMargin, "RightMargin", MiniPS::S_NUMBER, MiniPS::Qinteger(0), &cacheHints.RightMargin, "LowerMargin", MiniPS::S_NUMBER, MiniPS::Qinteger(0), &cacheHints.LowerMargin, "Comment", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Comment, "Title", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Title, "Subject", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Subject, "Author", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Author, "Creator", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Creator, "Producer", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Producer, "Created", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Created, "Produced", MiniPS::T_STRING, MiniPS::Qnull, &cacheHints.Produced, #if 0 /* vvv parameters for /DCTEncode. Currently ignored. Obsoleted by /DCT */ "Colors", MiniPS::S_ANY, MiniPS::Qnull, &dummy, "HSamples", MiniPS::S_ANY, MiniPS::Qnull, &dummy, "VSamples", MiniPS::S_ANY, MiniPS::Qnull, &dummy, "QuantTables", MiniPS::S_ANY, MiniPS::Qnull, &dummy, "QFactor", MiniPS::S_ANY, MiniPS::Qnull, &dummy, "HuffTables", MiniPS::S_ANY, MiniPS::Qnull, &dummy, #endif NULLP ); if (DCT==MiniPS::Qnull) dict->put("/DCT", DCT=(MiniPS::VALUE)new MiniPS::Dict()); // cacheHints.DCT=(DCT==MiniPS::Qnull)? new MiniPS::Dict() : MiniPS::RDICT(DCT); if (cache.isPS()) { MiniPS::setDumpPS(cacheHints.TopMargin, true); MiniPS::setDumpPS(cacheHints.BottomMargin, true); MiniPS::setDumpPS(cacheHints.LeftMargin, true); MiniPS::setDumpPS(cacheHints.RightMargin, true); MiniPS::setDumpPS(cacheHints.LowerMargin, true); } cacheHints.DCT=MiniPS::RDICT(DCT); cacheHints.EncoderColumns=MiniPS::int2ii(EncoderColumns); cacheHints.EncoderBPL=MiniPS::int2ii(EncoderBPL); cacheHints.EncoderColors=MiniPS::int2ii(EncoderColors); cacheHints.EncoderRows=MiniPS::int2ii(EncoderRows); cacheHints.PredictorColumns=MiniPS::int2ii(PredictorColumns); cacheHints.PredictorColors=MiniPS::int2ii(PredictorColors); cacheHints.PredictorBPC=MiniPS::int2ii(PredictorBPC); cacheHints.Effort=MiniPS::int2ii(Effort); cacheHints.RecordSize=MiniPS::int2ii(RecordSize); cacheHints.K=MiniPS::int2ii(K); cacheHints.Quality=MiniPS::int2ii(Quality); cacheHints.ColorTransform=MiniPS::int2ii(ColorTransform); cacheHints.TransferCPL=MiniPS::int2ii(TransferCPL); cacheHints.Scale=(Rule::CacheHints::sc_t)MiniPS::int2ii(Scale); /* fprintf(stderr, "scaled=%g\n", (char*)MiniPS::scale(ImageDPI,1)); */ } void Rule::OutputRule::doSampleFormat(Image::SampledInfo *info, bool separatep) { /* Dat: called from appliers.cpp:out_*_work(); the sample format is final */ bool separatep2= separatep && ( cache.SampleFormat==Image::SF_Transparent2 || cache.SampleFormat==Image::SF_Transparent4 || cache.SampleFormat==Image::SF_Transparent8); /* vvv simplifier added at Sat Jun 15 13:59:40 CEST 2002 */ if (separatep2) cache.SampleFormat=Image::SF_Transparent8; if (!info->setSampleFormat(cache.SampleFormat, cache.WarningOK, /*TryOnly*/false, cache.Transparent)) Error::sev(Error::EERROR) << "doSampleFormat: cannot set desired SampleFormat" << (Error*)0; Image::Sampled *img=info->getImg(); slen_t n=1; if (separatep2) { info->separate(); img=info->getImgs()[0];/*NULLP OK*/; n=info->getNncols(); } if (img!=NULLP) { if (0==cacheHints.EncoderBPL) cacheHints.EncoderBPL=(slen_t)img->getWd()*img->getCpp()*img->getBpc(); if (0==cacheHints.EncoderColumns) cacheHints.EncoderColumns=img->getWd(); if (0==cacheHints.EncoderColors) cacheHints.EncoderColors=img->getCpp(); if (0==cacheHints.EncoderRows) cacheHints.EncoderRows=img->getHt()*n; if (0==cacheHints.PredictorColumns) cacheHints.PredictorColumns=img->getWd(); if (0==cacheHints.PredictorColors) cacheHints.PredictorColors=img->getCpp(); if (0==cacheHints.PredictorBPC) cacheHints.PredictorBPC=img->getBpc(); if (-2==cacheHints.K) cacheHints.K=img->getHt()*n; } } static char const*getDecode(Rule::Cache::co_t Compression) { return (Compression==Rule::Cache::CO_LZW ? "/LZWDecode" :Compression==Rule::Cache::CO_Fax ? "/CCITTFaxDecode" :Compression==Rule::Cache::CO_ZIP ? "/FlateDecode" :Compression==Rule::Cache::CO_RLE ? "/RunLengthDecode" :Compression==Rule::Cache::CO_DCT ? "/DCTDecode" :Compression==Rule::Cache::CO_IJG ? "/DCTDecode" :Compression==Rule::Cache::CO_JAI ? "/DCTDecode" :""); } /** For PDF BI inline images */ static char const*getBIDecode(Rule::Cache::co_t Compression) { return (Compression==Rule::Cache::CO_LZW ? "/LZW" :Compression==Rule::Cache::CO_Fax ? "/CCF" :Compression==Rule::Cache::CO_ZIP ? "/Fl" :Compression==Rule::Cache::CO_RLE ? "/RL" :Compression==Rule::Cache::CO_DCT ? "/DCT" :Compression==Rule::Cache::CO_IJG ? "/DCT" :Compression==Rule::Cache::CO_JAI ? "/DCT" :""); } void Rule::OutputRule::appendDecoderSpec(GenBuffer::Writable &out) const { assert(cacheHints.PredictorBPC!=0 && "doSampleFormat already called"); bool hps=hasPredictorSpec(); if (cache.isPDF()) { /* Dat: also implies appendTransferSpec() -- this is true only for PDF */ if (!cache.isPDFB()) { if (cache.Compression==cache.CO_None) { if (cache.TransferEncoding==cache.TE_Hex) out << "/Filter/ASCIIHexDecode"; else if (cache.TransferEncoding==cache.TE_A85) out << "/Filter/ASCII85Decode"; } else if (cache.TransferEncoding!=cache.TE_Hex && cache.TransferEncoding!=cache.TE_A85) { out << "/Filter" << getDecode(cache.Compression); if (hps) { out << "/DecodeParms"; appendPredictorSpec(out); } } else { /* both TransferEncoding and Compression */ if (cache.TransferEncoding==cache.TE_Hex) out << "/Filter[/ASCIIHexDecode"; else if (cache.TransferEncoding==cache.TE_A85) out << "/Filter[/ASCII85Decode"; else assert(0); out << getDecode(cache.Compression); if (hps) { out << "]/DecodeParms[null"; appendPredictorSpec(out); } /* ^^^ BUGFIX at Tue Jun 4 18:50:13 CEST 2002 */ out << ']'; } } else { if (cache.Compression==cache.CO_None) { if (cache.TransferEncoding==cache.TE_Hex) out << "/F/AHx"; else if (cache.TransferEncoding==cache.TE_A85) out << "/F/A85"; } else if (cache.TransferEncoding!=cache.TE_Hex && cache.TransferEncoding!=cache.TE_A85) { out << "/F" << getBIDecode(cache.Compression); if (hps) { out << "/DP"; appendPredictorSpec(out); } } else { /* both TransferEncoding and Compression */ if (cache.TransferEncoding==cache.TE_Hex) out << "/F[/AHx"; else if (cache.TransferEncoding==cache.TE_A85) out << "/F[/A85"; else assert(0); out << getBIDecode(cache.Compression); if (hps) { out << "]/DP[null"; appendPredictorSpec(out); } out << ']'; } } /* IFELSE PDFB */ } else { /* NOT PDF */ if (cache.Compression!=cache.CO_None) { appendPredictorSpec(out); out << getDecode(cache.Compression) << " filter"; } } /* IFELSE PDF */ } bool Rule::OutputRule::hasPredictorSpec() const { return cache.Compression==cache.CO_Fax || ((cache.Compression==cache.CO_ZIP || cache.Compression==cache.CO_LZW) && cache.Predictor!=cache.PR_None); } void Rule::OutputRule::appendPredictorSpec(GenBuffer::Writable &out) const { assert(cacheHints.PredictorBPC!=0 && "doSampleFormat already called"); if (cache.Compression==cache.CO_Fax) out << "< EncoderBPL BUGFIX at Wed Jul 3 20:05:12 CEST 2002 */ << ">>"; else if ((cache.Compression==cache.CO_ZIP || cache.Compression==cache.CO_LZW) && cache.Predictor!=cache.PR_None) out<< "<>": "/Predictor 10>>"); } void Rule::OutputRule::appendTransferSpec(GenBuffer::Writable &out) const { if (cache.TransferEncoding==cache.TE_Hex) out << "/ASCIIHexDecode filter"; else if (cache.TransferEncoding==cache.TE_A85) out << "/ASCII85Decode filter"; } /* --- */ static Rule::Applier *first=(Rule::Applier*)NULLP; void Rule::register0(Rule::Applier *anew) { param_assert(anew!=NULLP); anew->next=first; first=anew; } unsigned Rule::printAppliers(GenBuffer::Writable &out) { unsigned num=0; Applier *p=first; while (p!=(Applier*)NULLP) { if (p->check_rule!=0/*NULLP*/ && p->work!=0/*NULLP*/) { num++; out << ' ' << p->format; } p=p->next; } return num; } Rule::OutputRule* Rule::buildProfile(MiniPS::VALUE Profile, bool quiet) { param_assert(MiniPS::getType(Profile)==MiniPS::T_ARRAY); MiniPS::Array *pary=MiniPS::RARRAY(Profile); OutputRule *ret=new OutputRule[pary->getLength()+1], *or_=ret; /* ^^^ just enough place; there may be BAD items which won't be stored */ MiniPS::VALUE *val; unsigned c; #if !USE_BUILTIN_LZW bool lzw_warning=true; #endif if (quiet) Error::pushPolicy((Error::level_t)0, /*printed_:*/Error::getTopPrinted()+0>Error::WARNING+0 ? Error::getTopPrinted() : Error::WARNING, Error::WARNING_DEFER, (GenBuffer::Writable*)NULLP); /* Dat: WARNING_DEFER untested */ for (c=0, pary->getFirst(val); val!=NULLP; pary->getNext(val), c++) { /* val: each OutputRule of the Profile */ or_->fromDict(*val); or_->c=c; Applier *p=first; // printf("building: %s...\n", p->format); #if !USE_BUILTIN_LZW if (or_->cache.Compression==or_->cache.CO_LZW && lzw_warning) { lzw_warning=false; Error::sev(Error::WARNING) << "buildProfile: please `configure --enable-lzw' for /Compression/LZW support in OutputRule #" << c << (Error*)0; } #endif while (p!=NULLP) { if (p->check_rule!=0/*NULLP*/) switch (p->check_rule(or_)) { case Applier::BAD: Error::sev(Error::WARNING_DEFER) << "buildProfile: ^^^ thus ignoring impossible OutputRule #" << c << (Error*)0; goto end_appliers; case Applier::MAYBE: case Applier::OK: if (p->work!=0/*NULLP*/) { or_++; goto end_appliers; } Error::sev(Error::WARNING_DEFER) << "buildProfile: ^^^ ignoring unimplemented OutputRule #" << c << (Error*)0; // case p->DONT_KNOW: ; } p=p->next; /* continue with other Appliers; hope other than DONT_KNOW */ } Error::sev(Error::WARNING_DEFER) << "buildProfile: ignoring, no handlers for OutputRule #" << c << (Error*)0; end_appliers: if (quiet) delete Error::getRecorded(); } if (quiet) { delete Error::getRecorded(); Error::popPolicy(); } if (or_==ret) Error::sev(Error::WARNING) << "buildProfile: all OutputRules in the .job file are useless" << (Error*)0; or_->dict=or_->dictHints=(MiniPS::Dict*)NULLP; /* end-of-list */ return ret; } void Rule::applyProfile(GenBuffer::Writable& out, OutputRule*rule_list, Image::SampledInfo *sf) { OutputRule *or_; // unsigned tryc=0; /* Wed Jul 3 19:30:33 CEST 2002 */ Error::pushPolicy((Error::level_t)0, /*printed_:*/Error::getTopPrinted()+0>Error::NOTICE+0 ? Error::getTopPrinted() : Error::NOTICE, Error::NOTICE_DEFER, (GenBuffer::Writable*)NULLP); Image::Sampled::rgb_t Transparent=0x1000000UL; if (rule_list->dict!=NULLP) { Transparent=rule_list->cache.Transparent; for (or_=rule_list+1; or_->dict!=NULLP; or_++) { if (Transparent!=rule_list->cache.Transparent) { /* Imp: make different copies, based on different or_->cache.Transparent -- or not? */ Error::sev(Error::EERROR) << "applyProfile: ambiguous /Transparent" << (Error*)0; } } } /* Dat: -transparent ... makes the specified color transparent, but it cannot * be used to remove transparenct */ // printf("Transparent=0x%lx\n",Transparent); for (or_=rule_list; or_->dict!=NULLP; or_++) { /* ^^^ Try each OutputRule (or_) in reverse order of registration */ Error::sev(Error::NOTICE_DEFER) << "applyProfile: trying OutputRule #" << or_->c << (Error*)0; if (sf->setSampleFormat(or_->cache.SampleFormat, or_->cache.WarningOK, /*TryOnly*/true, or_->cache.Transparent)) { /* image supports the SampleFormat of OutputRule */ Applier *p=first; while (p!=NULLP) { /* ^^^ Try each output Applier for the current candidate OutputRule */ if (p->check_rule!=0/*NULLP*/ && p->work!=0/*NULLP*/) { // tryc++; switch (p->work(out, or_, sf)) { case Applier::BAD: Error::sev(Error::WARNING) << "applyProfile: ^^^ thus cannot apply OutputRule #" << or_->c << (Error*)0; goto end_appliers; case Applier::OK: // if (or_->c!=0) { delete Error::getRecorded(); Error::popPolicy(); Error::sev(Error::NOTICE) << "applyProfile: applied OutputRule #" << or_->c << (Error*)0; return; /* case Applier::MAYBE: impossible */ // case p->DONT_KNOW: ; } } p=p->next; /* continue with other Appliers; hope other than DONT_KNOW */ end_appliers: ; } } /* IF image supports SampleFormat */ } Error::sev(Error::EERROR) << "applyProfile: invalid combination, no applicable OutputRule" << (Error*)0; } void Rule::deleteProfile(OutputRule*rule_list) { /* MiniPS::* objects still remain -- the caller (reader) will delete them. */ delete [] rule_list; } /* --- */ //#include //static char xx[5000]; void Rule::writeData(GenBuffer::Writable&, GenBuffer::Writable&outstream, Image::SampledInfo *sf) { Image::Indexed **imgs=sf->getImgs(); slen_t rlenht; if (imgs!=NULLP) { unsigned i; if (sf->getNncols()!=0 && 0!=(rlenht=imgs[0]->getRlen()*imgs[0]->getHt())) { // fprintf(stderr,"rh=%u nc=%u\n", rlenht, sf->getNncols()); for (i=0;igetNncols();i++) outstream.vi_write(imgs[i]->getRowbeg(), rlenht); //for (i=0;igetNncols();i++) { // memset(xx, 1<<(i), sizeof(xx)); // outstream.vi_write(xx, rlenht); //} } } else { Image::Sampled *img=sf->getImg(); rlenht=img->getRlen()*img->getHt(); if (rlenht!=0) outstream.vi_write(img->getRowbeg(), rlenht); } outstream.vi_write(0,0); /* Dat: frees cp, bp, (ap) */ } void Rule::writePalData(GenBuffer::Writable& outpal, GenBuffer::Writable&outstream, Image::SampledInfo *sf) { Image::Sampled *img=sf->getImg(); slen_t wlen=img->getRowbeg()-img->getHeadp(); if (wlen!=0) outpal.vi_write(img->getHeadp(), wlen); writeData(outpal, outstream, sf); /* vvv replaced by the more generic writeData */ // slen_t rlenht=img->getRlen()*img->getHt(); // if (rlenht!=0) outstream.vi_write(img->getRowbeg(), rlenht); // outstream.vi_write(0,0); /* Dat: frees cp, bp, (ap) */ } /** Returns a divisor of v1*v2 near 4096 */ static slen_t near_div(slen_t v1, slen_t v2) { static const slen_t LOW=2048, MID=4096, HIGH=8192; slen_t d, p; if (v1>v2) { d=v1; v1=v2; v2=d; } if (LOW<=v2 && v2<=HIGH) return v2; /* larger */ if (LOW<=v1 && v1<=HIGH) return v1; /* smaller */ if ((p=v1*v2)<=HIGH) return p; /* smaller */ for (d=MID;d<=HIGH;d++) if (p%d==0) return d; for (d=MID-1;d>=LOW;d--) if (p%d==0) return d; return v1; /* the smaller one */ } /** Basicly out.format("%g", (double)n/255);, but we don't want to depend on * floating point arithmetic of the underlying architecture. */ static void div255(GenBuffer::Writable& out, unsigned n) { char tmp[7]; unsigned abc; param_assert(n<=255); tmp[0]='0'; tmp[1]='.'; tmp[3]='\0'; if (n%51!=0) { /* Divisors of 255: 1, 3, 5, 15, 17, 51, 85, 255. * 0/255 == "0" 51/255 == "0.2" * 102/255 == "0.4" 153/255 == "0.6" * 204/255 == "0.8" 255/255 == "1" * All other k/255 are infinite as a decimal fraction. * 1000 > 2*255, so 3 digits after '.' is enough. */ assert(n<=254); #if 0 abc=(127L+1000*n)/255; tmp[2]='0'+abc/100; tmp[3]='0'+(abc/10)%10; tmp[4]='0'+abc%10; tmp[5]='\0'; #else abc=(127L+10000*n)/255; tmp[2]='0'+abc/1000; tmp[3]='0'+(abc/100)%10; tmp[4]='0'+(abc/10)%10; tmp[5]='0'+abc%10; tmp[6]='\0'; #endif } else if (n<153) { if (n<51) tmp[1]='\0'; else if (n>51) tmp[2]='4'; else tmp[2]='2'; } else if (n<204) tmp[2]='6'; else if (n>204) { tmp[0]='1'; tmp[1]='\0'; } else tmp[2]='8'; out << tmp; } void Rule::writeTTE( GenBuffer::Writable& out, GenBuffer::Writable&outpal, GenBuffer::Writable&outstream, char const*template_, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings) { unsigned int i, j; register char const*p; char *r; Image::Sampled *img=sf->getImg(); param_assert(template_!=(const char*)NULLP); p=template_; bool nzp, scp; SimBuffer::B scf; while (1) { assert(template_==p); while (*p!='`' && *p!='\0') p++; /* '`' is the escape character */ if (p!=template_) out.vi_write(template_, p-template_); if (*p++=='\0') break; switch (*p++) { case '\0': p--; /* fall through */ case '`': out.vi_write("`", 1); break; case '#': /* number of non-transparent colors of /Indexed*, /Transparent* */ out << sf->getNncols(); break; case 'p': /* 3*(number of non-transparent colors of /Indexed*, /Transparent*) */ out << (3*sf->getNncols()); break; case 'P': /* number of palette bytes (including the transparent color) */ out << img->getRowbeg()-img->getHeadp(); break; case '0': case '1': case '2': /* arbitrary, user-defined string */ param_assert(strings!=(char const*const*)NULLP); out << strings[p[-1]-'0']; break; case 'C': /* PDF /Procset entries */ if (or_->cache.isIndexed()) out << "/ImageI"; else if (or_->cache.isGray()) out << "/ImageB"; else out << "/ImageC"; /* SF_Rgb*, SF_Asis etc. */ break; case 'i': /* PS image or colorimage operator */ out << (or_->cache.isGray() ? "image" : or_->cache.SampleFormat==Image::SF_Mask || or_->cache.SampleFormat==Image::SF_Indexed1 ? "imagemask" : "false 3 colorimage"); break; case 'I': /* PS warning for usage of colorimage operator */ // if (!or_->cache.isGray()) out << "% PSLC required\n"; if (!or_->cache.isGray() && !or_->cache.isTransparentM()) out << "%%Extensions: CMYK\n"; break; #if 0 case "p:invalid": /* optional predictor specification */ { unsigned char pred=or_->cache.Predictor; if (pred== 2) out << "/Predictor 2"; /* TIFF predictor */ else if (pred>=10) out << "/Predictor 10"; /* any PNG predictor */ } #endif case 'w': /* image width, decimal */ out << img->getWd(); break; case 'h': /* image height, decimal */ out << img->getHt(); break; case '?': /* a divisor of rlen*height near 4096 */ if (sf->getImgs()!=NULLP) { /* /Transparent+ */ out << near_div(sf->getImgs()[0]->getRlen(), img->getHt()); /* Dat: `img->getHt()*sf->getNncols()' would be wrong */ } else { out << near_div(img->getRlen(), img->getHt()); } break; case 'B': /* Clean7Bits or Binary; Sun Jun 23 18:55:35 CEST 2002 */ out << (or_->cache.isPDF() ? (or_->cache.isBinSB() ? "%\307\354\217\242\n" : "") : (or_->cache.isBinSB() ? "Binary" : "Clean7Bit")); break; case 'b': /* image bpc, decimal */ /* added "true"|"false" for sam2p-0.39 at Sun Sep 22 17:49:25 CEST 2002 */ if (or_->cache.SampleFormat==Image::SF_Mask) out << "false"; else if (or_->cache.SampleFormat==Image::SF_Indexed1) out << "true"; else out << (unsigned)img->getBpc(); break; case 'c': /* image cpp, decimal */ out << (unsigned)img->getCpp(); break; case 'd': /* device-specific color-space name */ out << Image::Sampled::cs2devcs(img->getCs()); break; case 't': /* closefile specification in PostScript */ if (or_->cache.Compression!=or_->cache.CO_None) out << " F closefile"; if (or_->cache.TransferEncoding!=or_->cache.TE_Binary) out << " T closefile"; break; case 'T': /* TransferEncoding specification in PostScript */ or_->appendTransferSpec(out); break; case 'F': /* decoding filter specification in PostScript */ or_->appendDecoderSpec(out); break; case 'O': /* 0..1 /Decode values */ i=1; emit_Decode: j=img->getCpp(); out << "0 " << i; while (j--!=1) out << " 0 " << i; break; case 'D': /* 0..max-1 /Decode values for indexed, 0..1 for others */ i=(or_->cache.isIndexed())?(1<getBpc())-1:1; goto emit_Decode; case 'S': /* image data stream */ stream_writer(outpal, outstream, sf); break; case 'g': /* PDF 0..1 RGB triplet of the 0th palette color */ assert(img->getTy()==img->TY_INDEXED); r=img->getHeadp(); goto appG; case 'G': /* PDF 0..1 RGB triplet of the 1st palette color */ assert(img->getTy()==img->TY_INDEXED); r=img->getHeadp()+3; appG: div255(out, (unsigned char)r[0]); out << ' '; div255(out, (unsigned char)r[1]); out << ' '; div255(out, (unsigned char)r[2]); break; case 'r': /* PS 0..1 RGB triplet of the 0th palette color */ assert(img->getTy()==img->TY_INDEXED); r=img->getHeadp(); out << (unsigned)(unsigned char)r[0] << " 255 div " << (unsigned)(unsigned char)r[1] << " 255 div " << (unsigned)(unsigned char)r[2] << " 255 div"; break; case 'R': /* PS code for setting up bg and fg colors for an imagemask */ /* formerly: PS 0..1 RGB triplet of the 1st palette color */ /* changed at Sun Sep 22 18:02:41 CEST 2002 */ if (or_->cache.SampleFormat==Image::SF_Mask || or_->cache.SampleFormat==Image::SF_Indexed1) { assert(img->getTy()==img->TY_INDEXED); r=img->getHeadp(); out << (unsigned)(unsigned char)r[0] << " 255 div " /* 0th palette color */ << (unsigned)(unsigned char)r[1] << " 255 div " << (unsigned)(unsigned char)r[2] << " 255 div setrgbcolor\n"; if (or_->cache.SampleFormat==Image::SF_Indexed1) { out << "0 0 moveto\n" << img->getWd() << " 0 lineto\n0 " << img->getHt() << " rlineto\n-" << img->getWd() << " 0 rlineto\nclosepath fill\n" << (unsigned)(unsigned char)r[3] << " 255 div " /* 1st palette color */ << (unsigned)(unsigned char)r[4] << " 255 div " << (unsigned)(unsigned char)r[5] << " 255 div\nsetrgbcolor\n"; } } break; case 'E': /* EPS header for unscaled PS files */ if (or_->cacheHints.Scale==or_->cacheHints.SC_None) out << " EPSF-3.0"; break; case 'X': /* BoundingBox for EPS, MediaBox for PDF */ if (or_->cache.isPDF()) { // out << "0 0 "; out << "0 "; goto do_bbox; } else if (or_->cacheHints.Scale==or_->cacheHints.SC_None) { /* It is no point to start the BoundingBox of EPS files at * (LeftMargin,BottomMargin). The effect would be the same as * specifying no margins at all. Our choice is better: the * BoundingBox contains the image and the margins too. */ // out << "%%BoundingBox: 0 0 "; out << "%%BoundingBox: 0 "; do_bbox: // out << MiniPS::RVALUE(or_->cacheHints.LowerMargin) << ';'; /* SUXX: this would put `1 72 mul' */ // out << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << ';'; /* SUXX: this would put `1 72 mul' */ MiniPS::dumpAdd3(out, MiniPS::Qinteger(0), MiniPS::Qinteger(0), MiniPS::Qinteger(0), or_->cacheHints.LowerMargin, or_->cacheHints.BottomMargin, 1); out << ' '; MiniPS::dumpAdd3(out, or_->cacheHints.ImageDPI, MiniPS::Qinteger(img->getWd()), or_->cacheHints.LeftMargin, or_->cacheHints.RightMargin, MiniPS::Qinteger(0), 2); out << ' '; MiniPS::dumpAdd3(out, or_->cacheHints.ImageDPI, MiniPS::Qinteger(img->getHt()), or_->cacheHints.TopMargin, or_->cacheHints.LowerMargin, MiniPS::Qinteger(0), 2); if (!or_->cache.isPDF()) out << '\n'; } break; case 's': /* scaling to a full PostScript page or translation for PDF and EPS */ nzp=!(MiniPS::isZero(or_->cacheHints.LowerMargin) && MiniPS::isZero(or_->cacheHints.TopMargin)); scp=!MiniPS::isEq(or_->cacheHints.ImageDPI, 72) && !MiniPS::isEq(or_->cacheHints.ImageDPI, -72); if (or_->cache.isPDF()) { SimBuffer::B scf; if (scp) MiniPS::dumpScale(scf, or_->cacheHints.ImageDPI); else scf << 'x'; if (nzp || scp) out << " " << scf << " 0 0 " << scf << " " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.LowerMargin) << " cm"; /* translate */ } else switch (or_->cacheHints.Scale) { case Rule::CacheHints::SC_None: if (nzp) out << '\n' << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.LowerMargin) << " translate"; if (scp) { MiniPS::dumpScale(scf, or_->cacheHints.ImageDPI); out << '\n' << scf << " dup scale"; } break; case Rule::CacheHints::SC_OK: /* from pshack/big.ps */ out <<"\n6 dict begin currentpagedevice/PageSize get dup 0 get\n " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.RightMargin) << " sub/w exch\n" " def 1 get " << MiniPS::RVALUE(or_->cacheHints.TopMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " sub/h exch\n" " def/x " << img->getWd() << " def/y " << img->getHt() << " def " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " translate x h\n" " mul y w mul gt{w x 0 h y w mul x div sub 2 div}{h y w x h mul y div sub 2 div\n" " 0}ifelse translate div dup scale\nend"; break; case Rule::CacheHints::SC_RotateOK: /* from pshack/big.ps */ out <<"\n6 dict begin currentpagedevice/PageSize get dup 0 get\n " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.RightMargin) << " sub/w exch\n" " def 1 get " << MiniPS::RVALUE(or_->cacheHints.TopMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " sub/h exch\n" " def/x " << img->getWd() << " def/y " << img->getHt() << " def " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << "/b y h mul x\n" " w mul gt def b{w y}{h x}ifelse div/c x h mul y w mul gt def c{w x}{h y}ifelse\n" " div gt{h add translate -90 rotate b{w y h x w mul y div sub 2 div 0}{h\n" " x 0 w y h mul x div sub 2 div}}{translate c{w x 0 h y w mul x div sub 2 div}{h\n" " y w x h mul y div sub 2 div 0}}ifelse ifelse translate div dup scale\nend"; break; } break; default: Error::sev(Error::EERROR) << "writeTTE: unknown escape: " << (char)p[-1] << (Error*)0; } template_=p; } } /** by pts@fazekas.hu at Mon Apr 15 22:31:03 CEST 2002 */ void Rule::writeTTM( Filter::VerbatimE &outve, GenBuffer::Writable&outpal, GenBuffer::Writable&outstream, MiniPS::Array *chunkArray, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings) { static const unsigned MAXLEN=64; /* Imp: use heap instead of stack space */ slen_t offsets[MAXLEN+1]; /* 260 bytes stack */ SimBuffer::B chunks[MAXLEN]; /* <=1024 bytes stack; default constructor */ MiniPS::VALUE *chunk; param_assert(chunkArray!=NULLP); // param_assert(chunkArray->getLength()<=MAXLEN); if (chunkArray->getLength()>(int)MAXLEN) Error::sev(Error::EERROR) << "writeTTM: TTM too long" << (Error*)0; GenBuffer::Writable& out=outve.getOut(); MiniPS::ii_t i, ii; for (chunkArray->getFirst(chunk), i=0; chunk!=NULLP; chunkArray->getNext(chunk), i++) { if (MiniPS::getType(*chunk)==MiniPS::T_ARRAY) { outve.setOut(chunks[i]); writeTTM(outve, outpal, outstream, MiniPS::RARRAY(*chunk), or_, sf, stream_writer, strings); } } for (chunkArray->getFirst(chunk), offsets[i=0]=0; chunk!=NULLP; chunkArray->getNext(chunk), i++) { switch (MiniPS::getType(*chunk)) { case MiniPS::T_ARRAY: break; case MiniPS::T_STRING: /* always null-terminated */ outve.setOut(chunks[i]); writeTTE(outve, outpal, outstream, MiniPS::RSTRING(*chunk)->begin_(), or_, sf, stream_writer, strings); break; case MiniPS::T_INTEGER: if (0==(ii=MiniPS::int2ii(*chunk))) Error::sev(Error::EERROR) << "writeTTM: zero is an invalid chunk" << (Error*)0; if (ii>0) { /* an offset */ if (ii>i) Error::sev(Error::EERROR) << "writeTTM: cannot predict chunk offset" << (Error*)0; if (MiniPS::T_ARRAY==MiniPS::getType(chunkArray->get(ii))) chunks[i].write_num(offsets[ii], 10); /* Dat: 10: 10 digits (for PDF xref table), not base 10 */ else chunks[i] << offsets[ii]; } else { /* a length */ chunks[i] << chunks[-ii].getLength(); } break; default: Error::sev(Error::EERROR) << "writeTTM: invalid chunk type: " << MiniPS::getTypeStr(MiniPS::getType(*chunk)) << (Error*)0; } offsets[i+1]=offsets[i]+chunks[i].getLength(); } /* NEXT */ outve.setOut(out); for (i=0; igetLength(); i++) out << chunks[i]; /* Imp: organize that chunks[.] gets freed earlier than this */ } /* Rule::writeTTM() */ MiniPS::Dict *Rule::Templates=(MiniPS::Dict*)NULLP; void Rule::writeTTT( GenBuffer::Writable&out, GenBuffer::Writable&outpal, GenBuffer::Writable&outstream, char const *template_key, Rule::OutputRule*or_, Image::SampledInfo *sf, stream_writer_t stream_writer, char const*const*strings) { assert(Templates!=NULLP); Error::sev(Error::NOTICE) << "writeTTT: using template: " << template_key << (Error*)0; MiniPS::VALUE val=Templates->get(template_key, strlen(template_key)); assert(val!=MiniPS::Qundef); switch (MiniPS::getType(val)) { case MiniPS::T_STRING: writeTTE(out, outpal, outstream, MiniPS::RSTRING(val)->begin_(), or_, sf, stream_writer, strings); break; case MiniPS::T_ARRAY: /* Imp: vvv This up-cast is unsafe! */ writeTTM(*(Filter::VerbatimE*)&out, outpal, outstream, MiniPS::RARRAY(val), or_, sf, stream_writer, strings); break; default: Error::sev(Error::EERROR) << "writeTTT: invalid template type: " << MiniPS::getTypeStr(MiniPS::getType(val)) << (Error*)0; } } /* __END__ */ sam2p-0.49.2/sam2p_main.cpp0000644000175100017510000014626612212351433013575 0ustar ptspts/* sam2p_main.cpp * by pts@fazekas.hu at Fri Mar 15 16:11:03 CET 2002 */ #include "gensi.hpp" #include "gensio.hpp" #include "image.hpp" #include "error.hpp" #include "encoder.hpp" #include "minips.hpp" #include "rule.hpp" #include "main.hpp" #include "in_jai.hpp" #ifndef SAM2P_VERSION #include "sam2p_version.h" #endif /* Sat Jul 6 16:39:19 CEST 2002 * empirical checkerg++ helper routines for gcc version 2.95.2 20000220 (Debian GNU/Linux) * see c_lgcc.cpp for more */ #if !defined(OBJDEP) && defined(__CHECKER__) && !HAVE_PTS_C_LGCC_CPP_REQUIRED # include "c_lgcc.cpp" #endif #if 0 /*#ifdef __CHECKER__*/ #include void* __builtin_vec_new(unsigned len){ return malloc(len); } void __builtin_vec_delete(void *p) { free(p); } void* __builtin_new(unsigned len){ return malloc(len); } void __builtin_delete(void *p) { free(p); } void __rtti_user() { abort(); } void __rtti_si() { abort(); } void terminate() { abort(); } extern "C" void __pure_virtual(); void __pure_virtual() { abort(); } #endif #if OBJDEP # warning PROVIDES: sam2p_main # warning REQUIRES: gensi.o # warning REQUIRES: gensio.o # warning REQUIRES: image.o # warning REQUIRES: error.o # warning REQUIRES: encoder.o # warning REQUIRES: minips.o # warning REQUIRES: rule.o #endif #include #include /* memset() */ #if OBJDEP # warning REQUIRES: in_tiff.o # warning REQUIRES: in_jpeg.o # warning REQUIRES: in_png.o # warning REQUIRES: in_jai.o # warning REQUIRES: in_pcx.o # warning REQUIRES: in_xpm.o # warning REQUIRES: in_lbm.o # warning REQUIRES: in_gif.o # warning REQUIRES: in_bmp.o # warning REQUIRES: in_pnm.o # warning REQUIRES: in_tga.o /*# warning REQUIRES: in_pdf.o Dat: no more, integrated to in_ps.o */ # warning REQUIRES: in_ps.o #endif extern Image::Loader in_tiff_loader; extern Image::Loader in_jpeg_loader; extern Image::Loader in_png_loader; extern Image::Loader in_jai_loader; extern Image::Loader in_pcx_loader; extern Image::Loader in_xpm_loader; extern Image::Loader in_lbm_loader; extern Image::Loader in_gif_loader; extern Image::Loader in_bmp_loader; extern Image::Loader in_pnm_loader; extern Image::Loader in_tga_loader; extern Image::Loader in_pdf_loader; extern Image::Loader in_ps_loader; void init_loader() { static bool had_init_loader=false; if (had_init_loader) return; Image::register0(&in_tga_loader); /* checker not sure; install early */ Image::register0(&in_pcx_loader); Image::register0(&in_xpm_loader); Image::register0(&in_lbm_loader); Image::register0(&in_gif_loader); Image::register0(&in_bmp_loader); Image::register0(&in_pnm_loader); Image::register0(&in_tiff_loader); Image::register0(&in_jpeg_loader); Image::register0(&in_png_loader); Image::register0(&in_jai_loader); Image::register0(&in_pdf_loader); Image::register0(&in_ps_loader); had_init_loader=true; } #if OBJDEP # warning REQUIRES: appliers.o #endif extern Rule::Applier out_pnm_applier; extern Rule::Applier out_jpeg_applier; extern Rule::Applier out_jpegjai_applier; extern Rule::Applier out_tiffjai_applier; extern Rule::Applier out_tiff_applier; extern Rule::Applier out_png_applier; extern Rule::Applier out_bmp_applier; extern Rule::Applier out_gif89a_applier; extern Rule::Applier out_xpm_applier; extern Rule::Applier out_l1c_applier; // extern Rule::Applier out_l1op_applier; extern Rule::Applier out_l1tr_applier; extern Rule::Applier out_l23_applier; // extern Rule::Applier out_l1fa85g_applier; extern Rule::Applier out_l2jbin_applier; // extern Rule::Applier out_p0jbin_applier; extern Rule::Applier out_empty_applier; extern Rule::Applier out_meta_applier; extern Rule::Applier out_xwd_applier; extern Rule::Applier out_x11_applier; void init_applier() { static bool had_init_applier=false; if (had_init_applier) return; // Rule::register0(&out_l1op_applier); Rule::register0(&out_l1tr_applier); // Rule::register0(&out_l1fa85g_applier); Rule::register0(&out_l2jbin_applier); // Rule::register0(&out_p0jbin_applier); Rule::register0(&out_l23_applier); Rule::register0(&out_l1c_applier); Rule::register0(&out_xpm_applier); Rule::register0(&out_gif89a_applier); Rule::register0(&out_pnm_applier); Rule::register0(&out_jpeg_applier); Rule::register0(&out_jpegjai_applier); Rule::register0(&out_tiffjai_applier); Rule::register0(&out_tiff_applier); Rule::register0(&out_png_applier); Rule::register0(&out_bmp_applier); Rule::register0(&out_empty_applier); Rule::register0(&out_meta_applier); Rule::register0(&out_xwd_applier); Rule::register0(&out_x11_applier); had_init_applier=true; } static char bts_ttt[] = #include "bts2.tth" ; /* --- One-liner mode */ /** Dat: mod 16 does matter: expected # args etc. */ static const unsigned OPT_unknown=0, OPT_SampleFormat=0x02, OPT_LoadHints=0x12, OPT_Compression=0x22, OPT_TransferEncoding=0x32, OPT_TransferEncodingF=0x42, OPT_Asis=0x50, OPT_PSL1=0x60, OPT_PSLC=0x70, OPT_PSL2=0x80, OPT_PSL3=0x90, OPT_PS=0xA1, OPT_PDF=0xB1, OPT_DisplayJobFile=0xC1, OPT_Hints=0xD2, OPT_InputFile=0xE2, OPT_OutputFile=0xF2, OPT_Scale=0x101, OPT_Margins=0x112, OPT_Transparent=0x122, OPT_TmpRemove=0x132; /** @param s an option (lower/upper case intact), without leading `-'s * @param slen length of option * @return 0 if invalid/unsupported/unknown option * | 16*(k+1)+0 if the option never accepts parameters * | 16*(k+2)+1 if the option may or may not have a parameter * | 16*(k+3)+2 if the option must have a parameter */ static unsigned sam2p_optval(char const* s, slen_t slen) { if (slen==1) { switch (s[0]) { case 's': return OPT_SampleFormat; case 'l': return OPT_LoadHints; case 'h': return OPT_Hints; case 't': return OPT_TransferEncoding; case 'f': return OPT_TransferEncodingF; case 'c': return OPT_Compression; // case 'a': return OPT_Asis; /* disabled, automatic! */ case '1': return OPT_PSL1; case '2': return OPT_PSL2; case '3': return OPT_PSL3; case 'j': return OPT_DisplayJobFile; case 'o': case 'O': return OPT_OutputFile; case 'e': return OPT_Scale; case 'm': return OPT_Margins; } } else { slen_t len=slen; /* strlen(s); */ if (len>=32) return OPT_unknown; char buf[32]; GenBuffer::tolower_memcpy(buf, s, len); buf[len]='\0'; /* printf("buf=(%s)\n", buf); */ if (0==strcmp(buf, "sampleformat")) return OPT_SampleFormat; if (0==strcmp(buf, "loadhints")) return OPT_LoadHints; if (0==strcmp(buf, "tmpremove")) return OPT_TmpRemove; if (0==strcmp(buf, "transparent")) return OPT_Transparent; if (0==strcmp(buf, "hints")) return OPT_Hints; if (0==strcmp(buf, "ps") || 0==strcmp(buf, "eps")) return OPT_PS; if (0==strcmp(buf, "pdf")) return OPT_PDF; if (0==strcmp(buf, "1c")) return OPT_PSLC; if (0==strcmp(buf, "scale")) return OPT_Scale; if (0==strcmp(buf, "hints")) return OPT_Margins; } return OPT_unknown; } static void displayJob(GenBuffer::Writable &sout, SimBuffer::Flat const& jobss) { fflush(stdout); fflush(stderr); #if 0 puts("\n\n% begin sam2p job dump"); fwrite(stdout, 1, jobss.getLength(), jobss); puts("% end sam2p job dump\n"); #else /* vvv Dat: sout conflicts /OutputFile(-), but it is OK here */ sout << "\n% begin sam2p job dump\n" << jobss << "%)%)%)% end sam2p job dump\n\n"; #endif fflush(stdout); fflush(stderr); } static inline char const *protect_null(char const *s) { return s==(char const*)NULLP ? "//" : s; } /** @return the value for the parameter if matches key or the first letter of * key; or NULLP if no match. * @param key lower case */ static char const*one_pabbr(char const*param, char const *key) { return GenBuffer::nocase_strbegins(param, key) ? param+strlen(key) : (param[0]==key[0] || param[0]==key[0]+'A'-'a') && param[1]==':' ? param+2 : (char const*)NULLP; } #if 0 /* cannot set badp... */ static inline void one_setdimen2(char const*&Dimen1, char const*&Dimen2, char const*p2) { if (MiniPS::Real::isDimen(p2)) Dimen1=Dimen2=p2; else Error::sev(Error::ERROR_CONT) << "one_liner: dimen expected" /*<< (SimBuffer::B().appendDumpC(p2, true))*/ << (Error*)0; } #endif #if 0 #define one_setdimen2(Dimen1,Dimen2,p2) do { \ if (MiniPS::Real::isDimen(p2)) Dimen1=Dimen2=p2; \ else { badmsg="one_liner: dimen expected: "; goto bad_label; } \ } while(0) #endif static Filter::UngetFILED *ufd; static bool do_DisplayJobFile; static bool buildProfile_quiet=false; /** Creates an in-memory job file according to the command-line options. * @param a argv+1 * @param job initially an empty string. On error, this function leaves it * as-is, but on success, a valid job file is appened. * @return true on syntax error */ static bool one_liner(SimBuffer::B &jobss, char const *const* a) { /* Tue Jul 2 21:27:15 CEST 2002 */ char const *p, *pend; bool no_option_term=true; bool badp=false; bool no_selector=true; char const *badmsg; // SimBuffer::B Profile /* MiniPS code */ SimBuffer::B Hints; /* MiniPS code */ /* ^^^ Imp: separate hint for each -c arg?? */ SimBuffer::B LoadHints; bool TmpRemove_p=true; Rule::Cache::pr_t Predictor=Rule::Cache::PR_None; /* Imp: separate for each Compression */ Rule::Cache::ff_t FileFormat=Rule::Cache::FF_default; Rule::Cache::te_t TransferEncoding=Rule::Cache::TE_default; do_DisplayJobFile=false; bool do_stop_SampleFormat=false; char const *Transparent=(char const*)NULLP; /* change 1 color to transparent unless NULL */ char const *OutputFile=(char const*)NULLP, *InputFile=(char const*)NULLP; // SimBuffer::B tmp; char const *TopMargin=(char const*)NULLP, *BottomMargin=(char const*)NULLP, *LeftMargin=(char const*)NULLP, *RightMargin=(char const*)NULLP, *LowerMargin=(char const*)NULLP, *ImageDPI=(char const*)NULLP; bool negLowerMargin=false; Rule::CacheHints::sc_t Scale=Rule::CacheHints::SC_default; #define APPEND_sf(val) do { if (sfx[val]==0) { sfx[val]=1; sft[sflen++]=val; } } while (0) Image::sf_t sft[Image::SF_max+1]; char sfx[Image::SF_max+1]; memset(sfx, 0, sizeof(sfx)); unsigned sflen=0; #define APPEND_co(val) do { if (cox[val]==0) { cox[val]=1; cot[colen++]=val; } } while (0) Rule::Cache::co_t cot[Rule::Cache::CO_max+1]; char cox[Image::SF_max+1]; memset(cox, 0, sizeof(cox)); unsigned colen=0; /* ^^^ BUGFIX at 2002.12.02 */ /** OPT_* value of current option */ unsigned opt; /** Parameter for current option. May be NULL. */ char const *param=""; /* pacify VC6.0 */ char const *p2; slen_t paramlen; SimBuffer::B tmpnam; /* any dir -- keep on stack frame */ buildProfile_quiet=true; for (; (p=*a)!=(char const*)NULLP; a++) { if (p[0]=='-' && p[1]=='\0') { /* `-': Filename: STDIN or STDOUT */ #if 1 goto normal_label; #else Error::sev(Error::ERROR_CONT) << "one_liner: `-' (stdin|stdout) not allowed as filename" << (Error*)0; badp=true; continue; #endif } else if (p[0]=='-' && p[1]=='-' && p[2]=='\0') { /* `--': No more options */ if (a[1]==(char const*)NULLP && InputFile!=(char const*)NULLP) { /* `--' is last argument */ p=InputFile; /* OutputFile:=InputFile */ goto normal_label; } no_option_term=false; } else if (p[0]=='-' && no_option_term) { /* an option */ while (*p=='-') p++; /* short options (-p) and long options (--pdf) are equivalent */ pend=p; while (*pend!='\0' && *pend!=':' && *pend!='=') pend++; SimBuffer::Static optss(p, pend-p); if (0==(opt=sam2p_optval(p, pend-p))) { badmsg="one_liner: unknown option: "; bad_label: Error::sev(Error::ERROR_CONT) << badmsg << (SimBuffer::B().appendDumpC(optss, true)) << (Error*)0; badp=true; continue; } if ((opt&15)==0) { /* no parameters */ if (*pend!='\0') { badmsg="one_liner: don't give param to option: "; goto bad_label; } param=(char const*)NULLP; } else if ((opt&15)==1) { /* an optional parameter */ if (*pend!='\0') { param=pend+1; while (*pend==*param) param++; } else param=(char const*)NULLP; } else if ((opt&15)==2) { /* a mandatory parameter */ if (*pend!='\0') { param=pend+1; while (*pend==*param) param++; } else if ((param=*++a)==(char const*)NULLP) { badmsg="one_liner: missing param for option: "; goto bad_label; } } else assert(0); paramlen=param==(char const*)NULLP ? 0 : strlen(param); /* Dat: now opt, paramlen and param are correct */ switch (opt) { case OPT_LoadHints: LoadHints << ',' << param; break; case OPT_TmpRemove: TmpRemove_p=GenBuffer::parseBool(param, paramlen); break; case OPT_Transparent: Transparent=param; break; /* Imp: is this good memory management */ case OPT_Hints: Hints << '\n' << param; break; case OPT_PSL1: FileFormat=Rule::Cache::FF_PSL1; break; case OPT_PSLC: FileFormat=Rule::Cache::FF_PSLC; break; case OPT_PSL2: FileFormat=Rule::Cache::FF_PSL2; break; case OPT_PSL3: FileFormat=Rule::Cache::FF_PSL3; break; case OPT_DisplayJobFile: // fprintf(stderr, "param=(%s)\n", param); if (paramlen==0 || 0==GenBuffer::nocase_strcmp(param, "job")) do_DisplayJobFile=true; else if (0==GenBuffer::nocase_strcmp(param, "warn")) buildProfile_quiet=false; else if (GenBuffer::nocase_strbegins(param, "warn:")) buildProfile_quiet=!GenBuffer::parseBool(param+5, paramlen-5); else if (0==GenBuffer::nocase_strcmp(param, "quiet")) { buildProfile_quiet=true; Error::setTopPrinted(Error::ERROR_CONT); } /* Dat: hide warnings, info etc. */ /* at Fri Aug 26 07:54:00 CEST 2005 */ else if (GenBuffer::nocase_strbegins(param, "job:")) do_DisplayJobFile=GenBuffer::parseBool(param+4, paramlen-4); else do_DisplayJobFile=GenBuffer::parseBool(param, paramlen); /* Imp: better error report */ break; case OPT_Margins: /* Dat:abbreviation letters are distinct: [ahxvylrtubd] */ if (0!=(p2=one_pabbr(param,"all:"))) { all5: if (MiniPS::Real::isDimen(p2)) LeftMargin=RightMargin=TopMargin=BottomMargin=LowerMargin=p2; else { err_dimexp: badmsg="one_liner: dimen expected: "; goto bad_label; } } else if (0!=(p2=one_pabbr(param,"horiz:")) || 0!=(p2=one_pabbr(param,"x:"))) { if (MiniPS::Real::isDimen(p2)) LeftMargin=RightMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"vert:")) || 0!=(p2=one_pabbr(param,"y:"))) { if (MiniPS::Real::isDimen(p2)) TopMargin=BottomMargin=LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"left:"))) { if (MiniPS::Real::isDimen(p2)) LeftMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"right:"))) { if (MiniPS::Real::isDimen(p2)) RightMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"dpi:"))) { if (MiniPS::Real::isDimen(p2)) ImageDPI=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"top:")) || 0!=(p2=one_pabbr(param,"up:"))) { if (MiniPS::Real::isDimen(p2)) TopMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"bottom:")) || 0!=(p2=one_pabbr(param,"down:"))) { if (MiniPS::Real::isDimen(p2)) BottomMargin=LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"raise:"))) { if (MiniPS::Real::isDimen(p2)) LowerMargin=p2; else goto err_dimexp; } else if (0!=(p2=one_pabbr(param,"lower:"))) { negLowerMargin=true; if (MiniPS::Real::isDimen(p2)) LowerMargin=p2; else goto err_dimexp; } else { p2=param; goto all5; } break; case OPT_Scale: if (paramlen==0 || 0==GenBuffer::nocase_strcmp(param, "scale")) Scale=Rule::CacheHints::SC_OK; else if (0==GenBuffer::nocase_strcmp(param, "none")) Scale=Rule::CacheHints::SC_None; else if (0==GenBuffer::nocase_strcmp(param, "rot")) Scale=Rule::CacheHints::SC_RotateOK; else if (0==GenBuffer::nocase_strcmp(param, "rotate")) Scale=Rule::CacheHints::SC_RotateOK; else Scale=(Rule::CacheHints::sc_t)(GenBuffer::parseBool(param, paramlen) ? 0+Rule::CacheHints::SC_OK : 0+Rule::CacheHints::SC_None); /* ^^^ Imp: better error report */ /* ^^^ +0: pacify g++-3.1 */ break; case OPT_TransferEncoding: if (0==GenBuffer::nocase_strcmp(param, "bin")) TransferEncoding=Rule::Cache::TE_Binary; else if (0==GenBuffer::nocase_strcmp(param, "hex")) TransferEncoding=Rule::Cache::TE_Hex; else if (0==GenBuffer::nocase_strcmp(param, "a85")) TransferEncoding=Rule::Cache::TE_A85; else if (0==GenBuffer::nocase_strcmp(param, "ascii"))TransferEncoding=Rule::Cache::TE_ASCII; else if (0==GenBuffer::nocase_strcmp(param, "lsb1")) TransferEncoding=Rule::Cache::TE_LSBfirst; else if (0==GenBuffer::nocase_strcmp(param, "msb1")) TransferEncoding=Rule::Cache::TE_MSBfirst; else { inv_par: badmsg="one_liner: invalid param for option: "; goto bad_label; } break; case OPT_TransferEncodingF: if (0==GenBuffer::nocase_strcmp(param, "lsb2msb")) TransferEncoding=Rule::Cache::TE_LSBfirst; else if (0==GenBuffer::nocase_strcmp(param, "msb2lsb")) TransferEncoding=Rule::Cache::TE_MSBfirst; else goto inv_par; break; case OPT_PS: if (param==(char const*)NULLP || param[0]=='\0') FileFormat=Rule::Cache::FF_eps; else if (0==GenBuffer::nocase_strcmp(param, "1")) FileFormat=Rule::Cache::FF_PSL1; else if (0==GenBuffer::nocase_strcmp(param, "1c") || 0==GenBuffer::nocase_strcmp(param, "c")) FileFormat=Rule::Cache::FF_PSLC; else if (0==GenBuffer::nocase_strcmp(param, "2")) FileFormat=Rule::Cache::FF_PSL2; else if (0==GenBuffer::nocase_strcmp(param, "3")) FileFormat=Rule::Cache::FF_PSL3; else goto inv_par; break; case OPT_PDF: if (param==(char const*)NULLP || param[0]=='\0') FileFormat=Rule::Cache::FF_pdfb; else if (0==GenBuffer::nocase_strcmp(param, "b")) FileFormat=Rule::Cache::FF_pdfb; /* BI */ else if (0==GenBuffer::nocase_strcmp(param, "x")) FileFormat=Rule::Cache::FF_pdf; /* XObject */ else if (0==GenBuffer::nocase_strcmp(param, "b0")) FileFormat=Rule::Cache::FF_PDFB10; else if (0==GenBuffer::nocase_strcmp(param, "b2")) FileFormat=Rule::Cache::FF_PDFB12; else if (0==GenBuffer::nocase_strcmp(param, "0")) FileFormat=Rule::Cache::FF_PDF10; else if (0==GenBuffer::nocase_strcmp(param, "2")) FileFormat=Rule::Cache::FF_PDF12; else goto inv_par; break; case OPT_SampleFormat: pend=param; while (*pend!='\0') { while (*pend==':') pend++; if (do_stop_SampleFormat) goto inv_par; /* already stopped */ p=pend; while (*pend!='\0' && *pend!=':') pend++; paramlen=pend-p; if (4==paramlen && 0==memcmp(p,"stop",4)) { do_stop_SampleFormat=true; buildProfile_quiet=false; break; } if (5==paramlen && 0==memcmp(p,"stopq",5)) { do_stop_SampleFormat=true; break; } if (2==paramlen && 0==memcmp(p,"tr",2)) { APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Mask); APPEND_sf(Image::SF_Transparent2); APPEND_sf(Image::SF_Transparent4); APPEND_sf(Image::SF_Transparent8); } else { Image::sf_t sf=Rule::Cache::parseSampleFormat(p, paramlen); if (sf==Image::SF_max) goto inv_par; APPEND_sf(sf); } } break; case OPT_Compression: assert(param!=(char const*)NULLP); if (0==GenBuffer::nocase_strcmp(param, "none")) APPEND_co(Rule::Cache::CO_None); else if (0==GenBuffer::nocase_strcmp(param, "lzw")) APPEND_co(Rule::Cache::CO_LZW); else if (0==GenBuffer::nocase_strcmp(param, "zip")) APPEND_co(Rule::Cache::CO_ZIP); else if (0==GenBuffer::nocase_strcmp(param, "rle") || 0==GenBuffer::nocase_strcmp(param, "packbits")) APPEND_co(Rule::Cache::CO_RLE); else if (0==GenBuffer::nocase_strcmp(param, "dct")) { APPEND_co(Rule::Cache::CO_DCT); Hints << "\n/DCT<<>>"; } else if (0==GenBuffer::nocase_strcmp(param, "jpg") || 0==GenBuffer::nocase_strcmp(param, "jpeg")) { APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); } else if (0==GenBuffer::nocase_strcmp(param, "ijg")) APPEND_co(Rule::Cache::CO_IJG); else if (0==GenBuffer::nocase_strcmp(param, "g4")) { APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K -1"; } else if (0==GenBuffer::nocase_strcmp(param, "g3") || 0==GenBuffer::nocase_strcmp(param, "fax") || 0==GenBuffer::nocase_strcmp(param, "g3:1d"))APPEND_co(Rule::Cache::CO_Fax); else if (0==GenBuffer::nocase_strcmp(param, "g3:2d")){ APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K -2"; } else if (0==GenBuffer::nocase_strcmp(param, "jai")) APPEND_co(Rule::Cache::CO_JAI); else if (GenBuffer::nocase_strbegins(param, "lzw:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_LZW); Predictor=(Rule::Cache::pr_t)i; } else if (GenBuffer::nocase_strbegins(param, "rle:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_RLE); Hints << "\n/RecordSize " << i; } else if (GenBuffer::nocase_strbegins(param, "packbits:")) { SimBuffer::Static s(param+9); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_RLE); Hints << "\n/RecordSize " << i; } else if (GenBuffer::nocase_strbegins(param, "fax:")) { SimBuffer::Static s(param+4); long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_Fax); Hints << "\n/K " << i; } else if (GenBuffer::nocase_strbegins(param, "dct:")) { APPEND_co(Rule::Cache::CO_DCT); Hints << "\n/DCT<< " << (param+4) << " >>"; } else if (GenBuffer::nocase_strbegins(param, "ijg:")) { SimBuffer::Static s(param+4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_IJG); Hints << "\n/Quality " << i; } else if (GenBuffer::nocase_strbegins(param, "jpeg:")) { SimBuffer::Static s(param+5); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); Hints << "\n/Quality " << i; } else if (GenBuffer::nocase_strbegins(param, "zip:")) { pend=param+4; while (*pend!='\0' && *pend!=':') pend++; SimBuffer::Static s(param+4, pend-param-4); unsigned long i; /* toInteger() is quickest on long */ if (s.toInteger(i)) goto inv_par; APPEND_co(Rule::Cache::CO_ZIP); Predictor=(Rule::Cache::pr_t)i; if (*pend==':') { pend++; while (*pend==':') pend++; SimBuffer::Static s(pend); if (s.toInteger(i)) goto inv_par; // Error::sev(Error::FATAL) << "SUXX)" << s << ',' << i << '.' << (Error*)0; APPEND_co(Rule::Cache::CO_ZIP); Hints << "\n/Effort " << i; // Error::sev(Error::FATAL) << "SUXX(" << s << ',' << Hints << '.' << (Error*)0; } } else goto inv_par; break; default: assert(0); } } else { /* a selector or a normal argument */ if (!(no_selector && no_option_term)) goto normal_label; pend=p; while (*pend!='\0' && *pend!=':') pend++; if (pend-p>=2 && *pend==':') { /* an ImageMagick-style FileFormat selector */ if (GenBuffer::nocase_strbegins(p, "PSL2:") || GenBuffer::nocase_strbegins(p, "EPS2:")) FileFormat=Rule::Cache::FF_PSL2; else if (GenBuffer::nocase_strbegins(p, "EPS:")) FileFormat=Rule::Cache::FF_eps; else if (GenBuffer::nocase_strbegins(p, "PS2:")) { FileFormat=Rule::Cache::FF_PSL2; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (GenBuffer::nocase_strbegins(p, "PS:")) { FileFormat=Rule::Cache::FF_eps; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (GenBuffer::nocase_strbegins(p, "PSL1:")) FileFormat=Rule::Cache::FF_PSL1; else if (GenBuffer::nocase_strbegins(p, "PSLC:")) FileFormat=Rule::Cache::FF_PSLC; else if (GenBuffer::nocase_strbegins(p, "PSL3:")) FileFormat=Rule::Cache::FF_PSL3; else if (GenBuffer::nocase_strbegins(p, "PDF:") || GenBuffer::nocase_strbegins(p, "PDF:")) FileFormat=Rule::Cache::FF_pdfb; else if (GenBuffer::nocase_strbegins(p, "PDFX:")) FileFormat=Rule::Cache::FF_pdf; else if (GenBuffer::nocase_strbegins(p, "PDFB1.0:")) FileFormat=Rule::Cache::FF_PDFB10; else if (GenBuffer::nocase_strbegins(p, "PDFB1.2:")) FileFormat=Rule::Cache::FF_PDFB12; else if (GenBuffer::nocase_strbegins(p, "PDF1.0:")) FileFormat=Rule::Cache::FF_PDF10; else if (GenBuffer::nocase_strbegins(p, "PDF1.2:")) FileFormat=Rule::Cache::FF_PDF12; else if (GenBuffer::nocase_strbegins(p, "GIF89a:") || GenBuffer::nocase_strbegins(p, "GIF:")) FileFormat=Rule::Cache::FF_GIF89a; /* vvv do_stop_SampleFormat BUGFIX at Thu Nov 21 23:44:20 CET 2002 */ else if (GenBuffer::nocase_strbegins(p, "PNM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PBM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PGM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PPM:")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Rgb8); do_stop_SampleFormat=true; } else if (GenBuffer::nocase_strbegins(p, "PAM:")) FileFormat=Rule::Cache::FF_PAM; else if (GenBuffer::nocase_strbegins(p, "PIP:")) FileFormat=Rule::Cache::FF_PIP; else if (GenBuffer::nocase_strbegins(p, "Empty:"))FileFormat=Rule::Cache::FF_Empty; else if (GenBuffer::nocase_strbegins(p, "Meta:")) FileFormat=Rule::Cache::FF_Meta; else if (GenBuffer::nocase_strbegins(p, "JPEG:") || GenBuffer::nocase_strbegins(p, "JPG:")) FileFormat=Rule::Cache::FF_JPEG; else if (GenBuffer::nocase_strbegins(p, "TIFF:") || GenBuffer::nocase_strbegins(p, "TIF:")) FileFormat=Rule::Cache::FF_TIFF; else if (GenBuffer::nocase_strbegins(p, "PNG:")) FileFormat=Rule::Cache::FF_PNG; else if (GenBuffer::nocase_strbegins(p, "XPM:")) FileFormat=Rule::Cache::FF_XPM; else if (GenBuffer::nocase_strbegins(p, "BMP:") || GenBuffer::nocase_strbegins(p, "RLE:")) { FileFormat=Rule::Cache::FF_BMP; /*APPEND_co(Rule::Cache::CO_RLE);*/ } else if (GenBuffer::nocase_strbegins(p, "XWD:")) FileFormat=Rule::Cache::FF_XWD; else if (GenBuffer::nocase_strbegins(p, "X11:")) FileFormat=Rule::Cache::FF_X11; else { Error::sev(Error::ERROR_CONT) << "one_liner: invalid FileFormat selector: " << (SimBuffer::B().appendDumpC(SimBuffer::Static(p, pend-p), true)) << (Error*)0; badp=true; continue; } no_selector=false; while (*pend==':') pend++; if (*pend=='\0') continue; /* this arg is just a selector */ /* normal argument is coming */ p=pend; } normal_label: if (InputFile==(char const*)NULLP) { InputFile=p; /* set it even on error */ /* vvv since Sat Apr 19 13:37:57 CEST 2003: * Possibly unseekable STDIN is handled by Filter::UngetFILED */ #if 0 if (p[0]=='-' && p[1]=='\0') { /* Filename: STDIN */ Files::set_binary_mode(0, true); if (0!=fseek(stdin, 0L, 0)) { unseekable: #if 0 Error::sev(Error::ERROR_CONT) << "one_liner: `-' (stdin) not allowed as InputFile (stdin unseekable)" << (Error*)0; badp=true; continue; #endif FILE *f=Files::open_tmpnam(tmpnam); if (!f) { Error::sev(Error::ERROR_CONT) << "one_liner: cannot open" << " temporary file for `-' (stdin)" << (Error*)0; badp=true; continue; } tmpnam.term0(); Files::tmpRemoveCleanup(InputFile=tmpnam()); char *buf=new char[4096]; unsigned got; while ( (0<(got=fread(buf, 1, sizeof(buf), stdin))) && got==fwrite(buf, 1, sizeof(buf), f)) {} delete [] buf; if (ferror(f) || 0!=fclose(f) || ferror(stdin)) { Error::sev(Error::ERROR_CONT) << "one_liner: cannot write" << " temporary file for `-' (stdin)" << (Error*)0; badp=true; continue; } // fprintf(stderr, "if=(%s)\n", InputFile); continue; /* Imp: report `-' as filename on errors etc. */ } int c=MACRO_GETC(stdin); if (0!=fseek(stdin, 0L, 0)) { if (c>=0) ungetc(c, stdin); goto unseekable; } /* active test */ /* ungetc() is not necessary because of fseek() */ } #endif } else if (OutputFile==(char const*)NULLP) { /* Filename: STDOUT */ Files::set_binary_mode(1, true); OutputFile=p; if (FileFormat==Rule::Cache::FF_default) { /* OutputFile; determine FileFormat from extension */ pend=p+strlen(p); while (pend!=p && *pend!='.') pend--; /* ^^^ Dat: extra care later for /a/b.c/d */ if (pend!=p) { /* have extension */ assert(*pend=='.'); pend++; if (0==GenBuffer::nocase_strcmp(pend, "eps") || 0==GenBuffer::nocase_strcmp(pend, "epsi") || 0==GenBuffer::nocase_strcmp(pend, "epsf")) FileFormat=Rule::Cache::FF_eps; else if (0==GenBuffer::nocase_strcmp(pend, "ps")) { FileFormat=Rule::Cache::FF_eps; if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_RotateOK; } else if (0==GenBuffer::nocase_strcmp(pend, "pdf")) FileFormat=Rule::Cache::FF_pdfb; else if (0==GenBuffer::nocase_strcmp(pend, "gif")) FileFormat=Rule::Cache::FF_GIF89a; else if (0==GenBuffer::nocase_strcmp(pend, "pnm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pbm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray1); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pgm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Gray8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "ppm")) { FileFormat=Rule::Cache::FF_PNM; APPEND_sf(Image::SF_Rgb8); do_stop_SampleFormat=true; } else if (0==GenBuffer::nocase_strcmp(pend, "pam")) FileFormat=Rule::Cache::FF_PAM; else if (0==GenBuffer::nocase_strcmp(pend, "pip")) FileFormat=Rule::Cache::FF_PIP; else if (0==GenBuffer::nocase_strcmp(pend, "empty"))FileFormat=Rule::Cache::FF_Empty; else if (0==GenBuffer::nocase_strcmp(pend, "meta")) FileFormat=Rule::Cache::FF_Meta; else if (0==GenBuffer::nocase_strcmp(pend, "jpeg") || 0==GenBuffer::nocase_strcmp(pend, "jpg")) FileFormat=Rule::Cache::FF_JPEG; else if (0==GenBuffer::nocase_strcmp(pend, "tiff") || 0==GenBuffer::nocase_strcmp(pend, "tif")) FileFormat=Rule::Cache::FF_TIFF; else if (0==GenBuffer::nocase_strcmp(pend, "png")) FileFormat=Rule::Cache::FF_PNG; else if (0==GenBuffer::nocase_strcmp(pend, "xpm")) FileFormat=Rule::Cache::FF_XPM; else if (0==GenBuffer::nocase_strcmp(pend, "bmp") || 0==GenBuffer::nocase_strcmp(pend, "rle")) { FileFormat=Rule::Cache::FF_BMP; /*APPEND_co(Rule::Cache::CO_RLE);*/ } else if (0==GenBuffer::nocase_strcmp(pend, "xwd")) FileFormat=Rule::Cache::FF_XWD; // else if (0==GenBuffer::nocase_strcmp(pend, "x11")) FileFormat=Rule::Cache::FF_X11; /* ^^^ .x11 extension is useless */ } } } else { Error::sev(Error::ERROR_CONT) << "one_liner: got too many (>2) filenames" << (Error*)0; badp=true; continue; } } /* IF */ } /* NEXT */ if (InputFile==(char const*)NULLP) { Error::sev(Error::ERROR_CONT) << "one_liner: InputFile unspecified" << (Error*)0; badp=true; } if (OutputFile==(char const*)NULLP) { Error::sev(Error::ERROR_CONT) << "one_liner: OutputFile unspecified" << (Error*)0; badp=true; } if (FileFormat==Rule::Cache::FF_default) { Error::sev(Error::ERROR_CONT) << "one_liner: FileFormat unspecified" << (Error*)0; badp=true; } if (badp) return true; int prcc = (colen==0) ? 2 : 1; if (colen==0) { /* apply default if Compression is unspecified */ // Error::sev(Error::FATAL) << "FileFormat=" << (unsigned)FileFormat << (Error*)0; switch (FileFormat) { case Rule::Cache::FF_TIFF: case Rule::Cache::FF_eps: case Rule::Cache::FF_PSL2: case Rule::Cache::FF_PDFB10: case Rule::Cache::FF_PDF10: APPEND_co(Rule::Cache::CO_JAI); #if HAVE_LZW APPEND_co(Rule::Cache::CO_LZW); #endif APPEND_co(Rule::Cache::CO_RLE); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_BMP: case Rule::Cache::FF_PSL1: case Rule::Cache::FF_PSLC: /* assert(0); */ APPEND_co(Rule::Cache::CO_RLE); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_PSL3: case Rule::Cache::FF_pdfb: /* BUGFIX at Sun Sep 22 14:57:03 CEST 2002 */ case Rule::Cache::FF_pdf: case Rule::Cache::FF_PDFB12: case Rule::Cache::FF_PDF12: APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_ZIP); APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_GIF89a: APPEND_co(Rule::Cache::CO_LZW); /* _not_ /LZWEncode filter */ APPEND_co(Rule::Cache::CO_None); break; case Rule::Cache::FF_JPEG: APPEND_co(Rule::Cache::CO_JAI); APPEND_co(Rule::Cache::CO_IJG); break; case Rule::Cache::FF_PNG: APPEND_co(Rule::Cache::CO_ZIP); break; default: APPEND_co(Rule::Cache::CO_None); break; /* for others FileFormats: CO_None, but that is _not_ appended anyway */ } } else { if ((int)Predictor == 55 || (int)Predictor == 45) { Error::sev(Error::WARNING) << "predictor: /Predictor " << (int)Predictor << " is inefficient; use /Predictor 15 instead" << (Error*)0; } } /* Dat: don't append /Compression/None if the user has specified `-c'. The * user can append `-c none' manually. */ if (Scale==Rule::CacheHints::SC_default) Scale=Rule::CacheHints::SC_None; if (TransferEncoding==Rule::Cache::TE_default) { /* apply default if TransferEncoding is unspecified */ switch (FileFormat) { case Rule::Cache::FF_PSL1: case Rule::Cache::FF_PSLC: TransferEncoding=(Rule::Cache::te_t)(cox[Rule::Cache::CO_ZIP]!=0 || cox[Rule::Cache::CO_LZW]!=0 ? 0+Rule::Cache::TE_A85 : 0+Rule::Cache::TE_Hex); break; /* ^^^ Dat: /Hex is default for /RLE */ case Rule::Cache::FF_eps: case Rule::Cache::FF_PSL2: case Rule::Cache::FF_PSL3: TransferEncoding=Rule::Cache::TE_A85; break; #if 0 /* useless bugfix */ case Rule::Cache::FF_XPM: /* BUGFIX at Thu Jul 11 21:53:56 CEST 2002 */ // assert(0); TransferEncoding=Rule::Cache::TE_ASCII; break; #endif default: TransferEncoding=Rule::Cache::TE_Binary; break; } } unsigned coc=colen; /* Smart verify whether /Compression/JAI is requested. If so, and the input * file is JPEG, then load it as-is. Our heuristic is that if the user * allowed /Compression/JAI among others, and the input file is a baseline * JPEG, then /Compression/JAI will be the best (and only) compression * method. */ bool jaip=cox[Rule::Cache::CO_JAI]!=0; if (jaip) { if (ufd==NULLP) ufd=new Filter::UngetFILED(InputFile, stdin, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); /* vvv Imp: no error handling */ if (1!=jai_is_baseline_jpeg(ufd)) { jaip=false; coc--; cox[Rule::Cache::CO_JAI]=0; } ufd->seek(0); #if 0 assert(ufd->vi_getcc()==255); assert(ufd->vi_getcc()==0xd8); assert(ufd->vi_getcc()==255+0); assert(0); #endif } if (jaip) { /* Dat: might have changed to false */ APPEND_sf(Image::SF_Asis); LoadHints << ",jpeg-asis,"; cot[0]=Rule::Cache::CO_JAI; colen=1; /* disable all other compression */ } else if (coc==1 && cox[Rule::Cache::CO_Fax]!=0) { APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Indexed1); APPEND_sf(Image::SF_Mask); } else if (coc==1 && (cox[Rule::Cache::CO_DCT]!=0 || cox[Rule::Cache::CO_IJG]!=0)) { APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Rgb8); } else if (!do_stop_SampleFormat) { /* JAI compression is automatically disabled since jaip==false */ /* Guess SampleFormat automatically. The order is significant, so most * warnings emitted by Image::SampledInfo::setSampleFormat() are avoided. */ APPEND_sf(Image::SF_Opaque); APPEND_sf(Image::SF_Transparent); APPEND_sf(Image::SF_Gray1); APPEND_sf(Image::SF_Indexed1); APPEND_sf(Image::SF_Mask); APPEND_sf(Image::SF_Gray2); APPEND_sf(Image::SF_Indexed2); APPEND_sf(Image::SF_Rgb1); APPEND_sf(Image::SF_Gray4); APPEND_sf(Image::SF_Indexed4); APPEND_sf(Image::SF_Rgb2); APPEND_sf(Image::SF_Gray8); APPEND_sf(Image::SF_Indexed8); APPEND_sf(Image::SF_Rgb4); APPEND_sf(Image::SF_Rgb8); APPEND_sf(Image::SF_Transparent2); /* transparents are put last because of expensive color separation */ APPEND_sf(Image::SF_Transparent4); APPEND_sf(Image::SF_Transparent8); } /* Append more Hints */ if (Scale!=Rule::CacheHints::SC_None) Hints << "\n/Scale /" << protect_null(Rule::CacheHints::dumpScale(Scale)); if ((char const*)NULLP!=ImageDPI) Hints << "\n/ImageDPI " << ImageDPI; if ((char const*)NULLP!=LeftMargin) Hints << "\n/LeftMargin " << LeftMargin; if ((char const*)NULLP!=RightMargin) Hints << "\n/RightMargin " << RightMargin; if ((char const*)NULLP!=TopMargin) Hints << "\n/TopMargin " << TopMargin; if ((char const*)NULLP!=BottomMargin) Hints << "\n/BottomMargin " << BottomMargin; if ((char const*)NULLP!=LowerMargin) { Hints << "\n/LowerMargin "; if (negLowerMargin) { if (LowerMargin[0]=='-') Hints << (LowerMargin+1); else Hints << '-' << LowerMargin; } else Hints << LowerMargin; } /* Emit job file */ jobss << "<<%sam2p in-memory job file, autogenerated by " << Error::banner0 << "\n/InputFile "; jobss.appendDumpPS(SimBuffer::Static(InputFile), true); jobss << "\n/OutputFile "; jobss.appendDumpPS(SimBuffer::Static(OutputFile), true); jobss << "\n/LoadHints "; jobss.appendDumpPS(LoadHints, true); jobss << "\n/TmpRemove " << (TmpRemove_p ? "true" : "false"); jobss << "\n/Profile[\n"; unsigned coi, sfi; slen_t orc=0; int prc; bool is_predictor_recommended; for (sfi=0;sfi0; --prc) { /* Add an extra predictor only for LZW or ZIP, appropriate SampleFormat * and if the `-c' command line option was not specified. * So if the user specifies `-c zip', he won't get a predictor by * default; but if he specifies no `-c', he might get a `-c:zip:15'. * To get the smallest file size, he should specify `-c zip:15:9'. * * The value we assign to is_predictor_recommended comes from the * do_filter = ... assignment in png_write_IHDR() in pngwutil.c of * libpng-1.2.15 . */ is_predictor_recommended = ( sf==Image::SF_Gray8 || sf==Image::SF_Rgb8); if (prc>1 && ((co!=Rule::Cache::CO_LZW && co!=Rule::Cache::CO_ZIP) || !is_predictor_recommended)) continue; jobss << "<<% OutputRule #" << orc++ << "\n /FileFormat /" << protect_null(Rule::Cache::dumpFileFormat(FileFormat, co)) << "\n /TransferEncoding /" << protect_null(Rule::Cache::dumpTransferEncoding(TransferEncoding)) << "\n /SampleFormat /" << protect_null(Rule::Cache::dumpSampleFormat(sf)) << "\n /Compression /" << protect_null(Rule::Cache::dumpCompression (co)) << "\n /Predictor " << (int)(co==Rule::Cache::CO_LZW || co==Rule::Cache::CO_ZIP ? /* If no compression (or predictor) specified, try predictor 15, then 1; otherwise try the specified predictor */ /* +0 down there to avoid linking problems with g++ on Mac OS X 10.5.6 */ (prc>1 ? Rule::Cache::PR_PNGAuto+0 : Predictor != Rule::Cache::PR_PNGAutoMaybe ? Predictor : is_predictor_recommended ? Rule::Cache::PR_PNGAuto+0 : Rule::Cache::PR_None+0) : Rule::Cache::PR_None+0) << "\n /Hints << " << Hints << " >>"; // jobss << " /Transparent (\377\377\377)\n"; if (Transparent!=NULL) { jobss << "\n /Transparent "; jobss.appendDumpPS(SimBuffer::Static(Transparent), true); } jobss << "\n>>\n"; } } } jobss << "]>>% __EOF__\n"; /* Common keys not emited here: * /TmpRemove true /Templates pop * /ColorTransform pop * /EncoderColumns 0 /EncoderBPL 0 /EncoderRows 0 /EncoderColors 0 * /PredictorColumns 0 /PredictorBPC 0 /PredictorColors 0 * /Transparent null * /WarningOK true * /Comment pop * /Title pop * /Subject pop * /Author pop * /Creator pop * /Producer pop * /Created pop * /Produced pop */ return false; #undef APPEND_sf #undef APPEND_co } /* one_liner() */ static bool option_eq(char const *arg, char const*option) { if (option[0]=='-') { option++; while (arg[0]=='-') arg++; } return 0==GenBuffer::nocase_strcmp(arg, option); } void init_sam2p_engine(char const*argv0) { Error::long_argv0=argv0==(char const*)NULLP ? "sam2p" : argv0; Error::argv0=Files::only_fext(Error::long_argv0); Error::tmpargv0="_sam2p_"; Error::banner0="sam2p " SAM2P_VERSION; } /* --- */ /* Never returns. */ int run_sam2p_engine(Files::FILEW &sout, Files::FILEW &serr, char const*const*argv1, bool helpp) { class SerrResetter { public: SerrResetter(GenBuffer::Writable *old_serr_): old_serr(old_serr_) {} ~SerrResetter() { Error::serr = old_serr; } private: GenBuffer::Writable *old_serr; } serr_resetter(Error::serr); Error::serr=&serr; /* --- Parse arguments, generate/read .job file */ MiniPS::VALUE job=MiniPS::Qundef; Filter::FlatD bts(bts_ttt); ufd=(Filter::UngetFILED*)NULLP; if (!helpp && argv1[0]!=(char const*)NULLP && argv1[1]==(char const*)NULLP) { /* A single argument: must be the name of the .job file */ MiniPS::Parser p(argv1[0]); p.addSpecRun("%bts", &bts); /* bts: Built-in TemplateS, the bts.ttt file in the sources */ job=p.parse1(); if (p.parse1(p.EOF_ALLOWED)!=MiniPS::Qundef) Error::sev(Error::EERROR) << "job: the .job file should contain a single job" << (Error*)0; /* ^^^ Dat: the result of the second p.parse1() doesn't get delete0(...)d */ } else if (helpp || argv1[0]==(char const*)NULLP) { help: /* help message */ sout << "Usage: " << Error::long_argv0 << " \n" << " " << Error::long_argv0 << " [options] [OutputFormat:] \n" << "Example: " << Error::long_argv0 << " test.gif EPS: test.eps\n"; if (helpp) Error::cexit(Error::runCleanups(0)); Error::sev(Error::EERROR) << "Incorrect command line" << (Error*)0; } else { /* one_liner */ SimBuffer::B jobss; if (one_liner(jobss, argv1)) goto help; if (do_DisplayJobFile) displayJob(sout, jobss); Filter::FlatD jobr(jobss(), jobss.getLength()); MiniPS::Parser p(&jobr); p.addSpecRun("%bts", &bts); /* bts: Built-in TemplateS, the bts.ttt file in the sources */ if (MiniPS::Qerror==(job=p.parse1(p.EOF_ILLEGAL, Error::ERROR_CONT)) || p.parse1(p.EOF_ALLOWED)!=MiniPS::Qundef ) { displayJob(sout, jobss); Error::sev(Error::EERROR) << "job: in-memory .job file corrupt (bug?" "?)" << (Error*)0; /* ^^^ Dat: the result of the second p.parse1() doesn't get delete0(...)d */ } } Files::doSignalCleanup(); /* --- Pre-parse .job file */ /* Dat: memory storage for the MiniPS objects in the .job file are * allocated by p.parse1() and freed by MiniPS::delete0(job). Other * structures throughout this program hold pointers to inside `job', * but storage is not copied. */ MiniPS::String *InputFile, *OutputFile, *LoadHints; MiniPS::Array *Profile; MiniPS::VALUE TmpRemove; MiniPS::scanf_dict(job, /*show_warnings:*/true, "InputFile", MiniPS::T_STRING, MiniPS::Qundef, &InputFile, "OutputFile", MiniPS::T_STRING, MiniPS::Qundef, &OutputFile, "LoadHints", MiniPS::T_STRING, MiniPS::Qnull, &LoadHints, "Templates", MiniPS::T_DICT, MiniPS::Qnull, &Rule::Templates, "Profile", MiniPS::T_ARRAY, MiniPS::Qundef, &Profile, "TmpRemove", MiniPS::T_BOOLEAN,MiniPS::Qtrue, &TmpRemove, /* remove temporary files upon exit? */ NULLP ); // MiniPS::dump(sout, job, 1); Files::tmpRemove=TmpRemove==MiniPS::Qtrue; if (MiniPS::Qnull==(MiniPS::VALUE)Rule::Templates) { Filter::FlatD flatd("<< (%bts) run >>"); MiniPS::Parser p(&flatd); p.addSpecRun("%bts", &bts); Rule::Templates=(MiniPS::Dict*)p.parse1(); MiniPS::RDICT(job)->put("/Templates", (MiniPS::VALUE)Rule::Templates); /* avoid memory leak (job gets freed recursively) */ } /* --- Preprocess Appliers */ Rule::OutputRule *rule_list=Rule::buildProfile((MiniPS::VALUE)Profile, buildProfile_quiet); /* --- Read/open other files */ if ((MiniPS::VALUE)LoadHints==MiniPS::Qnull) { /* smart default */ if (!rule_list[0].isEOL() && rule_list[0].cache.Compression==Rule::Cache::CO_JAI) { LoadHints=new MiniPS::String("jpeg-asis",4); /* used by in_jai.cpp and in_jpeg.cpp; even TIFF/JPEG */ } else { LoadHints=new MiniPS::String("",0); } MiniPS::RDICT(job)->put("/LoadHints", (MiniPS::VALUE)LoadHints); /* avoid memory leak (job gets freed recursively) */ } /* Imp: eliminate memory leak from default LoadHints */ /* vvv may raise tons of error messages */ // InputFile->term0(); /* always term0() for MiniPS::String */ if (ufd==NULLP) ufd=new Filter::UngetFILED(InputFile->begin_(), stdin, Filter::UngetFILED::CM_closep|Filter::UngetFILED::CM_keep_stdinp); // fprintf(stderr, "ufd=%p\n", ufd); Image::SampledInfo info(Image::load( #if 0 InputFile->begin_(), /* knows about stdin `-' */ SimBuffer::B(",",1, LoadHints->begin_(),LoadHints->getLength(), ",",1 ).term0() /* three-way concatentation */ #else (Image::Loader::UFD*)ufd, SimBuffer::B(",",1, LoadHints->begin_(),LoadHints->getLength(), ",",1 ).term0(), /* three-way concatentation */ /*format:*/(char const*)NULLP #endif )); Error::sev(Error::NOTICE) << "job: read InputFile: " << FNQ2STDOK(InputFile->begin_(),InputFile->getLength()) << (Error*)0; delete ufd; // assert(0); bool overwrite=false; if (0==strcmp(InputFile->begin_(), OutputFile->begin_()) && 0!=strcmp("-", InputFile->begin_())) { // Error::sev(Error::WARNING) << "job: InputFile == OutputFile" << (Error*)0; OutputFile->replace(OutputFile->begin_(), OutputFile->getLength(), ".s2new", 6); overwrite=true; } FILE *of=stdout; if (OutputFile->getLength()!=1 || OutputFile->begin_()[0]!='-') { if ((of=fopen(OutputFile->begin_(), "wb"))==(FILE*)NULLP) { Error::sev(Error::EERROR) << "job: cannot rewrite OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; } /*if (!overwrite)*/ Files::tmpRemoveCleanup(OutputFile->begin_(), &of); } else Files::set_binary_mode(1, true); /* --- Find and apply best applier */ Files::FILEW wf(of); Rule::applyProfile(wf, rule_list, &info); /* --- Done, flush files and clean up. */ fflush(of); if (ferror(of)) { /* FILE *backup=of; of=(FILE*)NULLP; fclose(backup); */ Error::sev(Error::EERROR) << "job: error writing OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; } if (of!=stdout) { /* Don't interfere with tmpRemoveCleanup() */ FILE *backup=of; of=(FILE*)NULLP; fclose(backup); } if (overwrite) { if (0!=rename(OutputFile->begin_(), InputFile->begin_())) { // remove(OutputFile->begin_()); /* tmpRemoveCleanup() does it */ Error::sev(Error::EERROR) << "job: error renaming, InputFile left intact" << (Error*)0; } } Error::sev(Error::NOTICE) << "job: written OutputFile: " << FNQ2STDOK(OutputFile->begin_(),OutputFile->getLength()) << (Error*)0; /* Freeing memory may cause segfaults because of possibly * bad code design :-(. Luckily we have already saved the output file. */ Rule::deleteProfile(rule_list); MiniPS::delete0(job); /* frees OutputFile etc. */ bool successp = Error::getTopPrinted()+0<=Error::NOTICE+0; int exitCode = Error::runCleanups(0); fflush(stdout); fflush(stderr); if (successp && exitCode == 0) fputs("Success.\n", stderr); /* Don't do Error::cexit(exitCode);, it won't run destructors of * stack-allocated objects, and valgrind will complain about memory leaks. */ return exitCode; } /** main: process entry point for the sam2p utility. */ int main(int, char const*const* argv) { Files::FILEW sout(stdout); Files::FILEW serr(stderr); /* --- Initialize */ bool helpp=argv[0]==(char const*)NULLP || (argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && argv[2]==(char const*)NULLP && ( option_eq(argv[1], "-help") || option_eq(argv[1], "-h") || option_eq(argv[1], "-?") || option_eq(argv[1], "/h") || option_eq(argv[1], "/?"))); bool versionp=argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && argv[2]==(char const*)NULLP && ( option_eq(argv[1], "-version") || option_eq(argv[1], "-v")); bool quietp=argv[0]!=(char const*)NULLP && argv[1]!=(char const*)NULLP && option_eq(argv[1], "-j:quiet"); init_sam2p_engine(argv[0]); if (versionp) { sout << "This is " << Error::banner0 << ".\n"; return 0; } /* Don't print diagnostics to stdout, becuse it might be the OutputFile */ if (!quietp) { serr << "This is " << Error::banner0 << ".\n"; } init_loader(); if (!quietp) { serr << "Available Loaders:"; Image::printLoaders(serr); serr << ".\n"; } init_applier(); if (!quietp) { serr << "Available Appliers:"; Rule::printAppliers(serr); serr << ".\n"; } return run_sam2p_engine( sout, serr, argv+(argv[0]!=(char const*)NULLP), helpp); } sam2p-0.49.2/Makehelp.in0000644000175100017510000000026512211371426013110 0ustar ptsptsCXX=@CXX@ LDXX=@LDXX@ CXXFLAGS=-DHAVE_CONFIG2_H @CXXFLAGS@ CXXFLAGSB=@CXXFLAGSB@ ENABLE_DEBUG=@ENABLE_DEBUG@ GFLAG=@GFLAG@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sam2p-0.49.2/pts_lzw.c0000644000175100017510000012165512211371426012707 0ustar ptspts#define DUMMY \ set -ex; \ g++ -DNDEBUG=1 -O3 -ansi -pedantic \ -Wall -W -Wstrict-prototypes -Wtraditional -Wnested-externs -Winline \ -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \ -Wmissing-declarations pts_lzw.c -c; \ exit /* pts_lzw.c -- a real, effective implementation of PostScript * LanguageLevel2 and PDF /LZWEncode and /LZWDecode filters (same as the LZW * compression used in TIFF raster image files) * * based on tif_lzw.c in libtiff-v3.4beta037 by Sam Leffler and Silicon Graphics. * by pts@fazekas.hu at Sun Dec 30 15:04:19 CET 2001 * encoding and decoding works at Sun Dec 30 17:05:23 CET 2001 * modified for sam2p at Mon Mar 4 00:21:59 CET 2002 * * Note that the LZW compression (but not uncompression) is patented by * Unisys (patent number #4,558,302), so use this program at your own legal * risk! * * Predictors and PostScript LanguageLevel3 filter options are not supported. * * Test: linux-2.2.8.tar.gz * -- uncompressed: 58 388 480 bytes * -- LZWEncode (lzw_codec.c): 26 518 397 bytes (uncompression OK) * -- FlateEncode (almost gzip): 13 808 890 bytes (uncompression: zcat) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Imp: check #ifdef _WINDOWS */ /* Dat: a strip is an interval of rows. Each strip -- probably except for the * last -- has a same number of rows. Strips are useful for TIFF writers * to better organize data in memory or disk. */ #ifdef __GNUC__ #pragma implementation #endif #if _MSC_VER > 1000 # undef __PROTOTYPES__ # define __PROTOTYPES__ 1 # pragma warning(disable: 4127) /* conditional expression is constant */ # pragma warning(disable: 4244) /* =' : conversion from 'int ' to 'unsigned char ', possible loss of data */ #endif /* Original: /d1/sam/tiff/libtiff/RCS/tif_lzw.c,v 1.73 1997/08/29 21:45:54 sam Exp */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ /**** pts ****/ #if OBJDEP # warning PROVIDES: pts_lzw #endif #define LZW_SUPPORT 1 #if 0 /* conflicts with some system defs */ typedef unsigned short u_short; typedef unsigned char u_char; typedef unsigned long u_long; #endif #define TO_RDONLY 1 #define _TIFFmalloc malloc #define _TIFFfree free #define _TIFFmemset memset #include #include /* * ``Library-private'' definitions. */ /* * TIFF I/O Library Definitions. */ /* * Tag Image File Format (TIFF) * * Based on Rev 6.0 from: * Developer's Desk * Aldus Corporation * 411 First Ave. South * Suite 200 * Seattle, WA 98104 * 206-622-5500 */ #define TIFF_VERSION 42 /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, * - items marked with a ! are introduced in revision 6.0. * - items marked with a % are introduced post revision 6.0. * - items marked with a $ are obsoleted by revision 6.0. */ /* --- */ /* * This define can be used in code that requires * compilation-related definitions specific to a * version or versions of the library. Runtime * version checking should be done based on the * string returned by TIFFGetVersion. */ #define TIFFLIB_VERSION 19970127 /* January 27, 1997 */ /* * The following typedefs define the intrinsic size of * data types used in the *exported* interfaces. These * definitions depend on the proper definition of types * in tiff.h. Note also that the varargs interface used * to pass tag types and values uses the types defined in * tiff.h directly. * * NB: ttag_t is unsigned int and not unsigned short because * ANSI C requires that the type before the ellipsis be a * promoted type (i.e. one of int, unsigned int, pointer, * or double) and because we defined pseudo-tags that are * outside the range of legal Aldus-assigned tags. * NB: tsize_t is int32 and not uint32 because some functions * return -1. * NB: toff_t is not off_t for many reasons; TIFFs max out at * 32-bit file offsets being the most important */ #ifndef NULL #define NULL 0 #endif typedef struct pts_lzw_state TIFF; #include "pts_lzw.h" /**** pts ****/ static int TIFFInitLZW(TIFF*); static void TIFFError(char const*a, char const*b); #if 0 /**** pts ****/ static void TIFFWarning(char const*a, char const*b, int c); void TIFFWarning(char const*a, char const*b, int c) { fprintf(stderr, "Warning: %s: ", a); fprintf(stderr, b, c); fprintf(stderr, "\n"); } #endif static int TIFFAppendTo(TIFF*, tidataval_t*, tsize_t); /* tif_write.h */ #if 0 static void TIFFReverseBits(unsigned char *, unsigned long); #endif #ifdef LZW_SUPPORT /* * TIFF Library. * Rev 5.0 Lempel-Ziv & Welch Compression Support * * This code is derived from the compress program whose code is * derived from software contributed to Berkeley by James A. Woods, * derived from original work by Spencer Thomas and Joseph Orost. * * The original Berkeley copyright notice appears below in its entirety. */ #include /* #include */ /* * Internal version of TIFFFlushData that can be * called by ``encodestrip routines'' w/o concern * for infinite recursion. */ static int TIFFFlushData1(TIFF* tif) { if (tif->tif_rawcc > 0) { #if 0 if (tif->tif_revbits_p) TIFFReverseBits((unsigned char *)tif->tif_rawdata, tif->tif_rawcc); #endif if (!TIFFAppendTo(tif, /* isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, */ tif->tif_rawdata, tif->tif_rawcc)) return (0); tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; } return (1); } /* * NB: The 5.0 spec describes a different algorithm than Aldus * implements. Specifically, Aldus does code length transitions * one code earlier than should be done (for real LZW). * Earlier versions of this library implemented the correct * LZW algorithm, but emitted codes in a bit order opposite * to the TIFF spec. Thus, to maintain compatibility w/ Aldus * we interpret MSB-LSB ordered codes to be images written w/ * old versions of this library, but otherwise adhere to the * Aldus "off by one" algorithm. * * Future revisions to the TIFF spec are expected to "clarify this issue". */ #define LZW_COMPAT /* include backwards compatibility code */ /* * Each strip of data is supposed to be terminated by a CODE_EOI. * If the following #define is included, the decoder will also * check for end-of-strip w/o seeing this code. This makes the * library more robust, but also slower. */ #define LZW_CHECKEOS /* include checks for strips w/o EOI code */ #undef LZW_CHECKEOS /**** pts ****/ #define MAXCODE(n) ((1L<<(n))-1) /* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. */ #define BITS_MIN 9 /* start with 9 bits */ #define BITS_MAX 12 /* max of 12 bit strings */ /* predefined codes */ #define CODE_CLEAR 256 /* code to clear string table */ #define CODE_EOI 257 /* end-of-information code */ #define CODE_FIRST 258 /* first free code entry */ #define CODE_MAX MAXCODE(BITS_MAX) #define HSIZE 9001L /* 91% occupancy */ #define HSHIFT (13-8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ #define CSIZE (MAXCODE(BITS_MAX)+1024L) #else #define CSIZE (MAXCODE(BITS_MAX)+1L) #endif /* * State block for each open TIFF file using LZW * compression/decompression. Note that the predictor * state block must be first in this data structure. */ typedef struct { #if 0 /****pts****/ TIFFPredictorState predict; /* predictor super class */ #endif unsigned short nbits; /* # of bits/code */ unsigned short maxcode; /* maximum code for lzw_nbits */ unsigned short free_ent; /* next free entry in hash table */ long nextdata; /* next bits of i/o */ long nextbits; /* # of valid bits in lzw_nextdata */ } LZWBaseState; #define lzw_nbits base.nbits #define lzw_maxcode base.maxcode #define lzw_free_ent base.free_ent #define lzw_nextdata base.nextdata #define lzw_nextbits base.nextbits /* * Decoding-specific state. */ typedef struct code_ent { struct code_ent *next; unsigned short length; /* string len, including this token */ unsigned char value; /* data value */ unsigned char firstchar; /* first token of string */ } code_t; typedef int (*decodeFunc)(TIFF*, tidataval_t*, tsize_t); typedef struct { LZWBaseState base; long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ long dec_restart; /* restart count */ #ifdef LZW_CHECKEOS long dec_bitsleft; /* available bits in raw data */ #endif decodeFunc dec_decode; /* regular or backwards compatible */ code_t* dec_codep; /* current recognized code */ code_t* dec_oldcodep; /* previously recognized code */ code_t* dec_free_entp; /* next free entry */ code_t* dec_maxcodep; /* max available entry */ code_t* dec_codetab; /* kept separate for small machines */ } LZWDecodeState; /* * Encoding-specific state. */ typedef unsigned short hcode_t; /* codes fit in 16 bits */ typedef struct { long hash; hcode_t code; } hash_t; typedef struct { LZWBaseState base; int enc_oldcode; /* last code encountered */ long enc_checkpoint; /* point at which to clear table */ #define CHECK_GAP 10000 /* enc_ratio check interval */ long enc_ratio; /* current compression ratio */ long enc_incount; /* (input) data bytes encoded */ long enc_outcount; /* encoded (output) bytes */ tidataval_t* enc_rawlimit; /* bound on tif_rawdata buffer */ hash_t* enc_hashtab; /* kept separate for small machines */ } LZWEncodeState; #define LZWState(tif) ((LZWBaseState*) (void*) (tif)->tif_data) #define DecoderState(tif) ((LZWDecodeState*)(void*) LZWState(tif)) #define EncoderState(tif) ((LZWEncodeState*)(void*) LZWState(tif)) /* ^^^ Dat: (void*) -> suppress gcc warning from -Wcast-align */ static void cl_hash(LZWEncodeState*); #if 0 /**** pts ****/ /* LZW decoder is not needed */ static int LZWDecode(TIFF*, tidataval_t*, tsize_t); #ifdef LZW_COMPAT static int LZWDecodeCompat(TIFF*, tidataval_t*, tsize_t); #endif /* * LZW Decoder. */ #ifdef LZW_CHECKEOS /* * This check shouldn't be necessary because each * strip is suppose to be terminated with CODE_EOI. */ #define NextCode(_tif, _sp, _bp, _code, _get) { \ if ((_sp)->dec_bitsleft < nbits) { \ TIFFWarning(_tif->tif_name, \ "LZWDecode: Strip %d not terminated with EOI code", \ /*_tif->tif_curstrip*/ 0); \ _code = CODE_EOI; \ } else { \ _get(_sp,_bp,_code); \ (_sp)->dec_bitsleft -= nbits; \ } \ } #else #define NextCode(tif, sp, bp, code, get) get(sp, bp, code) #endif static int LZWSetupDecode(TIFF* tif) { LZWDecodeState* sp = DecoderState(tif); static const char module[] = " LZWSetupDecode"; int code; assert(sp != NULL); if (sp->dec_codetab == NULL) { sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t)); if (sp->dec_codetab == NULL) { TIFFError(module, "No space for LZW code table"); return (0); } /* * Pre-load the table. */ for (code = 255; code >= 0; code--) { sp->dec_codetab[code].value = code; sp->dec_codetab[code].firstchar = code; sp->dec_codetab[code].length = 1; sp->dec_codetab[code].next = NULL; } } return (1); } /* * Setup state for decoding a strip. */ static int LZWPreDecode(TIFF* tif) { LZWDecodeState *sp = DecoderState(tif); assert(sp != NULL); /* * Check for old bit-reversed codes. */ if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { #ifdef LZW_COMPAT if (!sp->dec_decode) { TIFFWarning(tif->tif_name, "Old-style LZW codes, convert file %d", 0); #if 0 /**** pts ****/ /* * Override default decoding methods with * ones that deal with the old coding. * Otherwise the predictor versions set * above will call the compatibility routines * through the dec_decode method. */ tif->tif_decoderow = LZWDecodeCompat; tif->tif_decodestrip = LZWDecodeCompat; tif->tif_decodetile = LZWDecodeCompat; /* * If doing horizontal differencing, must * re-setup the predictor logic since we * switched the basic decoder methods... */ (*tif->tif_setupdecode)(tif); #endif LZWSetupDecode(tif); sp->dec_decode = LZWDecodeCompat; } sp->lzw_maxcode = MAXCODE(BITS_MIN); #else /* !LZW_COMPAT */ if (!sp->dec_decode) { TIFFError(tif->tif_name, "Old-style LZW codes not supported"); sp->dec_decode = LZWDecode; } return (0); #endif/* !LZW_COMPAT */ } else { sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; sp->dec_decode = LZWDecode; } sp->lzw_nbits = BITS_MIN; sp->lzw_nextbits = 0; sp->lzw_nextdata = 0; sp->dec_restart = 0; sp->dec_nbitsmask = MAXCODE(BITS_MIN); #ifdef LZW_CHECKEOS sp->dec_bitsleft = tif->tif_rawcc << 3; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; /* * Zero entries that are not yet filled in. We do * this to guard against bogus input data that causes * us to index into undefined entries. If you can * come up with a way to safely bounds-check input codes * while decoding then you can remove this operation. */ _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); sp->dec_oldcodep = &sp->dec_codetab[-1]; sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; return (1); } /* * Decode a "hunk of data". */ #define GetNextCode(sp, bp, code) { \ nextdata = (nextdata<<8) | *(bp)++; \ nextbits += 8; \ if (nextbits < nbits) { \ nextdata = (nextdata<<8) | *(bp)++; \ nextbits += 8; \ } \ code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \ nextbits -= nbits; \ } static void codeLoop(TIFF* tif) { TIFFError(tif->tif_name, "LZWDecode: Bogus encoding, loop in the code table; scanline %d" /*,tif->tif_row*/); } static int LZWDecode(TIFF* tif, tidataval_t* op0, tsize_t occ0) { LZWDecodeState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; char *tp; unsigned char *bp; hcode_t code; int len; long nbits, nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; assert(sp != NULL); /* * Restart interrupted output operation. */ if (sp->dec_restart) { long residue; codep = sp->dec_codep; residue = codep->length - sp->dec_restart; if (residue > occ) { /* * Residue from previous decode is sufficient * to satisfy decode request. Skip to the * start of the decoded string, place decoded * values in the output buffer, and return. */ sp->dec_restart += occ; do { codep = codep->next; } while (--residue > occ && codep); if (codep) { tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ && codep); } return occ0-occ; } /* * Residue satisfies only part of the decode request. */ op += residue, occ -= residue; tp = op; do { int t; --tp; t = codep->value; codep = codep->next; *tp = t; } while (--residue && codep); sp->dec_restart = 0; } bp = (unsigned char *)tif->tif_rawcp; /* reading from here */ nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; nbitsmask = sp->dec_nbitsmask; oldcodep = sp->dec_oldcodep; free_entp = sp->dec_free_entp; maxcodep = sp->dec_maxcodep; while (occ > 0 && bptif_rawend /**** pts ****/) { NextCode(tif, sp, bp, code, GetNextCode); #if 0 if (bp>tif->tif_rawend) fprintf(stderr, "over %d\n", tif->tif_rawend-bp); assert(bp<=tif->tif_rawend); #endif if (code == CODE_EOI) break; if (code == CODE_CLEAR) { free_entp = sp->dec_codetab + CODE_FIRST; nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = sp->dec_codetab + nbitsmask-1; #if 1 /**** pts ****/ NextCode(tif, sp, bp, code, GetNextCode); if (code == CODE_EOI) break; *op++ = code, occ--; oldcodep = sp->dec_codetab + code; /* ! */ #endif continue; } codep = sp->dec_codetab + code; /* * Add the new entry to the code table. */ assert(&sp->dec_codetab[0] <= free_entp && free_entp < &sp->dec_codetab[CSIZE]); free_entp->next = oldcodep; free_entp->firstchar = free_entp->next->firstchar; free_entp->length = free_entp->next->length+1; free_entp->value = (codep < free_entp) ? codep->firstchar : free_entp->firstchar; if (++free_entp > maxcodep) { if (++nbits > BITS_MAX) /* should not happen */ nbits = BITS_MAX; nbitsmask = MAXCODE(nbits); maxcodep = sp->dec_codetab + nbitsmask-1; } oldcodep = codep; if (code >= 256) { /* * Code maps to a string, copy string * value to output (written in reverse). */ if (codep->length > occ) { /* * String is too long for decode buffer, * locate portion that will fit, copy to * the decode buffer, and setup restart * logic for the next decoding call. */ sp->dec_codep = codep; do { codep = codep->next; } while (codep && codep->length > occ); if (codep) { sp->dec_restart = occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ && codep); if (codep) { codeLoop(tif); return -1; } } break; } len = codep->length; tp = op + len; do { int t; --tp; t = codep->value; codep = codep->next; *tp = t; } while (codep && tp > op); if (codep) { codeLoop(tif); return -1; /* break; */ } op += len, occ -= len; } else *op++ = code, occ--; } tif->tif_rawcp = (tidataval_t*) bp; sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->dec_nbitsmask = nbitsmask; sp->dec_oldcodep = oldcodep; sp->dec_free_entp = free_entp; sp->dec_maxcodep = maxcodep; #if 0 /**** pts ****/ if (occ > 0) { TIFFError(tif->tif_name, "LZWDecode: Not enough data at scanline %d (short %d bytes)" /*,tif->tif_row, occ*/); return (0); } #endif return occ0-occ; } #ifdef LZW_COMPAT /* * Decode a "hunk of data" for old images. */ #define GetNextCodeCompat(sp, bp, code) { \ nextdata |= (unsigned long) *(bp)++ << nextbits; \ nextbits += 8; \ if (nextbits < nbits) { \ nextdata |= (unsigned long) *(bp)++ << nextbits; \ nextbits += 8; \ } \ code = (hcode_t)(nextdata & nbitsmask); \ nextdata >>= nbits; \ nextbits -= nbits; \ } static int LZWDecodeCompat(TIFF* tif, tidataval_t* op0, tsize_t occ0) { LZWDecodeState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; char *tp; unsigned char *bp; int code, nbits; long nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; assert(0); assert(sp != NULL); /* * Restart interrupted output operation. */ if (sp->dec_restart) { long residue; codep = sp->dec_codep; residue = codep->length - sp->dec_restart; if (residue > occ) { /* * Residue from previous decode is sufficient * to satisfy decode request. Skip to the * start of the decoded string, place decoded * values in the output buffer, and return. */ sp->dec_restart += occ; do { codep = codep->next; } while (--residue > occ); tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); return occ0-occ; } /* * Residue satisfies only part of the decode request. */ op += residue, occ -= residue; tp = op; do { *--tp = codep->value; codep = codep->next; } while (--residue); sp->dec_restart = 0; } bp = (unsigned char *)tif->tif_rawcp; nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; nbitsmask = sp->dec_nbitsmask; oldcodep = sp->dec_oldcodep; free_entp = sp->dec_free_entp; maxcodep = sp->dec_maxcodep; while (occ > 0 && bptif_rawend) { NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; if (code == CODE_CLEAR) { free_entp = sp->dec_codetab + CODE_FIRST; nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = sp->dec_codetab + nbitsmask; NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; *op++ = code, occ--; oldcodep = sp->dec_codetab + code; continue; } codep = sp->dec_codetab + code; /* * Add the new entry to the code table. */ assert(&sp->dec_codetab[0] <= free_entp && free_entp < &sp->dec_codetab[CSIZE]); free_entp->next = oldcodep; free_entp->firstchar = free_entp->next->firstchar; free_entp->length = free_entp->next->length+1; free_entp->value = (codep < free_entp) ? codep->firstchar : free_entp->firstchar; if (++free_entp > maxcodep) { if (++nbits > BITS_MAX) /* should not happen */ nbits = BITS_MAX; nbitsmask = MAXCODE(nbits); maxcodep = sp->dec_codetab + nbitsmask; } oldcodep = codep; if (code >= 256) { /* * Code maps to a string, copy string * value to output (written in reverse). */ if (codep->length > occ) { /* * String is too long for decode buffer, * locate portion that will fit, copy to * the decode buffer, and setup restart * logic for the next decoding call. */ sp->dec_codep = codep; do { codep = codep->next; } while (codep->length > occ); sp->dec_restart = occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); break; } op += codep->length, occ -= codep->length; tp = op; do { *--tp = codep->value; } while (0!=(codep = codep->next)); } else *op++ = code, occ--; } tif->tif_rawcp = (tidataval_t*) bp; sp->lzw_nbits = nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->dec_nbitsmask = nbitsmask; sp->dec_oldcodep = oldcodep; sp->dec_free_entp = free_entp; sp->dec_maxcodep = maxcodep; #if 0 /**** pts ****/ if (occ > 0) { TIFFError(tif->tif_name, "LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)" /*,tif->tif_row, occ*/); return (0); } #endif return occ0-occ; } #endif /* LZW_COMPAT */ #endif /**** pts ****/ /* --- */ /* * LZW Encoding. */ static int LZWSetupEncode(TIFF* tif) { LZWEncodeState* sp = EncoderState(tif); static const char module[] = "LZWSetupEncode"; assert(sp != NULL); sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t)); if (sp->enc_hashtab == NULL) { TIFFError(module, "No space for LZW hash table"); return (0); } return (1); } /* * Reset encoding state at the start of a strip. */ static int LZWPreEncode(TIFF* tif) { LZWEncodeState *sp = EncoderState(tif); assert(sp != NULL); sp->lzw_nbits = BITS_MIN; sp->lzw_maxcode = MAXCODE(BITS_MIN); sp->lzw_free_ent = CODE_FIRST; sp->lzw_nextbits = 0; sp->lzw_nextdata = 0; sp->enc_checkpoint = CHECK_GAP; sp->enc_ratio = 0; sp->enc_incount = 0; sp->enc_outcount = 0; /* * The 4 here insures there is space for 2 max-sized * codes in LZWEncode and LZWPostDecode. */ sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; cl_hash(sp); /* clear hash table */ sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */ return (1); } #define CALCRATIO(sp, rat) { \ if (incount > 0x007fffff) { /* NB: shift will overflow */\ rat = outcount >> 8; \ rat = (rat == 0 ? 0x7fffffff : incount/rat); \ } else \ rat = (incount<<8) / outcount; \ } #define PutNextCode(op, c) { \ nextdata = (nextdata << nbits) | c; \ nextbits += nbits; \ *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ nextbits -= 8; \ if (nextbits >= 8) { \ *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ nextbits -= 8; \ } \ outcount += nbits; \ } /* * Encode a chunk of pixels. * * Uses an open addressing double hashing (no chaining) on the * prefix code/next character combination. We do a variant of * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's * relatively-prime secondary probe. Here, the modular division * first probe is gives way to a faster exclusive-or manipulation. * Also do block compression with an adaptive reset, whereby the * code table is cleared when the compression ratio decreases, * but after the table fills. The variable-length output codes * are re-sized at this point, and a CODE_CLEAR is generated * for the decoder. */ static int LZWEncode(TIFF* tif, tidataval_t* bp, tsize_t cc) { register LZWEncodeState *sp = EncoderState(tif); register long fcode; register hash_t *hp; register int h, c; hcode_t ent; long disp; long incount, outcount, checkpoint; long nextdata, nextbits; int free_ent, maxcode, nbits; tidataval_t* op, *limit; if (sp == NULL) return (0); /* * Load local state. */ incount = sp->enc_incount; outcount = sp->enc_outcount; checkpoint = sp->enc_checkpoint; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; free_ent = sp->lzw_free_ent; maxcode = sp->lzw_maxcode; nbits = sp->lzw_nbits; op = tif->tif_rawcp; limit = sp->enc_rawlimit; ent = sp->enc_oldcode; if (ent == (hcode_t) -1 && cc > 0) { /* * NB: This is safe because it can only happen * at the start of a strip where we know there * is space in the data buffer. */ PutNextCode(op, CODE_CLEAR); ent = *bp++; cc--; incount++; } while (cc > 0) { c = *bp++; cc--; incount++; fcode = ((long)c << BITS_MAX) + ent; h = (c << HSHIFT) ^ ent; /* xor hashing */ #ifdef _WINDOWS /* ?? */ /* * Check hash index for an overflow. */ if (h >= HSIZE) h -= HSIZE; #endif hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) { ent = hp->code; continue; } if (hp->hash >= 0) { /* * Primary hash failed, check secondary hash. */ disp = HSIZE - h; if (h == 0) disp = 1; do { /* * Avoid pointer arithmetic 'cuz of * wraparound problems with segments. */ if ((h -= disp) < 0) h += HSIZE; hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) { ent = hp->code; goto hit; } } while (hp->hash >= 0); } /* * New entry, emit code and add to table. */ /* * Verify there is space in the buffer for the code * and any potential Clear code that might be emitted * below. The value of limit is setup so that there * are at least 4 bytes free--room for 2 codes. */ if (op > limit) { tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); TIFFFlushData1(tif); op = tif->tif_rawdata; } PutNextCode(op, ent); ent = c; hp->code = free_ent++; hp->hash = fcode; if (free_ent == CODE_MAX-1) { /* table is full, emit clear code and reset */ cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else { /* * If the next entry is going to be too big for * the code size, then increase it, if possible. */ if (free_ent > maxcode) { nbits++; assert(nbits <= BITS_MAX); maxcode = (int) MAXCODE(nbits); } else if (incount >= checkpoint) { long rat; /* * Check compression ratio and, if things seem * to be slipping, clear the hash table and * reset state. The compression ratio is a * 24+8-bit fractional number. */ checkpoint = incount+CHECK_GAP; CALCRATIO(sp, rat); if (rat <= sp->enc_ratio) { cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else sp->enc_ratio = rat; } } hit: ; } /* * Restore global state. */ sp->enc_incount = incount; sp->enc_outcount = outcount; sp->enc_checkpoint = checkpoint; sp->enc_oldcode = ent; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->lzw_free_ent = free_ent; sp->lzw_maxcode = maxcode; sp->lzw_nbits = nbits; tif->tif_rawcp = op; return (1); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int LZWPostEncode(TIFF* tif) { register LZWEncodeState *sp = EncoderState(tif); tidataval_t* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { /* fprintf(stderr, "Yupp!\n"); */ tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); TIFFFlushData1(tif); op = tif->tif_rawdata; } if (sp->enc_oldcode != (hcode_t) -1) { /* fprintf(stderr, "EIK\n"); */ PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = (hcode_t) -1; } PutNextCode(op, CODE_EOI); if (nextbits > 0) *op++ = (unsigned char)(nextdata << (8-nextbits)); tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); return (1); } /* * Reset encoding hash table. */ static void cl_hash(LZWEncodeState* sp) { register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; register long i = HSIZE-8; do { i -= 8; hp[-7].hash = -1; hp[-6].hash = -1; hp[-5].hash = -1; hp[-4].hash = -1; hp[-3].hash = -1; hp[-2].hash = -1; hp[-1].hash = -1; hp[ 0].hash = -1; hp -= 8; } while (i >= 0); for (i += 8; i > 0; i--, hp--) hp->hash = -1; } static void LZWCleanup(TIFF* tif) { if (tif->tif_data) { if (tif->tif_reading_p) { if (DecoderState(tif)->dec_codetab) _TIFFfree(DecoderState(tif)->dec_codetab); } else { if (EncoderState(tif)->enc_hashtab) _TIFFfree(EncoderState(tif)->enc_hashtab); } _TIFFfree(tif->tif_data); tif->tif_data = NULL; } } static int TIFFInitLZW(TIFF* tif) { /* assert(scheme == COMPRESSION_LZW); */ /* * Allocate state block so tag methods have storage to record values. */ if (tif->tif_reading_p) { tif->tif_data = (tidataval_t*) _TIFFmalloc(sizeof (LZWDecodeState)); if (tif->tif_data == NULL) goto bad; DecoderState(tif)->dec_codetab = NULL; DecoderState(tif)->dec_decode = NULL; } else { tif->tif_data = (tidataval_t*) _TIFFmalloc(sizeof (LZWEncodeState)); if (tif->tif_data == NULL) goto bad; EncoderState(tif)->enc_hashtab = NULL; } #if 0 /**** pts ****/ /* * Install codec methods. */ tif->tif_setupdecode = LZWSetupDecode; tif->tif_predecode = LZWPreDecode; tif->tif_decoderow = LZWDecode; tif->tif_decodestrip = LZWDecode; tif->tif_decodetile = LZWDecode; tif->tif_setupencode = LZWSetupEncode; tif->tif_preencode = LZWPreEncode; tif->tif_postencode = LZWPostEncode; tif->tif_encoderow = LZWEncode; tif->tif_encodestrip = LZWEncode; tif->tif_encodetile = LZWEncode; tif->tif_cleanup = LZWCleanup; #endif #if 0 /**** pts ****/ /* * Setup predictor setup. */ (void) TIFFPredictorInit(tif); #endif return (1); bad: TIFFError("TIFFInitLZW", "No space for LZW state block"); return (0); } /* * Copyright (c) 1985, 1986 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * James A. Woods, derived from original work by Spencer Thomas * and Joseph Orost. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #endif /* LZW_SUPPORT */ #if 0 #ifdef __cplusplus extern "C" #else extern #endif FILE *fdopen (int fildes, const char *mode); /* POSIX, but not ANSI */ #else #undef _POSIX_SOURCE #define _POSIX_SOURCE 1 #undef _POSIX_C_SOURCE /* Sat Jun 1 14:25:53 CEST 2002 */ #define _POSIX_C_SOURCE 2 #include #endif #if 0 /**** pts: never needed, because output FillOrder is always 1 */ void TIFFReverseBits(register unsigned char* cp, register unsigned long n) { char *TIFFBitRevTable=...; /**** pts ****/ for (; n > 8; n -= 8) { cp[0] = TIFFBitRevTable[cp[0]]; cp[1] = TIFFBitRevTable[cp[1]]; cp[2] = TIFFBitRevTable[cp[2]]; cp[3] = TIFFBitRevTable[cp[3]]; cp[4] = TIFFBitRevTable[cp[4]]; cp[5] = TIFFBitRevTable[cp[5]]; cp[6] = TIFFBitRevTable[cp[6]]; cp[7] = TIFFBitRevTable[cp[7]]; cp += 8; } while (n-- > 0) *cp = TIFFBitRevTable[*cp], cp++; } #endif static void TIFFError(char const*a, char const*b) { fprintf(stderr, "%s: %s\n", a, b); } static int TIFFAppendTo(TIFF*tif, tidataval_t* data, tsize_t cc) { (void)tif; (void)data; (void)cc; /* fwrite(data, 1, cc, (FILE*)tif->tif_sout); if (ferror((FILE*)tif->tif_sout)) return 0; */ if (-1==tif->tif_writer((char*)data, cc, tif->tif_sout)) return 0; #if 0 /**** pts ****/ /* tif_write.h */ (void)strip; TIFFDirectory *td = &tif->tif_dir; static const char module[] = "TIFFAppendToStrip"; if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) { /* * No current offset, set the current strip. */ if (td->td_stripoffset[strip] != 0) { if (!SeekOK(tif, td->td_stripoffset[strip])) { TIFFError(module, "%s: Seek error at scanline %lu", tif->tif_name, (unsigned long) tif->tif_row); return (0); } } else td->td_stripoffset[strip] = TIFFSeekFile(tif, (toff_t) 0, SEEK_END); tif->tif_curoff = td->td_stripoffset[strip]; } if (!WriteOK(tif, data, cc)) { TIFFError(module, "%s: Write error at scanline %lu", tif->tif_name, (unsigned long) tif->tif_row); return (0); } tif->tif_curoff += cc; td->td_stripbytecount[strip] += cc; #endif return (1); } #if 0 static tidataval_t readbuf[4096]; unsigned int readlen; static char *inname; typedef int (*filter_t)(FILE *sin, FILE*sout); /** /LZWEncode filter, STDIN -> STDOUT */ static int lzw_encode(FILE *sin, FILE *sout) { TIFF tif; tif.tif_sout=sout; tif.tif_reading_p=0; #if 0 tif.tif_revbits_p=0; #endif tif.tif_name=inname; tif.tif_rawdata=(tidataval_t*)_TIFFmalloc(tif.tif_rawdatasize=4096); /* Imp: check */ tif.tif_rawcp=tif.tif_rawdata; tif.tif_rawcc=0; if (TIFFInitLZW(&tif) && LZWSetupEncode(&tif) && LZWPreEncode(&tif) /* for each strip */) { while ((readlen=fread(readbuf, 1, sizeof(readbuf), sin))!=0) { if (!LZWEncode(&tif, readbuf, readlen)) goto err; /* fprintf(stderr, "readlen=%d\n", readlen); */ } if (!LZWPostEncode(&tif)) goto err; /* for each strip */ LZWCleanup(&tif); if (!TIFFFlushData1(&tif)) { _TIFFfree(tif.tif_rawdata); fflush(sout); return 0; } fflush(sout); } else { err: fflush(sout); LZWCleanup(&tif); _TIFFfree(tif.tif_rawdata); return 0; } return 1; } /** /LZWEncode filter, STDIN -> STDOUT */ static int lzw_decode(FILE *sin, FILE *sout) { TIFF tif; /* tidataval_t *rawend0; */ /* char *xbuf; */ int got; unsigned int left; tif.tif_reading_p=1; #if 0 tif.tif_revbits_p=0; #endif tif.tif_name=inname; tif.tif_rawdata=(tidataval_t*)_TIFFmalloc(tif.tif_rawdatasize=4096); /* Imp: check */ tif.tif_rawcc=0; left=0; if (TIFFInitLZW(&tif) && LZWSetupDecode(&tif) && LZWPreDecode(&tif) /* for each strip */) { /* vvv Dat: fread returns >=0 ! */ while ((readlen=left+fread(tif.tif_rawdata+left, 1, tif.tif_rawdatasize-left, sin))!=0) { #if DEBUGMSG fprintf(stderr, "readlen+=%d\n", readlen); #endif while (readlen<=3) { if ((got=fread(tif.tif_rawdata+readlen, 1, tif.tif_rawdatasize-readlen, sin))==0) { tif.tif_rawend=tif.tif_rawdata+readlen; goto star; } readlen+=got; } tif.tif_rawend=tif.tif_rawdata+readlen-3; star: tif.tif_rawcp=tif.tif_rawdata; #if DEBUGMSG fprintf(stderr, "readlen:=%d\n", readlen); #endif while (1) { if (-1==(got=(DecoderState(&tif)->dec_decode)(&tif, readbuf, sizeof(readbuf)))) goto err; #if DEBUGMSG fprintf(stderr, "OK, written: %d %d\n", got, tif.tif_rawend-tif.tif_rawcp); #endif if (0==got) break; fwrite(readbuf, 1, got, sout); } left=tif.tif_rawdata+readlen-tif.tif_rawcp; got=left; #if DEBUGMSG fprintf(stderr, "left=%d\n", left); fflush(stderr); #endif while (got--!=0) { tif.tif_rawdata[got]=tif.tif_rawcp[got]; } } #if 0 if (!LZWPostDecode(&tif)) { LZWCleanup(&tif); return 0; } /* for each strip */ #endif LZWCleanup(&tif); fflush(sout); } else { err: fflush(sout); LZWCleanup(&tif); _TIFFfree(tif.tif_rawdata); return 0; } return 1; } #endif static int feeder(char *readbuf, unsigned readlen, TIFF *tif) { /*(void)LZWPreDecode;*/ /* Imp: better avoid gcc warning... */ if (readlen!=0) { if (!LZWEncode(tif, (tidataval_t*)readbuf, readlen)) { e1: LZWCleanup(tif); e2: _TIFFfree(tif->tif_rawdata); return 0; } } else { if (!LZWPostEncode(tif)) goto e1; LZWCleanup(tif); if (!TIFFFlushData1(tif)) goto e2; } return 1; } /** /LZWEncode filter, STDIN -> STDOUT */ int pts_lzw_init(TIFF *tif) { /* tif_sout and tif_writer are already filled */ tif->tif_feeder=feeder; tif->tif_reading_p=0; #if 0 tif->tif_revbits_p=0; #endif tif->tif_name="//.filter";/*inname;*/ tif->tif_rawdata=(tidataval_t*)_TIFFmalloc(tif->tif_rawdatasize=4096); /* Imp: check */ tif->tif_rawcp=tif->tif_rawdata; tif->tif_rawcc=0; if (TIFFInitLZW(tif) && LZWSetupEncode(tif) && LZWPreEncode(tif) /* for each strip */) { return 1; } LZWCleanup(tif); _TIFFfree(tif->tif_rawdata); return 0; } #if 0 /**** pts ****/ int main(int argc, char **argv) { filter_t filter; FILE *sin, *sout; inname="STDIN"; if (argc>=2 && argc<=4 && argv[1][0]=='e') { filter=lzw_encode; } else if (argc>=2 && argc<=4 && argv[1][0]=='d') { filter=lzw_decode; } else { fprintf(stderr, "This is PotterSoftware LZW codec v0.1, (C) pts@fazekas.hu in Late Dec 2001\n" "THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!\n" "This program is free software, covered by the GNU GPL.\n" " Derived from code Copyright (c) 1988-1997 Sam Leffler\n" " Derived from code Copyright (c) 1991-1997 Silicon Graphics, Inc.\n\n" "Usage: %s encode|decode [INFILE] [OUTFILE]\n\n" "Unspecified file names mean STDIN or STDOUT.\n" "Encoding is /LZWEncode compression, decoding is /LZWDecode uncompression.\n\n" "Note that the LZW compression (but not uncompression) is patented by\n" "Unisys (patent number #4,558,302), so use this program at your own legal\n" "risk!\n" ,argv[0]); return 2; } if (argc>=3) sin= fopen(inname=argv[2],"rb"); else sin= fdopen(0, "rb"); if (sin==0) { fprintf(stderr, "%s: error opening infile\n", argv[0]); return 3; } if (argc>=4) sout=fopen(inname=argv[3],"wb"); else sout=fdopen(1, "wb"); if (sout==0) { fprintf(stderr, "%s: error opening outfile\n", argv[0]); return 4; } return !filter(sin, sout); /* fclose(sout); fclose(sin); */ } #endif sam2p-0.49.2/mkdist.sh0000755000175100017510000000542012211371426012662 0ustar ptspts#! /bin/bash -- # # mkdist.sh by pts@fazekas.hu at Wed Mar 6 09:09:01 CET 2002 # added debian/changelog support at Fri Mar 5 19:37:45 CET 2004 # added libevhdns Makefile.in support at Sun Apr 25 12:24:43 CEST 2010 # based on mkdist.sh of autotrace # if test "$1" = --cd; then MYDIR="${0%/*}" test "$MYDIR" || MYDIR=. cd "$MYDIR" fi # Get the release version number. if test -f debian/changelog; then # PRODUCT_AND_VERSION=$PRODUCT-$VERSION PRODUCT_AND_VERSION="`&2 exit 4 fi elif test -f Makefile.in && grep '^product-and-version:' /dev/null; then PRODUCT_AND_VERSION="`make SHELL=/bin/bash -f Makefile.in product-and-version`" if test "$?" != 0 || test -z "$PRODUCT_AND_VERSION"; then echo "$0: couldn't determine version from Makefile.in" >&2 exit 7 fi else echo "$0: missing: debian/changelog or RELEASE= in Makefile.in" >&2 exit 2 fi if test "$1" = --getversion; then echo "${PRODUCT_AND_VERSION##*-}" exit fi echo "Creating distfile in $PWD" # Get the list of files. if test -f files; then FILES="`cat files`" elif test -d CVS; then FILES=$( IFS=' ' find -type d -name CVS | while read D; do F="$D/Entries" export E="${D%/CVS}/" E="${E#./}" perl -ne 'print"$ENV{E}$1\n"if m@^/([^/]+)/[1-9]@' <"$F" done) else echo "$0: missing: files or **/CVS/Entries" >&2 exit 3 fi if test -e "$PRODUCT_AND_VERSION"; then echo "$0: directory $PRODUCT_AND_VERSION already exists, remove it first" >&2 exit 5 fi if test $# -gt 0; then TGZ_NAME="$1.tar.gz"; shift else TGZ_NAME="$PRODUCT_AND_VERSION.tar.gz" fi set -e # exit on error rm -f "../$TGZ_NAME" mkdir "$PRODUCT_AND_VERSION" (IFS=' '; exec tar -c -- $FILES "$@") | (cd "$PRODUCT_AND_VERSION" && exec tar -xv) # ^^^ tar(1) magically calls mkdir(2) etc. # vvv Dat: don't include sam2p-.../ in the filenames of the .tar.gz #(IFS=' #'; cd "$PRODUCT_AND_VERSION" && exec tar -czf "../../$TGZ_NAME" -- $FILES "$@") # vvv Dat: do include sam2p-.../ in the filenames of the .tar.gz (IFS=' '; export PRODUCT_AND_VERSION; exec tar -czf "../$TGZ_NAME" -- `echo "$FILES" | perl -pe '$_="$ENV{PRODUCT_AND_VERSION}/$_"'` "$@") rm -rf "$PRODUCT_AND_VERSION" set +e if test -s "../$TGZ_NAME"; then :; else echo "$0: failed to create distfile: ../$TGZ_NAME" >&2 exit 6 fi FULL_TGZ_NAME="`cd ..;echo "$PWD/$TGZ_NAME"`" echo "Created distfile: $FULL_TGZ_NAME" if type -p pts-xclip >/dev/null; then echo -n "$FULL_TGZ_NAME" | pts-xclip -i echo -n "$FULL_TGZ_NAME" | pts-xclip -i -selection clipboard echo "Name of distfile added to the X11 primary + clipboard." fi # __EOF__ sam2p-0.49.2/input-bmp.ci0000644000175100017510000003200112212351433013250 0ustar ptspts/* This code is ripped from Autotrace-0.29. Small modifications by pts. */ /* input-bmp.ci: reads any bitmap I could get for testing */ #ifdef __GNUC__ #pragma implementation #endif #include #include #include /* #include "types.h" */ #include "at_bitmap.h" /* #include "message.h" */ /* #include "xstd.h" */ /* #include "input-bmp.h" */ #define MAXCOLORS 256 /* #define Image long */ #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) #define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0) struct Bitmap_File_Head_Struct { char zzMagic[2]; /* 00 "BM" */ unsigned long bfSize; /* 02 */ unsigned short zzHotX; /* 06 */ unsigned short zzHotY; /* 08 */ unsigned long bfOffs; /* 0A */ unsigned long biSize; /* 0E */ } Bitmap_File_Head; struct Bitmap_Head_Struct { unsigned long biWidth; /* 12 */ unsigned long biHeight; /* 16 */ unsigned short biPlanes; /* 1A */ unsigned short biBitCnt; /* 1C */ unsigned long biCompr; /* 1E */ unsigned long biSizeIm; /* 22 */ unsigned long biXPels; /* 26 */ unsigned long biYPels; /* 2A */ unsigned long biClrUsed; /* 2E */ unsigned long biClrImp; /* 32 */ /* 36 */ } Bitmap_Head; static long ToL (unsigned char *); static short ToS (unsigned char *); static int ReadColorMap (FILE *, unsigned char[256][3], int, int, int *); static unsigned char *ReadImage (FILE *, int, int, unsigned char[256][3], int, int, int, int); #if PTS_SAM2P bitmap_type bmp_load_image (FILE* filename) #else bitmap_type bmp_load_image (at_string filename) #endif { FILE *fd; unsigned char buffer[64]; int ColormapSize, rowbytes, Maps=0, Grey; unsigned char ColorMap[256][3]; bitmap_type image; #if PTS_SAM2P /**** pts ****/ fd=filename; #else fd = fopen (filename, "rb"); if (!fd) FATAL1 ("Can't open \"%s\"\n", filename); #endif /* It is a File. Now is it a Bitmap? Read the shortest possible header.*/ if (!ReadOK(fd, buffer, 18) || (strncmp((const char *)buffer,"BM",2))) #if PTS_SAM2P /**** pts ****/ FATALP ("BMP: Not a valid BMP file"); #else FATAL ("Not a valid BMP file %s\n"); #endif /* bring them to the right byteorder. Not too nice, but it should work */ Bitmap_File_Head.bfSize = ToL (&buffer[0x02]); Bitmap_File_Head.zzHotX = ToS (&buffer[0x06]); Bitmap_File_Head.zzHotY = ToS (&buffer[0x08]); Bitmap_File_Head.bfOffs = ToL (&buffer[0x0a]); Bitmap_File_Head.biSize = ToL (&buffer[0x0e]); /* What kind of bitmap is it? */ if (Bitmap_File_Head.biSize == 12) /* OS/2 1.x ? */ { if (!ReadOK (fd, buffer, 8)) FATALP ("BMP: Error reading BMP file header #1"); Bitmap_Head.biWidth = ToS (&buffer[0x00]); /* 12 */ Bitmap_Head.biHeight = ToS (&buffer[0x02]); /* 14 */ Bitmap_Head.biPlanes = ToS (&buffer[0x04]); /* 16 */ Bitmap_Head.biBitCnt = ToS (&buffer[0x06]); /* 18 */ Bitmap_Head.biCompr = 0; Bitmap_Head.biSizeIm = 0; Bitmap_Head.biXPels = Bitmap_Head.biYPels = 0; Bitmap_Head.biClrUsed = 0; Maps = 3; } else if (Bitmap_File_Head.biSize == 40) /* Windows 3.x */ { if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4)) FATALP ("BMP: Error reading BMP file header #2"); Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */ Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */ Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */ Bitmap_Head.biBitCnt =ToS (&buffer[0x0A]); /* 1C */ Bitmap_Head.biCompr =ToL (&buffer[0x0C]); /* 1E */ Bitmap_Head.biSizeIm =ToL (&buffer[0x10]); /* 22 */ Bitmap_Head.biXPels =ToL (&buffer[0x14]); /* 26 */ Bitmap_Head.biYPels =ToL (&buffer[0x18]); /* 2A */ Bitmap_Head.biClrUsed =ToL (&buffer[0x1C]); /* 2E */ Bitmap_Head.biClrImp =ToL (&buffer[0x20]); /* 32 */ /* 36 */ Maps = 4; } else if (Bitmap_File_Head.biSize <= 64) /* Probably OS/2 2.x */ { if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4)) FATALP ("BMP: Error reading BMP file header #3"); Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */ Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */ Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */ Bitmap_Head.biBitCnt =ToS (&buffer[0x0A]); /* 1C */ Bitmap_Head.biCompr =ToL (&buffer[0x0C]); /* 1E */ Bitmap_Head.biSizeIm =ToL (&buffer[0x10]); /* 22 */ Bitmap_Head.biXPels =ToL (&buffer[0x14]); /* 26 */ Bitmap_Head.biYPels =ToL (&buffer[0x18]); /* 2A */ Bitmap_Head.biClrUsed =ToL (&buffer[0x1C]); /* 2E */ Bitmap_Head.biClrImp =ToL (&buffer[0x20]); /* 32 */ /* 36 */ Maps = 3; } else FATALP ("BMP: Error reading BMP file header #4"); /* Valid options 1, 4, 8, 16, 24, 32 */ /* 16 is awful, we should probably shoot whoever invented it */ /* There should be some colors used! */ ColormapSize = (Bitmap_File_Head.bfOffs - Bitmap_File_Head.biSize - 14) / Maps; if ((Bitmap_Head.biClrUsed == 0) && (Bitmap_Head.biBitCnt <= 8)) Bitmap_Head.biClrUsed = ColormapSize; /* Sanity checks */ if (Bitmap_Head.biHeight == 0 || Bitmap_Head.biWidth == 0) FATALP ("BMP: Error reading BMP file header #5"); if (Bitmap_Head.biPlanes != 1) FATALP ("BMP: Error reading BMP file header #6"); if (ColormapSize > 256 || Bitmap_Head.biClrUsed > 256) FATALP ("BMP: Error reading BMP file header #7"); /* Windows and OS/2 declare filler so that rows are a multiple of * word length (32 bits == 4 bytes) */ rowbytes= ( (Bitmap_Head.biWidth * Bitmap_Head.biBitCnt - 1) / 32) * 4 + 4; #ifdef DEBUG printf("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n", Bitmap_File_Head.bfSize,Bitmap_Head.biClrUsed,Bitmap_Head.biBitCnt,Bitmap_Head.biWidth, Bitmap_Head.biHeight, Bitmap_Head.biCompr, rowbytes); #endif /* Get the Colormap */ if (ReadColorMap (fd, ColorMap, ColormapSize, Maps, &Grey) == -1) FATALP ("BMP: Cannot read the colormap"); #ifdef DEBUG printf("Colormap read\n"); #endif /* Get the Image and return the ID or -1 on error*/ image.bitmap = ReadImage (fd, Bitmap_Head.biWidth, Bitmap_Head.biHeight, ColorMap, Bitmap_Head.biBitCnt, Bitmap_Head.biCompr, rowbytes, Grey); BITMAP_WIDTH (image) = (at_dimen_t) Bitmap_Head.biWidth; BITMAP_HEIGHT (image) = (at_dimen_t) Bitmap_Head.biHeight; BITMAP_PLANES (image) = Grey ? 1 : 3; return (image); } static int ReadColorMap (FILE *fd, unsigned char buffer[256][3], int number, int size, int *grey) { int i; unsigned char rgb[4]; *grey=(number>2); for (i = 0; i < number ; i++) { if (!ReadOK (fd, rgb, size)) FATALP ("BMP: Bad colormap"); /* Bitmap save the colors in another order! But change only once! */ buffer[i][0] = rgb[2]; buffer[i][1] = rgb[1]; buffer[i][2] = rgb[0]; *grey = ((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2])); } return 0; } static unsigned char* ReadImage (FILE *fd, int width, int height, unsigned char cmap[256][3], int bpp, int compression, int rowbytes, int grey) { unsigned char v,howmuch; int xpos = 0, ypos = 0; unsigned char *image; unsigned char *temp, *buffer; long rowstride, channels; unsigned short rgb; int i, j; if (bpp >= 16) /* color image */ { XMALLOCT (image, unsigned char*, width * height * 3 * sizeof (unsigned char)); channels = 3; } else if (grey) /* grey image */ { XMALLOCT (image, unsigned char*, width * height * 1 * sizeof (unsigned char)); channels = 1; } else /* indexed image */ { XMALLOCT (image, unsigned char*, width * height * 1 * sizeof (unsigned char)); channels = 1; } XMALLOCT (buffer, unsigned char*, rowbytes); rowstride = width * channels; ypos = height - 1; /* Bitmaps begin in the lower left corner */ switch (bpp) { case 32: { while (ReadOK (fd, buffer, rowbytes)) { temp = image + (ypos * rowstride); for (xpos= 0; xpos < width; ++xpos) { *(temp++)= buffer[xpos * 4 + 2]; *(temp++)= buffer[xpos * 4 + 1]; *(temp++)= buffer[xpos * 4]; } --ypos; /* next line */ } } break; case 24: { while (ReadOK (fd, buffer, rowbytes)) { temp = image + (ypos * rowstride); for (xpos= 0; xpos < width; ++xpos) { *(temp++)= buffer[xpos * 3 + 2]; *(temp++)= buffer[xpos * 3 + 1]; *(temp++)= buffer[xpos * 3]; } --ypos; /* next line */ } } break; case 16: { while (ReadOK (fd, buffer, rowbytes)) { temp = image + (ypos * rowstride); for (xpos= 0; xpos < width; ++xpos) { rgb= ToS(&buffer[xpos * 2]); *(temp++)= (unsigned char)(((rgb >> 10) & 0x1f) * 8); *(temp++)= (unsigned char)(((rgb >> 5) & 0x1f) * 8); *(temp++)= (unsigned char)(((rgb) & 0x1f) * 8); } --ypos; /* next line */ } } break; case 8: case 4: case 1: { if (compression == 0) { while (ReadOK (fd, &v, 1)) { for (i = 1; (i <= (8 / bpp)) && (xpos < width); i++, xpos++) { temp = (unsigned char*) (image + (ypos * rowstride) + (xpos * channels)); *temp= (unsigned char)(( v & ( ((1<> (8-(i*bpp))); } if (xpos == width) { (void) ReadOK (fd, buffer, rowbytes - 1 - (width * bpp - 1) / 8); ypos--; xpos = 0; } if (ypos < 0) break; } break; } else { while (ypos >= 0 && xpos <= width) { (void) ReadOK (fd, buffer, 2); if ((unsigned char) buffer[0] != 0) /* Count + Color - record */ { for (j = 0; ((unsigned char) j < (unsigned char) buffer[0]) && (xpos < width);) { #ifdef DEBUG2 printf("%u %u | ",xpos,width); #endif for (i = 1; ((i <= (8 / bpp)) && (xpos < width) && ((unsigned char) j < (unsigned char) buffer[0])); i++, xpos++, j++) { temp = image + (ypos * rowstride) + (xpos * channels); *temp = (unsigned char) ((buffer[1] & (((1<> (8 - (i * bpp))); } } } if (((unsigned char) buffer[0] == 0) && ((unsigned char) buffer[1] > 2)) /* uncompressed record */ { howmuch = buffer[1]; for (j = 0; j < howmuch; j += (8 / bpp)) { (void) ReadOK (fd, &v, 1); i = 1; while ((i <= (8 / bpp)) && (xpos < width)) { temp = image + (ypos * rowstride) + (xpos * channels); *temp = (unsigned char) ((v & (((1<> (8-(i*bpp))); i++; xpos++; } } if ((howmuch % 2) && (bpp==4)) howmuch++; if ((howmuch / (8 / bpp)) % 2) (void) ReadOK (fd, &v, 1); /*if odd(x div (8 div bpp )) then blockread(f,z^,1);*/ } if (((unsigned char) buffer[0] == 0) && ((unsigned char) buffer[1]==0)) /* Line end */ { ypos--; xpos = 0; } if (((unsigned char) buffer[0]==0) && ((unsigned char) buffer[1]==1)) /* Bitmap end */ { break; } if (((unsigned char) buffer[0]==0) && ((unsigned char) buffer[1]==2)) /* Deltarecord */ { (void) ReadOK (fd, buffer, 2); xpos += (unsigned char) buffer[0]; ypos -= (unsigned char) buffer[1]; } } break; } } break; default: /* This is very bad, we should not be here */ ; } /* fclose (fd); */ if (bpp <= 8) { unsigned char *temp2, *temp3; unsigned char index; temp2 = temp = image; XMALLOCT (image, unsigned char*, width * height * 3 * sizeof (unsigned char)); temp3 = image; for (ypos = 0; ypos < height; ypos++) { for (xpos = 0; xpos < width; xpos++) { index = *temp2++; *temp3++ = cmap[index][0]; if (!grey) { *temp3++ = cmap[index][1]; *temp3++ = cmap[index][2]; } } } free (temp); } free (buffer); return image; } #if 0 /**** pts ****/ FILE *errorfile; char *prog_name = "bmp"; char *filename; int interactive_bmp; #endif static long ToL (unsigned char *puffer) { return (puffer[0] | puffer[1]<<8 | puffer[2]<<16 | puffer[3]<<24); } static short ToS (unsigned char *puffer) { return ((short)(puffer[0] | puffer[1]<<8)); } sam2p-0.49.2/input-pnm.ci0000644000175100017510000003165512211371426013305 0ustar ptspts/* This code is ripped from Autotrace-0.29. Small modifications by pts. */ /* input-pnm.ci: * The pnm reading and writing code was written from scratch by Erik Nygren * (nygren@mit.edu) based on the specifications in the man pages and * does not contain any code from the netpbm or pbmplus distributions. */ #ifdef __GNUC__ #pragma implementation #endif /* #include "types.h" */ #include "at_bitmap.h" /* #include "input-pnm.h" */ /* #include "message.h" */ /* #include "xstd.h" */ /* #include -- ceil(); emulated */ #include /* atoi(...) */ /**** pts ****/ /* #include */ #define isspace(c) ((c)=='\0' || (c)==' ' || ((unsigned char)((c)-011)<=(unsigned char)(015-011))) /* ^^^ not strictly POSIX C locale */ #define isdigit(c) ((unsigned char)(c-'0')<=(unsigned char)('9'-'0')) #if 0 # define FILEE FILE # define fread_FILEE(s,slen,f) fread(s, 1, slen, f) #else # define FILEE /*Filter::UngetFILED*/GenBuffer::Readable # define fread_FILEE(s,slen,f) f->vi_read(s, slen) #endif /* Declare local data types */ typedef struct _PNMScanner { FILEE *fd; /* The file descriptor of the file being read */ char cur; /* The current character in the input stream */ int eof; /* Have we reached end of file? */ } PNMScanner; typedef struct _PNMInfo { unsigned int xres, yres; /* The size of the image */ int maxval; /* For ascii image files, the max value * which we need to normalize to */ int np; /* Number of image planes (0 for pbm) */ int asciibody; /* 1 if ascii body, 0 if raw body */ /* Routine to use to load the pnm body */ void (* loader) (PNMScanner *, struct _PNMInfo *, unsigned char *); } PNMInfo; /* Contains the information needed to write out PNM rows */ typedef struct _PNMRowInfo { FILEE *fd; /* File descriptor */ char *rowbuf; /* Buffer for writing out rows */ int xres; /* X resolution */ int np; /* Number of planes */ unsigned char *red; /* Colormap red */ unsigned char *grn; /* Colormap green */ unsigned char *blu; /* Colormap blue */ } PNMRowInfo; /* Save info */ typedef struct { int raw; /* raw or ascii */ } PNMSaveVals; typedef struct { int run; /* run */ } PNMSaveInterface; #define BUFLEN 512 /* The input buffer size for data returned * from the scanner. Note that lines * aren't allowed to be over 256 characters * by the spec anyways so this shouldn't * be an issue. */ #define SAVE_COMMENT_STRING "# CREATOR: The GIMP's PNM Filter Version 1.0\n" /* Declare some local functions. */ static void pnm_load_ascii (PNMScanner *scan, PNMInfo *info, unsigned char *pixel_rgn); static void pnm_load_raw (PNMScanner *scan, PNMInfo *info, unsigned char *pixel_rgn); static void pnm_load_rawpbm (PNMScanner *scan, PNMInfo *info, unsigned char *pixel_rgn); static void pnmscanner_destroy (PNMScanner *s); #if 0 static void pnmscanner_createbuffer (PNMScanner *s, unsigned int bufsize); static void pnmscanner_getchar (PNMScanner *s); static void pnmscanner_getsmalltoken (PNMScanner *s, unsigned char *buf); #endif static void pnmscanner_eatwhitespace (PNMScanner *s); static void pnmscanner_gettoken (PNMScanner *s, unsigned char *buf, unsigned int bufsize); static unsigned pnmscanner_getint(PNMScanner *s); static PNMScanner * pnmscanner_create (FILEE *fd); #define pnmscanner_eof(s) ((s)->eof) #define pnmscanner_fd(s) ((s)->fd) #if 0 /* pnmscanner_getchar --- * Reads a character from the input stream */ static void pnmscanner_getchar (PNMScanner *s) { if (s->inbuf) { s->cur = s->inbuf[s->inbufpos++]; if (s->inbufpos >= s->inbufvalidsize) { if (s->inbufsize > s->inbufvalidsize) s->eof = 1; else s->inbufvalidsize = fread(s->inbuf, 1, s->inbufsize, s->fd); s->inbufpos = 0; } } else s->eof = !fread(&(s->cur), 1, 1, s->fd); } #endif #define pnmscanner_getchar(s) do { s->eof = !fread_FILEE(&(s->cur), 1, s->fd); } while(0) /* pnmscanner_eatwhitespace --- * Eats up whitespace from the input and returns when done or eof. * Also deals with comments. */ static inline void pnmscanner_eatwhitespace(PNMScanner *s) { /**** pts ****/ while (1) { if (s->cur=='#') { do pnmscanner_getchar(s); while (s->cur!='\n'); } else if (!isspace(s->cur)) { break; } pnmscanner_getchar(s); } } static struct struct_pnm_types { char name; int np; int asciibody; int maxval; void (* loader) (PNMScanner *, struct _PNMInfo *, unsigned char *pixel_rgn); } pnm_types[] = { { '1', 0, 1, 1, pnm_load_ascii }, /* ASCII PBM */ { '2', 1, 1, 255, pnm_load_ascii }, /* ASCII PGM */ { '3', 3, 1, 255, pnm_load_ascii }, /* ASCII PPM */ { '4', 0, 0, 1, pnm_load_rawpbm }, /* RAW PBM */ { '5', 1, 0, 255, pnm_load_raw }, /* RAW PGM */ { '6', 3, 0, 255, pnm_load_raw }, /* RAW PPM */ { 0 , 0, 0, 0, NULL} }; #if PTS_SAM2P bitmap_type pnm_load_image (FILEE* filename) #else bitmap_type pnm_load_image (at_string filename) #endif { char buf[BUFLEN]; /* buffer for random things like scanning */ PNMInfo *pnminfo; PNMScanner * volatile scan; int ctr; FILEE* fd; bitmap_type bitmap; #if PTS_SAM2P /**** pts ****/ fd=filename; #else /* open the file */ fd = xfopen (filename, "rb"); if (fd == NULL) { FATAL("PNM: can't open file\n"); BITMAP_BITS (bitmap) = NULL; BITMAP_WIDTH (bitmap) = 0; BITMAP_HEIGHT (bitmap) = 0; BITMAP_PLANES (bitmap) = 0; return (bitmap); } #endif /* allocate the necessary structures */ /* pnminfo = (PNMInfo *) malloc (sizeof (PNMInfo)); */ XMALLOCTU(pnminfo, PNMInfo); scan = NULL; /* set error handling */ scan = pnmscanner_create(fd); /* Get magic number */ pnmscanner_gettoken (scan, (unsigned char *)buf, BUFLEN); if (pnmscanner_eof(scan)) FATALP ("PNM: premature end of file"); if (buf[0] != 'P' || buf[2]) FATALP ("PNM: is not a valid file"); /* Look up magic number to see what type of PNM this is */ for (ctr=0; pnm_types[ctr].name; ctr++) if (buf[1] == pnm_types[ctr].name) { pnminfo->np = pnm_types[ctr].np; pnminfo->asciibody = pnm_types[ctr].asciibody; pnminfo->maxval = pnm_types[ctr].maxval; pnminfo->loader = pnm_types[ctr].loader; } if (!pnminfo->loader) FATALP ("PNM: file not in a supported format"); pnmscanner_gettoken(scan, (unsigned char *)buf, BUFLEN); if (pnmscanner_eof(scan)) FATALP ("PNM: premature end of file"); pnminfo->xres = isdigit(*buf)?atoi(buf):0; if (pnminfo->xres<=0) FATALP ("PNM: invalid xres while loading"); pnmscanner_gettoken(scan, (unsigned char *)buf, BUFLEN); if (pnmscanner_eof(scan)) FATALP ("PNM: premature end of file"); pnminfo->yres = isdigit(*buf)?atoi(buf):0; if (pnminfo->yres<=0) FATALP ("PNM: invalid yres while loading"); if (pnminfo->np != 0) /* pbm's don't have a maxval field */ { pnmscanner_gettoken(scan, (unsigned char *)buf, BUFLEN); if (pnmscanner_eof(scan)) FATALP ("PNM: premature end of file"); pnminfo->maxval = isdigit(*buf)?atoi(buf):0; if ((pnminfo->maxval<=0) || (pnminfo->maxval>255 && !pnminfo->asciibody)) FATALP ("PNM: invalid maxval while loading"); } BITMAP_WIDTH (bitmap) = (at_dimen_t) pnminfo->xres; BITMAP_HEIGHT (bitmap) = (at_dimen_t) pnminfo->yres; BITMAP_PLANES (bitmap) = (pnminfo->np)?(pnminfo->np):1; /* BITMAP_BITS (bitmap) = (unsigned char *) malloc (pnminfo->yres * pnminfo->xres * BITMAP_PLANES (bitmap)); */ XMALLOCT(BITMAP_BITS (bitmap), unsigned char *, pnminfo->yres * pnminfo->xres * BITMAP_PLANES (bitmap)); pnminfo->loader (scan, pnminfo, BITMAP_BITS (bitmap)); /* vvv Dat: We detect truncation late truncated files will just have garbage :-( */ if (pnmscanner_eof(scan)) FATALP ("PNM: truncated image data"); /* Destroy the scanner */ pnmscanner_destroy (scan); /* free the structures */ /* free (pnminfo); */ XFREE(pnminfo); /* close the file */ /* xfclose (fd, filename); */ return (bitmap); } static void pnm_load_ascii (PNMScanner *scan, PNMInfo *info, unsigned char *data) { register unsigned char *d, *dend; unsigned u, s; #if 0 /**** pts ****/ /* Buffer reads to increase performance */ /* !! convert(1) is faster -- maybe buffering helps? */ pnmscanner_createbuffer(scan, 4096); #endif d = data; if (info->np==0) { /* PBM */ dend=d+info->xres*info->yres; while (d!=dend) { /* pnmscanner_getsmalltoken(scan, (unsigned char *)buf); */ pnmscanner_eatwhitespace(scan); *d++=-(scan->cur=='0'); pnmscanner_getchar(scan); } } else { /* PGM or PPM */ /**** pts ****/ dend=d+info->xres*info->yres*info->np; switch (s=info->maxval) { case 255: while (d!=dend) { *d++=pnmscanner_getint(scan); /* Dat: removed isdigit() */ } break; case 15: while (d!=dend) { *d++ = pnmscanner_getint(scan)*17; } break; case 3: while (d!=dend) { *d++ = pnmscanner_getint(scan)*85; } break; case 0: /* avoid division by 0 */ case 1: while (d!=dend) { *d++ = -(0==pnmscanner_getint(scan)); /* (*buf=='0')?0xff:0x00; */ } default: while (d!=dend) { u=pnmscanner_getint(scan); *d++ = (0UL+u*255UL+(s>>1))/s; /* always <= 255 */ } } } } static void pnm_load_raw (PNMScanner *scan, PNMInfo *info, unsigned char *data) { unsigned char *d, *dend; unsigned s=info->maxval; slen_t delta, scanlines; FILEE *fd=pnmscanner_fd(scan); scanlines = info->yres; d = data; delta=info->xres * info->np; dend=d+delta*scanlines; while (d!=dend) { if (info->xres*info->np != fread_FILEE((char*)d, delta, fd)) return; d+=delta; } d=data; switch (s=info->maxval) { /**** pts ****/ case 1: case 0: for (; d!=dend; d++) if (*d!=0) *d=255; break; case 3: while (d!=dend) *d++*=85; break; case 15: while (d!=dend) *d++*=17; break; case 255: break; default: for (; d!=dend; d++) *d=(0UL+*d*255UL+(s>>1))/s; /* always <= 255 */ break; } } static void pnm_load_rawpbm (PNMScanner *scan, PNMInfo *info, unsigned char *data) { unsigned char *buf; unsigned char curbyte; unsigned char *d; unsigned int x, i; unsigned int start, end, scanlines; FILEE *fd; unsigned int rowlen, bufpos; fd = pnmscanner_fd(scan); /****pts****/ /* rowlen = (unsigned int)ceil((double)(info->xres)/8.0);*/ rowlen=(info->xres+7)>>3; /* buf = (unsigned char *)malloc(rowlen*sizeof(unsigned char)); */ XMALLOCT(buf, unsigned char*, rowlen*sizeof(unsigned char)); start = 0; end = info->yres; scanlines = end - start; d = data; for (i = 0; i < scanlines; i++) { if (rowlen != fread_FILEE((char*)buf, rowlen, fd)) FATALP ("PNM: error reading file"); bufpos = 0; curbyte = buf[0]; for (x = 0; x < info->xres; x++) { if ((x % 8) == 0) { curbyte = buf[bufpos++]; /* // if (curbyte!=0) printf("%d <%u>\n", x, curbyte); */ } /* // if (curbyte!=0) printf("[%u]\n", curbyte); */ d[x] = (curbyte&0x80) ? 0x00 : 0xff; curbyte <<= 1; } d += info->xres; } XFREE(buf); } /**************** FILE SCANNER UTILITIES **************/ /* pnmscanner_create --- * Creates a new scanner based on a file descriptor. The * look ahead buffer is one character initially. */ static PNMScanner * pnmscanner_create (FILEE *fd) { PNMScanner *s; XMALLOCTU (s, PNMScanner); s->fd = fd; s->eof = !fread_FILEE(&(s->cur), 1, s->fd); return s; } /* pnmscanner_destroy --- * Destroys a scanner and its resources. Doesn't close the fd. */ static void pnmscanner_destroy (PNMScanner *s) { XFREE(s); } #if 0 /**** pts ****/ /* pnmscanner_createbuffer --- * Creates a buffer so we can do buffered reads. */ static void pnmscanner_createbuffer (PNMScanner *s, unsigned int bufsize) { /* s->inbuf = (char *)malloc(sizeof(char)*bufsize); */ XMALLOCT(s->inbuf, char*, sizeof(char)*bufsize); s->inbufsize = bufsize; s->inbufpos = 0; s->inbufvalidsize = fread(s->inbuf, 1, bufsize, s->fd); } #endif /* pnmscanner_gettoken --- * Gets the next token, eating any leading whitespace. */ static void pnmscanner_gettoken (PNMScanner *s, unsigned char *buf, unsigned int bufsize) { unsigned char *bufend=buf+bufsize-1; pnmscanner_eatwhitespace(s); while (!pnmscanner_eof(s) && !isspace(s->cur) && s->cur!='#') { if (buf!=bufend) *buf++=s->cur; pnmscanner_getchar(s); } *buf='\0'; } static unsigned pnmscanner_getint(PNMScanner *s) { unsigned ret=0; pnmscanner_eatwhitespace(s); while (!pnmscanner_eof(s)) { if (isdigit(s->cur)) ret=10*ret+s->cur-'0'; else if (isspace(s->cur) || s->cur=='#') break; pnmscanner_getchar(s); } return ret; } sam2p-0.49.2/input-tga.ci0000644000175100017510000003514212212351433013256 0ustar ptspts/* This code is ripped from Autotrace-0.29. Small modifications by pts. */ /* input-tga.ci reads tga files */ #ifdef __GNUC__ #pragma implementation #endif #include #include #include /* #include */ #include "at_bitmap.h" /* #include "message.h" */ /* #include "xstd.h" */ /* #include "input-tga.h" */ /* BUGFIX by pts: bmp -> tga */ /* TODO: - Handle loading images that aren't 8 bits per channel. */ /* Round up a division to the nearest integer. */ #define ROUNDUP_DIVIDE(n,d) (((n) + (d - 1)) / (d)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define INDEXED 1 #define INDEXEDA 2 #define GRAY 3 #define TGA_RGB 5 #define INDEXED_IMAGE 1 #define INDEXEDA_IMAGE 2 #define GRAY_IMAGE 3 #define GRAYA_IMAGE 4 #define TGA_RGB_IMAGE 5 #define TGA_RGBA_IMAGE 6 typedef struct _TgaSaveVals { int rle; } TgaSaveVals; typedef struct _TgaSaveInterface { int run; } TgaSaveInterface; struct tga_header { unsigned char idLength; unsigned char colorMapType; /* The image type. */ #define TGA_TYPE_MAPPED 1 #define TGA_TYPE_COLOR 2 #define TGA_TYPE_GRAY 3 #define TGA_TYPE_MAPPED_RLE 9 #define TGA_TYPE_COLOR_RLE 10 #define TGA_TYPE_GRAY_RLE 11 unsigned char imageType; /* Color Map Specification. */ /* We need to separately specify high and low bytes to avoid endianness and alignment problems. */ unsigned char colorMapIndexLo, colorMapIndexHi; unsigned char colorMapLengthLo, colorMapLengthHi; unsigned char colorMapSize; /* Image Specification. */ unsigned char xOriginLo, xOriginHi; unsigned char yOriginLo, yOriginHi; unsigned char widthLo, widthHi; unsigned char heightLo, heightHi; unsigned char bpp; /* Image descriptor. 3-0: attribute bpp 4: left-to-right ordering 5: top-to-bottom ordering 7-6: zero */ #define TGA_DESC_ABITS 0x0f #define TGA_DESC_HORIZONTAL 0x10 #define TGA_DESC_VERTICAL 0x20 unsigned char descriptor; }; #if 0 static struct { unsigned int extensionAreaOffset; unsigned int developerDirectoryOffset; #define TGA_SIGNATURE "TRUEVISION-XFILE" char signature[16]; char dot; char null; } tga_footer; #endif static bitmap_type ReadImage (FILE *fp, struct tga_header *hdr); #if PTS_SAM2P /**** pts ****/ bitmap_type tga_load_image (FILE* filename) #else bitmap_type tga_load_image (at_string filename) #endif { FILE *fp; struct tga_header hdr; bitmap_type image; image.bitmap = NULL; #if PTS_SAM2P /**** pts ****/ fp=filename; #else fp = fopen (filename, "rb"); if (!fp) FATAL1 ("TGA: can't open \"%s\"\n", filename); #endif memset(&hdr, '\0', sizeof(hdr)); #if 0 /* Check the footer. */ if (fseek (fp, 0L - (sizeof (tga_footer)), SEEK_END) || fread (&tga_footer, sizeof (tga_footer), 1, fp) != 1) #if PTS_SAM2P FATALP("TGA: Cannot read footer"); #else FATAL1 ("TGA: Cannot read footer from \"%s\"\n", filename); #endif /* Check the signature. */ if (fseek (fp, 0, SEEK_SET) || #else if (0 || #endif fread (&hdr, sizeof (hdr), 1, fp) != 1) #if PTS_SAM2P FATALP("TGA: Cannot read header"); #else FATAL1 ("TGA: Cannot read header from \"%s\"\n", filename); #endif /* Skip the image ID field. */ { #if 0 if (hdr.idLength && fseek (fp, hdr.idLength, SEEK_CUR)) #else char buf[256]; if (hdr.idLength!=fread(buf, 1, hdr.idLength, fp)) #endif #if PTS_SAM2P FATALP("TGA: Cannot skip ID field"); #else FATAL1 ("TGA: Cannot skip ID field in \"%s\"\n", filename); #endif } image = ReadImage (fp, &hdr); /* fclose (fp); */ return image; } static int std_fread (unsigned char *buf, int datasize, int nelems, FILE *fp) { return fread (buf, datasize, nelems, fp); } #define RLE_PACKETSIZE 0x80 /* Decode a bufferful of file. */ static int rle_fread (unsigned char *buf, int datasize, int nelems, FILE *fp) { static unsigned char *statebuf = 0; static int statelen = 0; static int laststate = 0; int j, k; int buflen, count, bytes; unsigned char *p; /* Scale the buffer length. */ buflen = nelems * datasize; j = 0; while (j < buflen) { if (laststate < statelen) { /* Copy bytes from our previously decoded buffer. */ bytes = MIN (buflen - j, statelen - laststate); memcpy (buf + j, statebuf + laststate, bytes); j += bytes; laststate += bytes; /* If we used up all of our state bytes, then reset them. */ if (laststate >= statelen) { laststate = 0; statelen = 0; } /* If we filled the buffer, then exit the loop. */ if (j >= buflen) break; } /* Decode the next packet. */ count = fgetc (fp); if (count == EOF) { return j / datasize; } /* Scale the byte length to the size of the data. */ bytes = ((count & ~RLE_PACKETSIZE) + 1) * datasize; if (j + bytes <= buflen) { /* We can copy directly into the image buffer. */ p = buf + j; } else { /* Allocate the state buffer if we haven't already. */ if (!statebuf) statebuf = (unsigned char *) malloc (RLE_PACKETSIZE * datasize); p = statebuf; } if (count & RLE_PACKETSIZE) { /* Fill the buffer with the next value. */ if (fread (p, datasize, 1, fp) != 1) { return j / datasize; } /* Optimized case for single-byte encoded data. */ if (datasize == 1) memset (p + 1, *p, bytes - 1); else for (k = datasize; k < bytes; k += datasize) memcpy (p + k, p, datasize); } else { /* Read in the buffer. */ if (fread (p, bytes, 1, fp) != 1) { return j / datasize; } } /* We may need to copy bytes from the state buffer. */ if (p == statebuf) statelen = bytes; else j += bytes; } return nelems; } static bitmap_type ReadImage (FILE *fp, struct tga_header *hdr) { bitmap_type image; unsigned char *buffer; unsigned char *alphas; int width, height, bpp, abpp, pbpp, nalphas; int j, k; int pelbytes, wbytes, bsize, npels, pels; int rle, badread; int itype=0; unsigned char *cmap = NULL; int (*myfread)(unsigned char *, int, int, FILE *); /* Find out whether the image is horizontally or vertically reversed. */ char horzrev = (char) (hdr->descriptor & TGA_DESC_HORIZONTAL); char vertrev = (char) (!(hdr->descriptor & TGA_DESC_VERTICAL)); image.bitmap = NULL; /* Reassemble the multi-byte values correctly, regardless of host endianness. */ width = (hdr->widthHi << 8) | hdr->widthLo; height = (hdr->heightHi << 8) | hdr->heightLo; bpp = hdr->bpp; abpp = hdr->descriptor & TGA_DESC_ABITS; if (hdr->imageType == TGA_TYPE_COLOR || hdr->imageType == TGA_TYPE_COLOR_RLE) pbpp = MIN (bpp / 3, 8) * 3; else if (abpp < bpp) pbpp = bpp - abpp; else pbpp = bpp; if (abpp + pbpp > bpp) { WARNINGP3 ("TGA: ",pbpp," bit image, ",abpp," bit alpha is greater than ",bpp," total bits per pixel"); /* Assume that alpha bits were set incorrectly. */ abpp = bpp - pbpp; WARNINGP1 ("TGA: reducing to * bit alpha: ", abpp); } else if (abpp + pbpp < bpp) { WARNINGP3 ("TGA: ",pbpp," bit image, ",abpp," bit alpha is less than ",bpp," total bits per pixel"); /* Again, assume that alpha bits were set incorrectly. */ abpp = bpp - pbpp; WARNINGP1 ("TGA: increasing to * bit alpha: ", abpp); } rle = 0; switch (hdr->imageType) { case TGA_TYPE_MAPPED_RLE: rle = 1; case TGA_TYPE_MAPPED: itype = INDEXED; /* Find the size of palette elements. */ pbpp = MIN (hdr->colorMapSize / 3, 8) * 3; if (pbpp < hdr->colorMapSize) abpp = hdr->colorMapSize - pbpp; else abpp = 0; if (bpp != 8) /* We can only cope with 8-bit indices. */ FATALP ("TGA: index sizes other than 8 bits are unimplemented"); break; case TGA_TYPE_GRAY_RLE: rle = 1; case TGA_TYPE_GRAY: itype = GRAY; break; case TGA_TYPE_COLOR_RLE: rle = 1; case TGA_TYPE_COLOR: itype = TGA_RGB; break; default: FATALP1 ("TGA: unrecognized image type ", (unsigned)hdr->imageType); } if ((abpp && abpp != 8) || ((itype == TGA_RGB || itype == INDEXED) && pbpp != 24) || (itype == GRAY && pbpp != 8)) /* FIXME: We haven't implemented bit-packed fields yet. */ FATALP ("TGA: channel sizes other than 8 bits are unimplemented"); /* Check that we have a color map only when we need it. */ if (itype == INDEXED) { if (hdr->colorMapType != 1) FATALP1 ("TGA: indexed image has invalid color map type ", (unsigned)hdr->colorMapType); } else if (hdr->colorMapType != 0) FATALP1 ("TGA: non-indexed image has invalid color map type ", (unsigned)hdr->colorMapType); alphas = 0; nalphas = 0; if (hdr->colorMapType == 1) { /* We need to read in the colormap. */ int index, colors; unsigned int length; index = (hdr->colorMapIndexHi << 8) | hdr->colorMapIndexLo; length = (hdr->colorMapLengthHi << 8) | hdr->colorMapLengthLo; if (length == 0) FATALP1 ("TGA: invalid color map length ", length); pelbytes = ROUNDUP_DIVIDE (hdr->colorMapSize, 8); colors = length + index; cmap = (unsigned char *) malloc (colors * pelbytes); /* Zero the entries up to the beginning of the map. */ memset (cmap, 0, index * pelbytes); /* Read in the rest of the colormap. */ if (fread (cmap + (index * pelbytes), pelbytes, length, fp) != length) FATALP1 ("TGA: error reading colormap; ftell == ", ftell (fp)); /* If we have an alpha channel, then create a mapping to the alpha values. */ if (pelbytes > 3) alphas = (unsigned char *) malloc (colors); k = 0; for (j = 0; j < colors * pelbytes; j += pelbytes) { /* Swap from BGR to TGA_RGB. */ unsigned char tmp = cmap[j]; cmap[k ++] = cmap[j + 2]; cmap[k ++] = cmap[j + 1]; cmap[k ++] = tmp; /* Take the alpha values out of the colormap. */ if (alphas) alphas[nalphas ++] = cmap[j + 3]; } /* If the last color was transparent, then omit it from the mapping. */ if (nalphas && alphas[nalphas - 1] == 0) colors --; /* Now pretend as if we only have 8 bpp. */ abpp = 0; pbpp = 8; pelbytes = 1; } else pelbytes = 3; image.bitmap = (unsigned char *) malloc (width * height * 3 * sizeof(unsigned char)); BITMAP_WIDTH (image) = (unsigned short) width; BITMAP_HEIGHT (image) = (unsigned short) height; BITMAP_PLANES (image) = (unsigned short) 3; /* Calculate TGA bytes per pixel. */ bpp = ROUNDUP_DIVIDE (pbpp + abpp, 8); /* Maybe we need to reverse the data. */ buffer = NULL; if (horzrev || vertrev) buffer = (unsigned char *) malloc (width * height * pelbytes * sizeof (unsigned char)); if (rle) myfread = rle_fread; else myfread = std_fread; wbytes = width * pelbytes; badread = 0; npels = width * height; bsize = wbytes * height; /* Suck in the data one height at a time. */ if (badread) pels = 0; else pels = (*myfread) (image.bitmap, bpp, npels, fp); if (pels != npels) { if (!badread) { /* Probably premature end of file. */ WARNINGP1 ("TGA: error reading; ftell == ", ftell (fp)); badread = 1; } /* Fill the rest of this tile with zeros. */ memset (image.bitmap + (pels * bpp), 0, ((npels - pels) * bpp)); } /* If we have indexed alphas, then set them. */ if (nalphas) { /* Start at the end of the buffer, and work backwards. */ k = (npels - 1) * bpp; for (j = bsize - pelbytes; j >= 0; j -= pelbytes) { /* Find the alpha for this index. */ image.bitmap[j + 1] = alphas[image.bitmap[k]]; image.bitmap[j] = image.bitmap[k --]; } } if (itype == GRAY) for (j = bsize/3 - 1; j >= 0; j -= 1) { /* Find the alpha for this index. */ image.bitmap[3*j] = image.bitmap[j]; image.bitmap[3*j+1] = image.bitmap[j]; image.bitmap[3*j+2] = image.bitmap[j]; } if (pelbytes >= 3) { /* Rearrange the colors from BGR to TGA_RGB. */ for (j = 0; j < bsize; j += pelbytes) { unsigned char tmp = image.bitmap[j]; image.bitmap[j] = image.bitmap[j + 2]; image.bitmap[j + 2] = tmp; } } if (horzrev || vertrev) { unsigned char *tmp; if (vertrev) { /* We need to mirror only vertically. */ for (j = 0; j < bsize; j += wbytes) memcpy (buffer + j, image.bitmap + bsize - (j + wbytes), wbytes); } else if (horzrev) { /* We need to mirror only horizontally. */ for (j = 0; j < bsize; j += wbytes) for (k = 0; k < wbytes; k += pelbytes) memcpy (buffer + k + j, image.bitmap + (j + wbytes) - (k + pelbytes), pelbytes); } else { /* Completely reverse the pixels in the buffer. */ for (j = 0; j < bsize; j += pelbytes) memcpy (buffer + j, image.bitmap + bsize - (j + pelbytes), pelbytes); } /* Swap the buffers because we modified them. */ tmp = buffer; buffer = image.bitmap; image.bitmap = tmp; } if (fgetc (fp) != EOF) WARNINGP ("TGA: too much input data, ignoring extra..."); free (buffer); if (hdr->colorMapType == 1) { unsigned char *temp, *temp2, *temp3; unsigned char index; int xpos, ypos; temp2 = temp = image.bitmap; image.bitmap = temp3 = (unsigned char *) malloc (width * height * 3 * sizeof (unsigned char)); for (ypos = 0; ypos < height; ypos++) { for (xpos = 0; xpos < width; xpos++) { index = *temp2++; *temp3++ = cmap[3*index+0]; *temp3++ = cmap[3*index+1]; *temp3++ = cmap[3*index+2]; } } free (temp); free (cmap); } if (alphas) free (alphas); return image; } /* read_image */ sam2p-0.49.2/at_bitmap.h0000644000175100017510000000447112211371426013146 0ustar ptspts/* This code is ripped from Autotrace-0.29, but modified by pts. */ /* bitmap.h: definition for a bitmap type. No packing is done by default; each pixel is represented by an entire byte. Among other things, this means the type can be used for both grayscale and binary images. */ #ifndef AT_BITMAP_H #define AT_BITMAP_H #ifdef __GNUC__ #pragma interface #endif #define PTS_SAM2P 1 #define FATALP(m) Error::sev(Error::EERROR) << m << (Error*)0; #define WARNINGP(m) Error::sev(Error::WARNING) << m << (Error*)0; #define FATALP1(m,a) Error::sev(Error::EERROR) << m << a << (Error*)0; #define WARNINGP1(m,a) Error::sev(Error::WARNING) << m << a << (Error*)0; #define FATALP3(m,a,n,b,o,c,p) Error::sev(Error::EERROR) << m << a << n << b << o << c << p << (Error*)0; #define WARNINGP3(m,a,n,b,o,c,p) Error::sev(Error::WARNING) << m << n << b << o << c << p << (Error*)0; #define XMALLOCT(var,typep,size) var=(typep)new char[size] #define XMALLOCTU(var,type) var=(type*)new type #define XFREE(p) delete p /* ^^^ Imp: arrays?? */ typedef unsigned at_dimen_t; /**** pts ****/ /* #include "autotrace.h" */ typedef char *at_string; typedef struct _at_bitmap_type { at_dimen_t height; at_dimen_t width; unsigned char *bitmap; unsigned int np; } at_bitmap_type; #include #define xfclose(fd,dummy) fclose(fd) /* The basic structure and macros to access it. */ typedef at_bitmap_type bitmap_type; /* The number of color planes of each pixel */ #define BITMAP_PLANES(b) ((b).np) /* The pixels, represented as an array of bytes (in contiguous storage). Each pixel is represented by np bytes. */ #define BITMAP_BITS(b) ((b).bitmap) /* These are convenient abbreviations for geting inside the members. */ #define BITMAP_WIDTH(b) ((b).width) #define BITMAP_HEIGHT(b) ((b).height) /* This is the pixel at [ROW,COL]. */ #define BITMAP_PIXEL(b, row, col) \ ((BITMAP_BITS (b) + (row) * BITMAP_PLANES (b) * BITMAP_WIDTH (b) \ + (col) * BITMAP_PLANES(b))) #define BITMAP_VALID_PIXEL(b, row, col) \ ((row) < BITMAP_HEIGHT (b) && (col) < BITMAP_WIDTH (b)) /* Allocate storage for the bits, set them all to white, and return an initialized structure. */ extern bitmap_type new_bitmap (at_dimen_t, at_dimen_t); /* Free that storage. */ extern void free_bitmap (bitmap_type *); #endif /* not AT_BITMAP_H */ sam2p-0.49.2/pts_lzw.h0000644000175100017510000000334112211371426012703 0ustar ptspts/* * pts_lzw.h -- a compact LZW compressor (not uncompressor) interface * compiled by pts@fazekas.hu at Mon Mar 4 00:31:20 CET 2002 */ #ifndef PTS_LZW_H #define PTS_LZW_H 1 #ifdef __GNUC__ #pragma interface #endif #include "config2.h" /* PTS_const */ /**** pts ****/ #ifndef ___ #if (defined(__STDC__) || defined(__cplusplus)) && !defined(NO_PROTO) # define _(args) args # define OF(args) args # define ___(arg2s,arg1s,argafter) arg2s /* Dat: no direct comma allowed in args :-( */ #else # define _(args) () # define OF(args) () # define ___(arg2s,arg1s,argafter) arg1s argafter /* Dat: no direct comma allowed in args :-( */ #endif #endif typedef char tbool_t; typedef unsigned char tidataval_t; /* internal image data value type */ typedef unsigned int tsize_t; /* i/o size in bytes */ typedef int (*tiwriter_t) OF((char *block, unsigned len, void *zfile)); struct pts_lzw_state; struct pts_lzw_state { /*FILE*/void* tif_sout; /**** pts ****/ /* for encode */ tiwriter_t tif_writer; int (*tif_feeder)(char *readbuf, unsigned readlen, struct pts_lzw_state *tif); #if 0 tbool_t tif_revbits_p; /**** pts ****/ #endif tbool_t tif_reading_p; /**** pts ****/ char PTS_const* tif_name; /* name of open file, used for debugging */ /* compression scheme hooks */ tidataval_t* tif_data; /* compression scheme private data */ /* input/output buffering */ tidataval_t* tif_rawend; /**** pts ****/ tidataval_t* tif_rawdata; /* raw data buffer */ tsize_t tif_rawdatasize;/* # of bytes in raw data buffer */ tidataval_t* tif_rawcp; /* current spot in raw buffer */ tsize_t tif_rawcc; /* bytes unread from raw buffer */ }; extern #ifdef __cplusplus "C" #endif int pts_lzw_init OF((struct pts_lzw_state*)); #endif sam2p-0.49.2/files0000644000175100017510000001147112211371426012060 0ustar ptsptsmain.hpp config-vc6.h sam2p16.ico sam2p32.ico vcsam2p.ico vcsam2p.cpp vcsam2p.dsp vcsam2p.h vcsam2p.ico vcsam2p.rc resource.h StdAfx.cpp StdAfx.h hq.pl c_lgcc.cpp c_lgcc3.cpp in_jai.hpp jpegdump_main.cpp sam2p_main.cpp test_main.cpp testfax_main.c snprintf.h snprintf.c pts_fax.c pts_fax.h examples/pts2.pbm examples/ptsbanner.gif ccdep.pl helpere.hpp encoder.hpp error.hpp gensi.hpp gensio.hpp image.hpp gensi.cpp Makefile rule.hpp gensio.cpp minips.hpp cgif.c encoder.cpp error.cpp image.cpp in_bmp.cpp in_gif.cpp in_jai.cpp in_jpeg.cpp in_lbm.cpp in_pcx.cpp in_png.cpp in_pnm.cpp in_ps.cpp pts_defl.c pts_defl.h in_tga.cpp in_tiff.cpp in_xpm.cpp out_gif.cpp crc32.c crc32.h cgif.h cols2.pl in_pnm.cpp xpmc.h in_xpm.cpp in_tga.cpp minips.cpp rule.cpp sam2p_main.cpp Makehelp.in pts_lzw.c mkdist.sh input-bmp.ci input-pnm.ci input-tga.ci at_bitmap.h pts_lzw.h files pts_defl.c pts_defl.h aclocal.m4 configure.in config2.h config.h.in configure COPYING README appliers.cpp in_jai.cpp out_gif.cpp mapping.hpp mapping.cpp contrib/aprea.ps contrib/sam2p.tk contrib/sam2ptol.pm contrib/template.job examples/a_jpg.job examples/a_jpg2.job examples/a_l1r8r_eps.job examples/at-logo_none_xpm.job examples/fishg_lzw12_pdf.job examples/fishg_lzw2_pdf.job examples/fishwbb_l128n_eps.job examples/fishwbb_l128r_eps.job examples/fishwbb_l12bn_eps.job examples/fishwbb_l12br_eps.job examples/fishwbb_l12hn_eps.job examples/fishwbb_l12hr_eps.job examples/fishwbb_l148n_eps.job examples/fishwbb_l148r_eps.job examples/fishwbb_l14bn_eps.job examples/fishwbb_l14br_eps.job examples/fishwbb_l14hn_eps.job examples/fishwbb_l14hr_eps.job examples/fishwbb_l188n_eps.job examples/fishwbb_l188r_eps.job examples/fishwbb_l18bn_eps.job examples/fishwbb_l18br_eps.job examples/fishwbb_l18hn_eps.job examples/fishwbb_l18hr_eps.job examples/fusi2_png.job examples/fusi_gif.job examples/fusi_l1t8r_eps.job examples/fusi_l1tbr_eps.job examples/fusi_l1thn_eps.job examples/fusi_l1thr_eps.job examples/fusi_png.job examples/fusi_pnm.job examples/fusi_pnm_ascii.job examples/fusi_tiff_bad_pdf.job examples/fusi_tiff_eps.job examples/fusi_tra_eps.job examples/fusi_trabin_eps.job examples/fusi_tradct_eps.job examples/fusi_tradct_jpeg.job examples/fusi_trafax_eps.job examples/fusi_traijg_eps.job examples/fusi_tral1a85_eps.job examples/fusiblack_png.job examples/fusiwhite_a85none.job examples/fusiwhite_binnone.job examples/fusiwhite_xwd.job examples/j_taska_lzw_eps.job examples/j_taska_rle_bmp.job examples/mixing_ijg.job examples/mixing_pcx_zip.job examples/mixing_zip.job examples/pts2_l1g8n_eps.job examples/pts2_l1g8r_eps.job examples/pts2_l1gbr_eps.job examples/pts2_pbm.job examples/pts2_pbm_pnm.job examples/pts2_pbm_zip0.job examples/ptsbanner2_ijg_tiff.job examples/ptsbanner2_jai.job examples/ptsbanner2_jai_jpeg.job examples/ptsbanner2_jai_pdf.job examples/ptsbanner2_jai_tiff.job examples/ptsbanner2_jpeg_tiff.job examples/ptsbanner__jpeg.job examples/ptsbanner_bbox_pdf.job examples/ptsbanner_gif_xwd.job examples/ptsbanner_jpeg.job examples/ptsbanner_jpg_xwd.job examples/ptsbanner_lzw.job examples/ptsbanner_lzw_framed.job examples/ptsbanner_lzw_margin.job examples/ptsbanner_lzw_margin_pdf.job examples/ptsbanner_lzw_pdf.job examples/ptsbanner_lzw_pdfb.job examples/ptsbanner_lzw_ps.job examples/ptsbanner_lzw_rot_ps.job examples/ptsbanner_lzw_tiff.job examples/ptsbanner_none_tiff.job examples/ptsbanner_png.job examples/ptsbanner_rle_pdf.job examples/ptsbanner_rle_tiff.job examples/ptsbanner_tralzw.job examples/ptsbanner_xpm_zip.job examples/ptsbanner_zip.job examples/ptsbanner_ziprgb4_tiff.job examples/ptsbanner_ziprgb8_tiff.job examples/ptsbannerg_jai.job examples/ptsbannerg_jai_pdf.job examples/ptsbannerg_jai_tiff.job examples/ptsbannerg_lzw_tiff.job examples/sam2p_fishg.job examples/sam2p_fisht.job examples/sam2p_fishwbb.job examples/sam2p_fishwbg.job examples/sam2p_fishwbg_bug.job examples/sam2p_fishwww.job examples/sam2psho.job examples/shot_fax31d_tiff.job examples/shot_fax32d_tiff.job examples/shot_fax4_tiff.job examples/shot_gif.job examples/shot_i1.job examples/shot_l118r_eps.job examples/shot_l11bn_eps.job examples/shot_l11br_eps.job examples/shot_l11hr_eps.job examples/shot_l1m8r_eps.job examples/shot_l1mbn_eps.job examples/shot_l1mbr_eps.job examples/shot_l1mhr_eps.job examples/shot_pdfb.job examples/shot_pdfb_hex.job examples/shot_png.job examples/shot_ppm.job examples/sziget_al.job examples/sziget_al_pdf.job examples/sziget_ma.job examples/transparent_tr.job examples/transparent_tr_pdf.job examples/xv_cant_display_eps.job examples/xv_cant_display_eps_gray.job examples/xv_cant_display_eps_rgb.job examples/xv_cant_display_gif.job examples/yellow_gif.job examples/yellow_op.job examples/yellow_op_pdf.job examples/yellow_rle_tiff.job bts.ttt l1zip.psm l1lzw.psm psmlib.psm ps_tiny.c debian/README.debian debian/changelog debian/control debian/copyright debian/dirs debian/rules sam2p_pdf_scale.pl sam2p-0.49.2/pts_defl.c0000644000175100017510000041272612211371426013007 0ustar ptspts#define DUMMY \ set -ex; \ "${CC:-gcc}" -DNDEBUG=1 -DPTS_DEFL_MAIN -O3 -ansi \ -Wall -W -Wstrict-prototypes -Wtraditional -Wnested-externs -Winline \ -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \ -Wmissing-declarations pts_defl.c -o flateenc; \ exit /* * pts_defl.c -- C source file ZIP compression ripped from linux-2.6.8.1 * by pts@fazekas.hu at Tue Jan 18 15:19:06 CET 2005 * * This ZIP compression (ZIP == PostScript /FlateEncode compression filter * (ZLIB RFC 1950)) routine has been ripped from the Linux kernel 2.6.8.1 * (directory lib/zlib_deflate), which has been ripped from ZLIB 1.1.3 * * To have a UNIX filter program (stdin -> stdout), compile zipfilt.c * * Dat: the exported symbols are: zlib_deflate zlib_deflateEnd * zlib_deflateInit_ zlib_deflateInit2_ zlib_deflateParams * zlib_deflate_workspacesize * */ /* ---- by pts */ /* +++ deflate.c */ /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in ftp://ds.internic.net/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ #if 0 /**** pts ****/ # include #endif /**** pts ****/ #if OBJDEP /* sam2p */ # warning PROVIDES: pts_defl #endif #if HAVE_CONFIG2_H /* sam2p */ # include "config2.h" #endif /* #include */ /* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-1998 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id: pts_defl.c,v 1.6 2008/08/28 20:16:47 pts Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H #if 0 /**** pts ****/ # include #else # include "pts_defl.h" #endif #if 0 /**** pts ****/ # include # include # include #endif /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.1.3, July 9th, 1998 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ /*#include */ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1998 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id: pts_defl.c,v 1.6 2008/08/28 20:16:47 pts Exp $ */ /*#ifndef _ZCONF_H*/ /*#define _ZCONF_H*/ #ifndef NULLP /**** pts ****/ #define NULLP ((void*)0) /* Imp: g++, with const */ #endif #if 0 /**** pts ****/ /* Dat: `inline' is not ANSI C */ # define ZINLINE inline #else # define ZINLINE #endif #define ZSTATIC static /**** pts ****/ /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # define MAX_MEM_LEVEL 8 #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* Type declarations */ typedef unsigned char Byte; /* 8 bits */ typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ typedef void *voidp; /*#endif*/ /* _ZCONF_H */ /* end of linux/zconf.h */ #if 0 #define ZLIB_VERSION "1.1.3" #endif /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ #if 0 struct zlib_internal_state; /**** pts ****/ /* Dat: was: internal_state */ typedef struct z_stream_s { Byte *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Byte *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULLP if no error */ struct zlib_internal_state *state; /* not visible by applications */ void *workspace; /* memory allocated for this stream */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return NULLP if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ #endif typedef z_stream *z_streamp; /* constants */ #if 0 #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_PACKET_FLUSH 2 #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #endif #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #if 0 #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ #endif #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ /* basic functions */ extern const char * zlib_zlibVersion (void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ extern int zlib_deflate_workspacesize (void); /* Returns the number of bytes that needs to be allocated for a per- stream workspace. A pointer to this number of bytes should be returned in stream->workspace before calling zlib_deflateInit(). */ /* extern int deflateInit (z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to NULLP, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ extern int zlib_deflate (z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least 0.1% larger than avail_in plus 12 bytes. If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update data_type if it can make a good guess about the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULLP), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). */ extern int zlib_deflateEnd (z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ extern int zlib_inflate_workspacesize (void); /* Returns the number of bytes that needs to be allocated for a per- stream workspace. A pointer to this number of bytes should be returned in stream->workspace before calling zlib_inflateInit(). */ /* extern int zlib_inflateInit (z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, and workspace must be initialized before by the caller. If next_in is not NULLP and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to NULLP, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ extern int zlib_inflate (z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may some introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_SYNC_FLUSH and Z_FINISH, but the current implementation actually flushes as much output as possible anyway. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call. If a preset dictionary is needed at this point (see inflateSetDictionary below), inflate sets strm-adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULLP), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then call inflateSync to look for a good compression block. */ extern int zlib_inflateEnd (z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* extern int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string match). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ extern int zlib_deflateSetDictionary (z_streamp strm, const Byte *dictionary, uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. Upon return of this function, strm->adler is set to the Adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULLP dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ extern int zlib_deflateCopy (z_streamp dest, z_streamp source); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULLP). msg is left unchanged in both source and destination. */ extern int zlib_deflateReset (z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULLP). */ extern int zlib_deflateParams (z_streamp strm, int level, int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ /* extern int inflateInit2 (z_streamp strm, int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memLevel). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ extern int zlib_inflateSetDictionary (z_streamp strm, const Byte *dictionary, uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the Adler32 value returned by this call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULLP dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect Adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ extern int zlib_inflateSync (z_streamp strm); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ extern int zlib_inflateReset (z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULLP). */ extern int zlib_inflateIncomp (z_stream *strm); /* This function adds the data at next_in (avail_in bytes) to the output history without performing any output. There must be no pending output, and the decompressor must be expecting to see the start of a block. Calling this function is equivalent to decompressing a stored block containing the data at next_in (except that the data is not output). */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ extern int zlib_deflateInit_ (z_streamp strm, int level, const char *version, int stream_size); extern int zlib_inflateInit_ (z_streamp strm, const char *version, int stream_size); extern int zlib_deflateInit2_ (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); extern int zlib_inflateInit2_ (z_streamp strm, int windowBits, const char *version, int stream_size); #if 0 /**** pts ****/ #define zlib_deflateInit(strm, level) \ zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define zlib_inflateInit(strm) \ zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define zlib_inflateInit2(strm, windowBits) \ zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #endif #if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) struct zlib_internal_state {int dummy;}; /* hack for buggy compilers */ #endif extern const char * zlib_zError (int err); extern int zlib_inflateSyncPoint (z_streamp z); extern const uLong * zlib_get_crc_table (void); /**** pts ****/ #define max(a,b) ((a)<(b) ? (b) : (a)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ /* Common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif /* functions */ typedef uLong (*check_func) (uLong check, const Byte *buf, uInt len); /* checksum functions */ #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULLP, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, NULLP, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ static ZINLINE uLong zlib_adler32(uLong adler, const Byte *buf, uInt len) { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == NULLP) return 1L; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } #endif /* _Z_UTIL_H */ /* end of zutil.h */ /* #include "defutil.h" */ #define Assert(err, str) #define Trace(dummy) #define Tracev(dummy) #define Tracecv(err, dummy) #define Tracevv(dummy) #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } tree_desc; typedef ush Pos; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct deflate_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Byte *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Byte *pending_out; /* next pending byte to output to the stream */ int pending; /* nb of bytes in the pending buffer */ int noheader; /* suppress zlib header and adler32 */ Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Byte *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Pos *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Pos *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uch *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ush *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ ulg compressed_len; /* total bit length of compressed file */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG_ZLIB ulg bits_sent; /* bit length of the compressed data */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } deflate_state; typedef struct deflate_workspace { /* State memory for the deflator */ deflate_state deflate_memory; Byte window_memory[2 * (1 << MAX_WBITS)]; Pos prev_memory[1 << MAX_WBITS]; Pos head_memory[1 << (MAX_MEM_LEVEL + 7)]; char overlay_memory[(1 << (MAX_MEM_LEVEL + 6)) * (sizeof(ush)+2)]; } deflate_workspace; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ ZSTATIC void zlib_tr_init (deflate_state *s); ZSTATIC int zlib_tr_tally (deflate_state *s, unsigned dist, unsigned lc); ZSTATIC ulg zlib_tr_flush_block (deflate_state *s, char *buf, ulg stored_len, int eof); ZSTATIC void zlib_tr_align (deflate_state *s); ZSTATIC void zlib_tr_stored_block (deflate_state *s, char *buf, ulg stored_len, int eof); ZSTATIC void zlib_tr_stored_type_only (deflate_state *); /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ static ZINLINE unsigned bi_reverse(unsigned code, /* the value to invert */ int len) /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ static ZINLINE void bi_flush(deflate_state *s) { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ static ZINLINE void bi_windup(deflate_state *s) { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG_ZLIB s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* end of defutil.h */ #if USE_ZLIB_MEM # include /* memcpy(), memset() */ # define zmemcpy(a,b,c) memcpy(a,b,c) # define zmemset(a,b,c) memset(a,b,c) #else static void *zmemcpy(void * dest,const void *src,unsigned count) { char *tmp = (char *) dest; char const *s = (char const*) src; while (count--) *tmp++ = *s++; return dest; } static void *zmemset(void * s,int c,unsigned count) { char *xs = (char *) s; while (count--) *xs++ = c; return s; } #endif /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) (deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ static void fill_window (deflate_state *s); static block_state deflate_stored (deflate_state *s, int flush); static block_state deflate_fast (deflate_state *s, int flush); static block_state deflate_slow (deflate_state *s, int flush); static void lm_init (deflate_state *s); static void putShortMSB (deflate_state *s, uInt b); static void flush_pending (z_streamp strm); static int read_buf (z_streamp strm, Byte *buf, unsigned size); static uInt longest_match (deflate_state *s, IPos cur_match); #ifdef DEBUG_ZLIB static void check_match (deflate_state *s, IPos start, IPos match, int length); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; static const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int zlib_deflateInit_( z_streamp strm, int level, const char *version, int stream_size ) { return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int zlib_deflateInit2_( z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size ) { deflate_state *s; int noheader = 0; static char my_version[] = ZLIB_VERSION; deflate_workspace *mem; ush *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == NULLP || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == NULLP) return Z_STREAM_ERROR; strm->msg = (char*)NULLP; /**** pts ****/ if (level == Z_DEFAULT_COMPRESSION) level = 6; mem = (deflate_workspace *) strm->workspace; if (windowBits < 0) { /* undocumented feature: suppress zlib header */ noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } s = (deflate_state *) &(mem->deflate_memory); strm->state = (struct zlib_internal_state *)s; s->strm = strm; s->data_type=strm->data_type; /**** pts ****/ /* BUGFIX at Tue Jan 18 16:01:08 CET 2005 */ /* Imp: report this bugfix to the Linux kernel */ s->noheader = noheader; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Byte *) mem->window_memory; s->prev = (Pos *) mem->prev_memory; s->head = (Pos *) mem->head_memory; s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ush *) mem->overlay_memory; s->pending_buf = (uch *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return zlib_deflateReset(strm); } #if 0 /**** pts ****/ /* ========================================================================= */ int zlib_deflateSetDictionary( z_streamp strm, const Byte *dictionary, uInt dictLength ) { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == NULLP || strm->state == NULLP || dictionary == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (s->status != INIT_STATE) return Z_STREAM_ERROR; strm->adler = zlib_adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > MAX_DIST(s)) { length = MAX_DIST(s); #ifndef USE_DICT_HEAD dictionary += dictLength - length; /* use the tail of the dictionary */ #endif } zmemcpy((char *)s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } #endif /* ========================================================================= */ int zlib_deflateReset( z_streamp strm ) { deflate_state *s; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; strm->total_in = strm->total_out = 0; strm->msg = (char*)NULLP; strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->noheader < 0) { s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ } s->status = s->noheader ? BUSY_STATE : INIT_STATE; strm->adler = 1; s->last_flush = Z_NO_FLUSH; zlib_tr_init(s); lm_init(s); return Z_OK; } #if 0 /**** pts ****/ /* ========================================================================= */ int zlib_deflateParams( z_streamp strm, int level, int strategy ) { deflate_state *s; compress_func func; int err = Z_OK; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if (func != configuration_table[level].func && strm->total_in != 0) { /* Flush the last buffer: */ err = zlib_deflate(strm, Z_PARTIAL_FLUSH); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } #endif /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ static void putShortMSB( deflate_state *s, uInt b ) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ static void flush_pending( z_streamp strm ) { deflate_state *s = (deflate_state *) strm->state; unsigned len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; if (strm->next_out != NULLP) { zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; } s->pending_out += len; strm->total_out += len; strm->avail_out -= len; s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } /* ========================================================================= */ int zlib_deflate( z_streamp strm, int flush ) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == NULLP || strm->state == NULLP || flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } s = (deflate_state *) strm->state; if ((strm->next_in == NULLP && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { return Z_STREAM_ERROR; } if (strm->avail_out == 0) return Z_BUF_ERROR; s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the zlib header */ if (s->status == INIT_STATE) { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags = (s->level-1) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = 1L; } /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUFF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { return Z_BUF_ERROR; } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { return Z_BUF_ERROR; } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { zlib_tr_align(s); } else if (flush == Z_PACKET_FLUSH) { /* Output just the 3-bit `stored' block type value, but not a zero length. */ zlib_tr_stored_type_only(s); } else { /* FULL_FLUSH or SYNC_FLUSH */ zlib_tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->noheader) return Z_STREAM_END; /* Write the zlib trailer (adler32) */ putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ s->noheader = -1; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int zlib_deflateEnd( z_streamp strm ) { int status; deflate_state *s; if (strm == NULLP || strm->state == NULLP) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; status = s->status; if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } strm->state = (struct zlib_internal_state*)NULLP; /**** pts ****/ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } #if 0 /**** pts ****/ /* ========================================================================= * Copy the source state to the destination state. */ int zlib_deflateCopy ( z_streamp dest, z_streamp source ) { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ush *overlay; deflate_workspace *mem; if (source == NULLP || dest == NULLP || source->state == NULLP) { return Z_STREAM_ERROR; } ss = (deflate_state *) source->state; *dest = *source; mem = (deflate_workspace *) dest->workspace; ds = &(mem->deflate_memory); dest->state = (struct zlib_internal_state *) ds; *ds = *ss; ds->strm = dest; ds->window = (Byte *) mem->window_memory; ds->prev = (Pos *) mem->prev_memory; ds->head = (Pos *) mem->head_memory; overlay = (ush *) mem->overlay_memory; ds->pending_buf = (uch *) overlay; zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif } #endif /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ static int read_buf( z_streamp strm, Byte *buf, unsigned size ) { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (!((deflate_state *)(strm->state))->noheader) { strm->adler = zlib_adler32(strm->adler, strm->next_in, len); } zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ static void lm_init( deflate_state *s ) { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; } /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ static uInt longest_match( deflate_state *s, IPos cur_match /* current match */ ) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Byte *scan = s->window + s->strstart; /* current string */ register Byte *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Pos *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Byte *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ush*)scan; register ush scan_end = *(ush*)(scan+best_len-1); #else register Byte *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ush*)(match+best_len-1) != scan_end || *(ush*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ush*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return best_len; return s->lookahead; } #ifdef DEBUG_ZLIB /* =========================================================================== * Check that the match at match_start is indeed a match. */ static void check_match( deflate_state *s, IPos start, IPos match, int length ) { /* check that the match is indeed a match */ if (memcmp((char *)s->window + match, (char *)s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ static void fill_window( deflate_state *s ) { register unsigned n, m; register Pos *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) */ more--; /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ } else if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy((char *)s->window, (char *)s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, eof) { \ zlib_tr_flush_block(s, (s->block_start >= 0L ? \ (char *)&s->window[(unsigned)s->block_start] : \ (char *)/****pts****/NULLP), \ (ulg)((long)s->strstart - s->block_start), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, eof) { \ FLUSH_BLOCK_ONLY(s, eof); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ static block_state deflate_stored( deflate_state *s, int flush ) { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ static block_state deflate_fast( deflate_state *s, int flush ) { IPos hash_head = NIL; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); bflush = zlib_tr_tally(s, s->strstart - s->match_start, s->match_length - MIN_MATCH); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in hash table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); bflush = zlib_tr_tally (s, 0, s->window[s->strstart]); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ static block_state deflate_slow( deflate_state *s, int flush ) { IPos hash_head = NIL; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR))) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); bflush = zlib_tr_tally(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); if (zlib_tr_tally (s, 0, s->window[s->strstart-1])) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); zlib_tr_tally (s, 0, s->window[s->strstart-1]); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } int zlib_deflate_workspacesize(void) { return sizeof(deflate_workspace); } /* +++ trees.c */ /* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ /* #include "deflate.h" */ #if 0 /**** pts ****/ # include # include "defutil.h" # ifdef DEBUG_ZLIB # include # endif #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; static const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; static const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; static const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ static ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see zlib_tr_init * below). */ static ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ static uch dist_code[512]; /* distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ static uch length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ static int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ static int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULLP */ const int *extra_bits; /* extra bits for each code or NULLP */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; static static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; static static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; static static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ static void tr_static_init (void); static void init_block (deflate_state *s); static void pqdownheap (deflate_state *s, ct_data *tree, int k); static void gen_bitlen (deflate_state *s, tree_desc *desc); static void gen_codes (ct_data *tree, int max_code, ush *bl_count); static void build_tree (deflate_state *s, tree_desc *desc); static void scan_tree (deflate_state *s, ct_data *tree, int max_code); static void send_tree (deflate_state *s, ct_data *tree, int max_code); static int build_bl_tree (deflate_state *s); static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); static void compress_block (deflate_state *s, ct_data *ltree, ct_data *dtree); static void set_data_type (deflate_state *s); static unsigned bi_reverse (unsigned value, int length); static void bi_windup (deflate_state *s); static void bi_flush (deflate_state *s); static void copy_block (deflate_state *s, char *buf, unsigned len, int header); #ifndef DEBUG_ZLIB # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG_ZLIB */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif #define d_code(dist) \ ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. dist_code[256] and dist_code[257] are never * used. */ /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG_ZLIB static void send_bits (deflate_state *s, int value, int length); static void send_bits( deflate_state *s, int value, /* value to send */ int length /* number of bits */ ) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (value << s->bi_valid); put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG_ZLIB */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (val << s->bi_valid);\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG_ZLIB */ /* =========================================================================== * Initialize the various 'constant' tables. In a multi-threaded environment, * this function may be called by two threads concurrently, but this is * harmless since both invocations do exactly the same thing. */ static void tr_static_init(void) { static int static_init_done; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; } /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ ZSTATIC void zlib_tr_init( deflate_state *s ) { tr_static_init(); s->compressed_len = 0L; s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG_ZLIB s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ static void init_block( deflate_state *s ) { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ static void pqdownheap( deflate_state *s, ct_data *tree, /* the tree to restore */ int k /* node to move down */ ) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ static void gen_bitlen( deflate_state *s, tree_desc *desc /* the tree descriptor */ ) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const int *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ static void gen_codes( ct_data *tree, /* the tree to decorate */ int max_code, /* largest code with non zero frequency */ ush *bl_count /* number of codes at each bit length */ ) { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch) (max(s->depth[n], s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ static void scan_tree( deflate_state *s, ct_data *tree, /* the tree to be scanned */ int max_code /* and its largest code of non zero frequency */ ) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ static void send_tree( deflate_state *s, ct_data *tree, /* the tree to be scanned */ int max_code /* and its largest code of non zero frequency */ ) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ static int build_bl_tree( deflate_state *s ) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ static void send_all_trees( deflate_state *s, int lcodes, /* number of codes for each tree */ int dcodes, /* number of codes for each tree */ int blcodes /* number of codes for each tree */ ) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ ZSTATIC void zlib_tr_stored_block( deflate_state *s, char *buf, /* input block */ ulg stored_len, /* length of input block */ int eof /* true if this is the last block for a file */ ) { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* Send just the `stored block' type code without any length bytes or data. */ ZSTATIC void zlib_tr_stored_type_only( deflate_state *s ) { send_bits(s, (STORED_BLOCK << 1), 3); bi_windup(s); s->compressed_len = (s->compressed_len + 3) & ~7L; } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ ZSTATIC void zlib_tr_align( deflate_state *s ) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ ZSTATIC ulg zlib_tr_flush_block( deflate_state *s, char *buf, /* input block, or NULLP if too old */ ulg stored_len, /* length of input block */ int eof /* true if this is the last block for a file */ ) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is ascii or binary */ if (s->data_type == Z_UNKNOWN) set_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute first the block length in bytes*/ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } /* If compression failed and this is the first and last block, * and if the .zip file can be seeked (to rewrite the local header), * the whole file is transformed into a stored file: */ #ifdef STORED_FILE_OK # ifdef FORCE_STORED_FILE if (eof && s->compressed_len == 0L) { /* force stored file */ # else if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { # endif /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (char*)0) error ("block vanished"); copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ s->compressed_len = stored_len << 3; s->method = STORED; } else #endif /* STORED_FILE_OK */ #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULLP is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ zlib_tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); s->compressed_len += 3 + s->static_len; } else { send_bits(s, (DYN_TREES<<1)+eof, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); s->compressed_len += 3 + s->opt_len; } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); init_block(s); if (eof) { bi_windup(s); s->compressed_len += 7; /* align on byte boundary */ } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); return s->compressed_len >> 3; } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ ZSTATIC int zlib_tr_tally( deflate_state *s, unsigned dist, /* distance of matched string */ unsigned lc /* match length-MIN_MATCH or unmatched char (if dist==0) */ ) { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "zlib_tr_tally: bad match"); s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0xfff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ static void compress_block( deflate_state *s, ct_data *ltree, /* literal tree */ ct_data *dtree /* distance tree */ ) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Set the data type to ASCII or BINARY, using a crude approximation: * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * IN assertion: the fields freq of dyn_ltree are set and the total of all * frequencies does not exceed 64K (to fit in an int on 16 bit machines). */ static void set_data_type( deflate_state *s ) { int n = 0; unsigned ascii_freq = 0; unsigned bin_freq = 0; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ static void copy_block( deflate_state *s, char *buf, /* the input data */ unsigned len, /* its length */ int header /* true if block header must be written */ ) { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG_ZLIB s->bits_sent += 2*16; #endif } #ifdef DEBUG_ZLIB s->bits_sent += (ulg)len<<3; #endif /* bundle up the put_byte(s, *buf++) calls */ zmemcpy(&s->pending_buf[s->pending], buf, len); s->pending += len; } /* end of deftree.c */ /* ---- by pts */ #if PTS_DEFL_MAIN /* * Usage: flateenc [-] < > * is one of: 0: no compression; 1: low & fast; 9: high & slow */ #include "pts_defl.h" #include /* read(), write() */ #include #include /* abort() */ int main(int argc, char **argv) { char ibuf[4096], obuf[6000]; /* Dat: 4096->6000 should be enough */ char workspace[sizeof(deflate_workspace)]; /* Dat: as returned by zlib_deflate_workspacesize in ZLIB 1.1.3 */ int got, zgot; /** Compression level: 0..9 or Z_DEFAULT_COMPRESSION */ int level=Z_DEFAULT_COMPRESSION; z_stream zs; (void)argc; if (argv && argv[0] && argv[1] && argv[1][0]=='-' && argv[1][1]>='0' && argv[1][1]<='9') level=argv[1][1]-'0'; /* printf("ws=%d\n", zlib_deflate_workspacesize()); */ if (zlib_deflate_workspacesize()+(unsigned)00 && got!=write(1, zs.next_out-got, got)) abort(); } if (0!=got) abort(); do { /* flush all output */ zs.next_in=NULL; zs.avail_in=0; zs.next_out=obuf; zs.avail_out=sizeof(obuf); if (Z_STREAM_END!=(zgot=zlib_deflate(&zs, Z_FINISH)) && Z_OK!=zgot) abort(); #ifdef DEBUG_PTS_DEFL fprintf(stderr, "ai=%d ao=%d flush\n", zs.avail_in, zs.avail_out); #endif got=sizeof(obuf)-zs.avail_out; if (got>0 && got!=write(1, zs.next_out-got, got)) abort(); } while (zgot==Z_OK); if (Z_OK!=zlib_deflateEnd(&zs)) abort(); return 0; } #endif sam2p-0.49.2/pts_defl.h0000644000175100017510000000716512211371426013011 0ustar ptspts/* * pts_defl.h -- C header file ZIP compression ripped from linux-2.6.8.1 * by pts@fazekas.hu at Tue Jan 18 15:19:06 CET 2005 * * This ZIP compression (ZIP == PostScript /FlateEncode compression filter * (ZLIB RFC 1950)) routine has been ripped from the Linux kernel 2.6.8.1 * (directory lib/zlib_deflate), which has been ripped from ZLIB 1.1.3 * * This is a minimal .h file, to avoid namespace pollution. * See more in the beginning of pts_defl.c * For documentation comments, see pts_defl.c * */ #ifndef PTS_DEFL_H #define PTS_DEFL_H #define PTS_DEFL_RIPPED_ZLIB 1 /** Must be at least zlib_deflate_workspacesize(): 267946 on Linux i386 */ #define ZLIB_DEFLATE_WORKSPACESIZE_MIN 270000 #define ZLIB_VERSION "1.1.3" #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_PACKET_FLUSH 2 #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ struct zlib_internal_state; /**** pts ****/ /* Dat: was: internal_state */ typedef struct z_stream_s { unsigned char *next_in; /* next input byte */ unsigned int avail_in; /* number of bytes available at next_in */ unsigned long total_in; /* total nb of input bytes read so far */ unsigned char *next_out; /* next output byte should be put there */ unsigned int avail_out; /* remaining free space at next_out */ unsigned long total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULLP if no error */ struct zlib_internal_state *state; /* not visible by applications */ void *workspace; /* memory allocated for this stream */ int data_type; /* best guess about the data type: ascii or binary */ unsigned long adler; /* adler32 value of the uncompressed data */ unsigned long reserved; /* reserved for future use */ } z_stream; #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif EXTERN_C int zlib_deflate_workspacesize (void); EXTERN_C int zlib_deflate (z_stream* strm, int flush); EXTERN_C int zlib_deflateEnd (z_stream* strm); EXTERN_C int zlib_deflateParams (z_stream* strm, int level, int strategy); EXTERN_C int zlib_deflateInit_ (z_stream* strm, int level, const char *version, int stream_size); EXTERN_C int zlib_deflateInit2_ (z_stream* strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); #define zlib_deflateInit(strm, level) \ zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #endif sam2p-0.49.2/aclocal.m40000644000175100017510000011323512211371426012674 0ustar ptsptsdnl dnl aclocal.m4, read by configure dnl by pts@fazekas.hu at Thu Nov 1 23:07:16 CET 2001 dnl advanced integer checks Sat Apr 6 12:32:02 CEST 2002 dnl dnl Imp: is shell `elif' compatible dnl Imp: less autoconf warnings dnl Dat: m4 SUXX, no normal error message for missing ')' dnl Dat: FILE *f=fopen("conftestval", "w"); is autoconf trad dnl autoconf-2.13 generates bad code for AC_C_CONST in g++-3.2 dnl autoconf-2.54 is good (verified at Wed Dec 11 15:28:28 CET 2002) AC_PREREQ([2.14]) dnl stupid autoconf-2.54 does #include m4_define([_AC_PROG_CXX_EXIT_DECLARATION],[:]) AC_DEFUN([AC_PTS_CHECK_INTEGRALS],[ dnl Checks for integral sizes. AC_REQUIRE([AC_HEADER_STDC]) AC_PTS_C_CHAR_UNSIGNED dnl ^^^ eliminates autoconf warning `warning: AC_TRY_RUN called without default to allow cross compiling' dnl by pts@fazekas.hu at Sat Apr 6 12:43:48 CEST 2002 dnl Run some tests in a single burst. if test x"$ac_cv_sizeof_char" = x; then AC_MSG_CHECKING(size of char) AC_CACHE_VAL(ac_cv_sizeof_char, [ac_cv_sizeof_char_p=-1;ac_cv_sizeof_short=-1;ac_cv_sizeof_int=-1 ac_cv_sizeof_long=-1 AC_TRY_RUN([ #undef const #undef volatile #undef inline #include int main(){FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "ac_cv_sizeof_char=%d\n", sizeof(char)); fprintf(f, "ac_cv_sizeof_char_p=%d\n", sizeof(char*)); fprintf(f, "ac_cv_sizeof_short=%d\n", sizeof(short)); fprintf(f, "ac_cv_sizeof_int=%d\n", sizeof(int)); fprintf(f, "ac_cv_sizeof_long=%d\n", sizeof(long)); return 0; /* exit(0); -- return is more portable */ }], eval "`cat conftestval`", , ac_cv_sizeof_char=-1)]) AC_MSG_RESULT($ac_cv_sizeof_char) AC_DEFINE_UNQUOTED(SIZEOF_CHAR, $ac_cv_sizeof_char) AC_DEFINE_UNQUOTED(SIZEOF_CHAR_P, $ac_cv_sizeof_char_p) AC_DEFINE_UNQUOTED(SIZEOF_SHORT, $ac_cv_sizeof_short) AC_DEFINE_UNQUOTED(SIZEOF_INT, $ac_cv_sizeof_int) AC_DEFINE_UNQUOTED(SIZEOF_LONG, $ac_cv_sizeof_long) fi dnl AC_PTS_CHECK_SIZEOF(char, -1) if test $ac_cv_sizeof_char = -1; then AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_INTEGRALS) fi AC_PTS_CHECK_SIZEOF(short, -1) AC_PTS_CHECK_SIZEOF(int, -1) AC_PTS_CHECK_SIZEOF(long, -1) AC_PTS_CHECK_SIZEOF(long long, -1) if test $ac_cv_sizeof_long_long = 8 then ac_cv_sizeof___int64=0; ac_cv_sizeof_very_long=0; fi AC_PTS_CHECK_SIZEOF(very long, -1) if test $ac_cv_sizeof_very_long = 8; then ac_cv_sizeof___int64=0; fi AC_PTS_CHECK_SIZEOF(__int64, -1) dnl ^^^ very long type doesn't exit in any C standard. dnl Imp: make these cached # echo $ac_cv_sizeof_long_long if test $ac_cv_sizeof_char != 1; then AC_MSG_ERROR(sizeof(char)!=1) fi if test $ac_cv_sizeof_short = 2; then ac_cv_pts_int16_t=short elif test $ac_cv_sizeof_int = 2; then ac_cv_pts_int16_t=int else AC_MSG_ERROR(cannot find inttype: sizeof(inttype)==2) fi AC_DEFINE_UNQUOTED(PTS_INT16_T, $ac_cv_pts_int16_t) if test $ac_cv_sizeof_int = 4; then ac_cv_pts_int32_t=int elif test $ac_cv_sizeof_long = 4; then ac_cv_pts_int32_t=long elif test $ac_cv_sizeof_long -lt 4; then AC_MSG_ERROR(sizeof(long)<4) else AC_MSG_ERROR(cannot find inttype: sizeof(inttype)==4) fi AC_DEFINE_UNQUOTED(PTS_INT32_T, $ac_cv_pts_int32_t) if test $ac_cv_sizeof_long = 8; then ac_cv_pts_int64_t=long elif test $ac_cv_sizeof_long_long = 8; then ac_cv_pts_int64_t="long long" elif test $ac_cv_sizeof_very_long = 8; then ac_cv_pts_int64_t="very long" elif test $ac_cv_sizeof___int64 = 8; then ac_cv_pts_int64_t="__int64" else dnl AC_DEFINE(PTS_INT64_T, 0) -- skip AC_DEFINE(); #undef is OK in aclocal.h dnl Imp: put a real #undef into config.h (configure comments it out :-< ) ac_cv_pts_int64_t=0 AC_MSG_WARN(cannot find inttype: sizeof(inttype)==8) fi AC_DEFINE_UNQUOTED(PTS_INT64_T, $ac_cv_pts_int64_t) if test $ac_cv_sizeof_long = 16; then ac_cv_pts_int128_t=long elif test $ac_cv_sizeof_long_long = 16; then ac_cv_pts_int128_t="long long" elif test $ac_cv_sizeof_very_long = 16; then ac_cv_pts_int128_t="very long" else dnl AC_DEFINE(PTS_INT128_T, 0) -- skip AC_DEFINE(); #undef is OK in aclocal.h dnl Imp: put a real #undef into config.h (configure comments it out :-< ) ac_cv_pts_int128_t=0 AC_MSG_WARN(cannot find inttype: sizeof(inttype)==16) fi AC_DEFINE_UNQUOTED(PTS_INT128_T, $ac_cv_pts_int128_t) ]) dnl ripped from autoconf-2.13 (ruined by autoconf-2.50) dnl by pts@fazekas.hu at Wed Dec 11 12:33:53 CET 2002 dnl AC_PTS_CHECK_SIZEOF(TYPE [, CROSS-SIZE]) AC_DEFUN(AC_PTS_CHECK_SIZEOF, [changequote(<<, >>)dnl dnl The name to #define. define(<>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl dnl The cache variable name. define(<>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl changequote([, ])dnl AC_MSG_CHECKING(size of $1) AC_CACHE_VAL(AC_CV_NAME, [AC_TRY_RUN([#include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof($1)); return 0; }], AC_CV_NAME=`cat conftestval`, AC_CV_NAME=0, ifelse([$2], , , AC_CV_NAME=$2))])dnl AC_MSG_RESULT($AC_CV_NAME) AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME) undefine([AC_TYPE_NAME])dnl undefine([AC_CV_NAME])dnl ]) AC_DEFUN([AC_PTS_CHECK_POINTERS],[ AC_REQUIRE([AC_PTS_CHECK_INTEGRALS]) AC_PTS_CHECK_SIZEOF(char *, -1) AC_PTS_CHECK_SIZEOF(void *, -1) dnl no need for checking for -1, AC_PTS_CHECK_INTEGRALS already did it AC_MSG_CHECKING(for an integral type to hold a ptr) AC_CACHE_VAL(ac_cv_pts_intp_t, [ if test $ac_cv_sizeof_char_p != $ac_cv_sizeof_void_p; then AC_MSG_ERROR($ac_cv_sizeof_char_p==sizeof(char*)!=sizeof(void*)) fi if test $ac_cv_sizeof_char_p -le 2; then ac_cv_pts_intp_t=$ac_cv_pts_int16_t elif test $ac_cv_sizeof_char_p -le 4; then ac_cv_pts_intp_t=$ac_cv_pts_int32_t elif test $ac_cv_sizeof_char_p -le 8; then ac_cv_pts_intp_t=$ac_cv_pts_int64_t elif test $ac_cv_sizeof_char_p -le 16; then ac_cv_pts_intp_t=$ac_cv_pts_int128_t else # :; fi; if true; then AC_MSG_RESULT(not found!) AC_MSG_ERROR(no integral type for sizeof(char*)==$ac_cv_sizeof_char_p) fi ])dnl AC_CACHE_VAL AC_DEFINE_UNQUOTED(PTS_INTP_T, $ac_cv_pts_intp_t) AC_MSG_RESULT($ac_cv_pts_intp_t) AC_MSG_CHECKING(for ptr <-> integral conversion) AC_CACHE_VAL(ac_cv_pts_intp_ok, [ AC_TRY_RUN([ /* #include "confdefs.h" -- automatic */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif /* #ifndef __cplusplus; #define const; #endif -- automatic config.h */ {char const*p="The quick brown fox."+5; PTS_INTP_T i; while (*p!='r') p++; /* prevent compiler optimisations */ i=(PTS_INTP_T)p; while (*p!='w') p++; /* prevent compiler optimisations */ return p!=(char*)(i+2); } ], ac_cv_pts_intp_ok=yes, ac_cv_pts_intp_ok=no, [AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_POINTERS)] )])dnl AC_CACHE_VAL if test x"$ac_cv_pts_intp_ok" = xyes; then AC_DEFINE(PTS_INTP_OK) fi AC_MSG_RESULT($ac_cv_pts_intp_ok) ]) dnl Ballast code elmiminated at Sat Apr 6 11:47:08 CEST 2002 dnl [AC_MSG_RESULT(not found); AC_MSG_ERROR(This is fatal.)], dnl [AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_INTEGRAL_TYPE)] dnl) dnlAC_MSG_RESULT($ac_cv_integral_type_$1) dnl]) AC_DEFUN([AC_PTS_CHECK_INTEGRAL_TYPEX],[ dnl @param $1: name of type dnl @param $2: substitution type dnl @param $3: stored name for the variable dnl errs out if specified type doesn't exist dnl please invoke AC_CHECK_HEADERS(unistd.h) 1st dnl Imp: make it work even if specified type doesn't exist dnl AC_TYPE_SIZE_T AC_REQUIRE([AC_HEADER_STDC]) AC_MSG_CHECKING(for integral type $3) AC_CACHE_VAL(ac_cv_integral_type_$3, [ AC_TRY_RUN([ #include /* #include "confdefs.h" -- automatic */ #include #if STDC_HEADERS #include #include #endif #include #if HAVE_UNISTD_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif #define MY_TYPE $1 int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, 0<(MY_TYPE)-1 ? "unsigned " : "signed "); if (sizeof(MY_TYPE)==1) fprintf(f, "char"); else if (sizeof(MY_TYPE)==sizeof(char)) fprintf(f, "char"); else if (sizeof(MY_TYPE)==sizeof(short)) fprintf(f, "short"); else if (sizeof(MY_TYPE)==sizeof(int)) fprintf(f, "int"); else if (sizeof(MY_TYPE)==sizeof(long)) fprintf(f, "long"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT16_T)) fprintf(f, "PTS_INT16_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT32_T)) fprintf(f, "PTS_INT32_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT64_T)) fprintf(f, "PTS_INT64_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT128_T)) fprintf(f, "PTS_INT128_T"); else return 3; /* fprintf(f, "???"); */ if (ferror(f)) return 2; /* printf("\n"); */ return 0; }], [ac_cv_integral_type_$3="`cat conftestval`"; ], dnl vvv Imp: make this a macro [if test x"$2" = x; then AC_MSG_RESULT(not found); AC_MSG_ERROR(This is fatal.); fi ac_cv_integral_type_$3="$2" echo -n "substituting " dnl ^^^ Imp: echo -n... dnl AC_MSG_RESULT(substituting $2) # doesn't work because of AC_CACHE_VAL ], [AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_INTEGRAL_TYPEX)] ) ])dnl AC_CACHE_VAL AC_DEFINE_UNQUOTED(PTS_$3, $ac_cv_integral_type_$3) AC_MSG_RESULT($ac_cv_integral_type_$3) ]) AC_DEFUN([AC_PTS_CHECK_INTEGRAL_TYPE],[ AC_PTS_CHECK_INTEGRAL_TYPEX($1,$2,$1) ]) AC_DEFUN([AC_PTS_TYPE_GETGROUPS], [ AC_REQUIRE([AC_TYPE_GETGROUPS]) dnl echo ,$ac_cv_type_getgroups, AC_PTS_CHECK_INTEGRAL_TYPEX($ac_cv_type_getgroups, [], getgroups_t) ]) dnl ripped from ruby-1.6.2 AC_DEFUN([AC_PTS_HAVE_PROTOTYPES], [ AC_CACHE_CHECK(whether cc supports prototypes, ac_cv_pts_have_prototypes, [ AC_TRY_COMPILE( [int foo(int x) { return 0; }], [return foo(10);], ac_cv_pts_have_prototypes=yes, ac_cv_pts_have_prototypes=no ) ]) if test x"$ac_cv_pts_have_prototypes" = xyes; then AC_DEFINE(HAVE_PROTOTYPES) fi ]) dnl by pts@fazekas.hu at Wed Dec 11 12:09:14 CET 2002 AC_DEFUN([AC_PTS_HAVE_STATIC_CONST], [ AC_CACHE_CHECK(whether c++ supports static const, ac_cv_pts_have_static_const, [ AC_TRY_COMPILE( [#undef const class A { public: static const int i=1; };], [return A::i==0;], ac_cv_pts_have_static_const=yes, ac_cv_pts_have_static_const=no ) ]) if test x"$ac_cv_pts_have_static_const" = xyes; then AC_DEFINE(HAVE_STATIC_CONST) fi ]) class A { static const int i=1; }; dnl by pts@fazekas.hu at Fri Nov 2 13:15:27 CET 2001 AC_DEFUN([AC_PTS_HAVE_STDC], [ dnl Check for working standard C (also called as ANSI C) dnl implies check for AC_PTS_HAVE_PROTOTYPES, AC_HEADER_STDC AC_REQUIRE([AC_HEADER_STDC]) AC_REQUIRE([AC_PTS_HAVE_PROTOTYPES]) AC_CACHE_CHECK(whether cc compiles standard C, ac_cv_pts_have_stdc, [ AC_EGREP_CPP(nope, [ #if defined(__STDC__) && __STDC__ /* note: the starting spaces are deliberate in the next line */ #if 0 nope #endif #else #if defined(__cplusplus) && __cplusplus #if 0 nope #endif #else nope #endif #endif ], ac_cv_pts_have_stdc=no, [ if test x"$ac_cv_pts_have_prototypes" = xyes; then ac_cv_pts_have_stdc=yes else ac_cv_pts_have_stdc=no fi ]) ]) if test x"$ac_cv_pts_have_stdc" = xyes; then AC_DEFINE(HAVE_PTS_STDC) fi ]) dnl by pts@fazekas.hu at Fri Nov 2 13:46:39 CET 2001 AC_DEFUN([AC_PTS_C_VOLATILE], [ AC_CACHE_CHECK(for C keyword volatile, ac_cv_pts_have_volatile, [ AC_TRY_COMPILE( [volatile int i;], [i=5; i++; return i-6;], ac_cv_pts_have_volatile=yes, ac_cv_pts_have_volatile=no ) ]) if test x"$ac_cv_pts_have_volatile" = xno; then AC_DEFINE(volatile, ) fi ]) AC_DEFUN([AC_PTS_CHECK_HEADER], [ dnl @param $1 file to be #included dnl @param $2 function to be tested dnl @param $3 cache name, such as `strcpy_in_string' dnl @param $4 test code (main() function) dnl better than AC_CHECK_HEADERS because it undefines const and volatile dnl before including AC_CACHE_CHECK(for working $2 in $1, ac_cv_pts_$3, [ AC_TRY_RUN([ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include <$1> #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { $4 return 1; }], ac_cv_pts_$3=yes, ac_cv_pts_$3=no, [AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_HEADER)] ) ]) if test x"$ac_cv_pts_$3" = xyes; then AC_DEFINE_UNQUOTED(HAVE_$3) fi ]) dnl by pts@fazekas.hu at Fri Nov 2 15:05:19 CET 2001 AC_DEFUN([AC_PTS_CHECK_STRING], [ dnl defines ac_cv_pts_have_string dnl defines ac_cv_pts_have_memcmpy_builtin dnl defines ac_cv_pts_string_header AC_PTS_CHECK_HEADER(string.h, strcpy, strcpy_in_string, [char s[42]="X"; strcpy(s, "Hello, World!"); return *s!='H';] ) ac_cv_pts_have_string=no if test x"$ac_cv_pts_strcpy_in_string" = xyes; then ac_cv_pts_have_string=yes ac_cv_pts_string_header=string else AC_PTS_CHECK_HEADER(strings.h, strcpy, strcpy_in_strings, [char s[42]="X"; strcpy(s, "Hello, World!"); return *s!='H';] ) if test x"$ac_cv_pts_strcpy_in_strings" = xyes; then ac_cv_pts_have_string=yes ac_cv_pts_string_header=strings fi fi if test x"$ac_cv_pts_have_string" = xyes; then AC_DEFINE(HAVE_STRING) fi CC_bak="$CC" CC="${CC:-cc} -Werror" AC_PTS_CHECK_HEADER($ac_cv_pts_string_header.h, memcpy, memcpy_in_stringxs, [char s[42]="X"; memcpy(s, "Hello, World!", 2); return *s!='H'; ]) CC="$CC_bak" AC_CACHE_CHECK(whether memcmp and memcpy are built-in, ac_cv_pts_have_memcmpy_builtin, [ ac_cv_pts_have_memcmpy_builtin=no if test x"$ac_cv_pts_have_string" = xyes; then dnl They are built-in for gcc 2.7.2.3 -traditional if test x"$ac_cv_pts_memcpy_in_stringxs" = xno; then AC_TRY_RUN([ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; memcpy(s, "Hello, World!", 2); return memcmp(s, "H", 1)!=0; }], [ac_cv_pts_have_memcmpy_builtin=yes], [AC_MSG_ERROR(missing memcmp and memcpy)], [AC_MSG_ERROR(cross compiling not supported by .._PTS_CHECK_STRING)] ) fi fi ]) if test x"$ac_cv_pts_have_memcmpy_builtin" = xyes; then AC_DEFINE(HAVE_MEMCMPY_BUILTIN) fi ]) dnl by pts@fazekas.hu at Tue Sep 3 19:27:50 CEST 2002 dnl g++-3.2: cc1plus: warning: ignoring command line option '-Wnested-externs' dnl Usage: AC_PTS_CHECK_IGNORING(nebfcmd,-Wnested-externs -Wbad-function-cast -Wmissing-declarations) AC_DEFUN([AC_PTS_CHECK_IGNORING], [ XTRA="$2" CC_bak="$CC" CC="${CC:-cc} -Werror $2" CXX_bak="$CXX" CXX="${CXX:-c++} -Werror $2" AC_CACHE_CHECK([for ignored $2],ac_cv_pts_ignoring_$1, [ AC_TRY_COMPILE([],[], ac_cv_pts_ignoring_$1=no,ac_cv_pts_ignoring_$1=yes)]) CC="$CC_bak" CXX="$CXX_bak" ]) dnl by pts@fazekas.hu at Fri Nov 2 15:05:27 CET 2001 AC_DEFUN([AC_PTS_CHECK_MALLOC], [ dnl never fails AC_PTS_CHECK_HEADER(stdlib.h, malloc, malloc_in_stdlib, [char *p=(char*)malloc(42); if (p!=0) free((void*)p); return p==0;]) if test x"$ac_cv_pts_malloc_in_stdlib" != xyes; then AC_PTS_CHECK_HEADER(malloc.h, malloc, malloc_in_malloc, [char *p=malloc(42); if (p!=0) free(p); return p==0;]) fi ]) dnl by pts@fazekas.hu at Fri Nov 2 16:51:13 CET 2001 AC_DEFUN([AC_PTS_HAVE_SWITCH_ENUM_BUG], [ AC_CACHE_CHECK(for switch(enum) bug, ac_cv_pts_have_switch_enum_bug, [ AC_TRY_RUN([ enum what { foo, bar }; int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { switch ((enum what)1) { case foo: return 1; case bar: return 0; } return 1; }], [ac_cv_pts_have_switch_enum_bug=no], [ac_cv_pts_have_switch_enum_bug=yes], [AC_MSG_ERROR(cross compiling not supported by .._PTS_HAVE_SWITCH_ENUM_BUG)] ) ]) if test x"$ac_cv_pts_have_switch_enum_bug" = xyes; then AC_DEFINE(HAVE_SWITCH_ENUM_BUG) fi ]) dnl by pts@fazekas.hu at Mon Mar 4 09:17:43 CET 2002 AC_DEFUN([AC_PTS_HAVE_ASCII_SYSTEM], [ AC_CACHE_CHECK(for ASCII system, ac_cv_pts_have_ascii_system, [ AC_EGREP_CPP(ascii_yes,[ #if 'a'!=97 || '!'!=33 #error You need an ASCII system to compile this. #else ascii_yes #endif ], ac_cv_pts_have_ascii_system=yes, ac_cv_pts_have_ascii_system=no ) ]) if test x"$ac_cv_pts_have_ascii_system" = xyes; then AC_DEFINE(HAVE_ASCII_SYSTEM) fi ]) AC_DEFUN([AC_PTS_ENSURE_ASCII_SYSTEM], [ AC_PTS_HAVE_ASCII_SYSTEM if test x"$ac_cv_pts_have_ascii_system" != xyes; then AC_MSG_ERROR(you need an ASCII system) fi ]) dnl by pts@fazekas.hu at Fri Nov 2 16:51:13 CET 2001 AC_DEFUN([AC_PTS_CFG_P_TMPDIR], [ AC_CACHE_CHECK(for tmpdir, ac_cv_pts_cfg_p_tmpdir, [ AC_TRY_RUN([ #define __USE_SVID 1 #define __USE_GNU 1 #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *f=fopen("conftestval","w"); if (!f) return 1; fputs(P_tmpdir,f); return 0; }], [ac_cv_pts_cfg_p_tmpdir=\""`cat conftestval`"\"], [ac_cv_pts_cfg_p_tmpdir=0], [AC_MSG_ERROR(cross compiling not supported by .._PTS_CFG_P_TMPDIR)] ) ]) AC_DEFINE_UNQUOTED(PTS_CFG_P_TMPDIR, $ac_cv_pts_cfg_p_tmpdir) ]) dnl by pts@fazekas.hu at Wed Oct 1 19:14:28 CEST 2003 dnl on i386: dnl perl -e 'die sprintf"%.16f",(1/3)' ## 0.3333333333333333 (we chose 16) dnl perl -e 'die sprintf"%.17f",(1/3)' ## 0.33333333333333331 AC_DEFUN([AC_PTS_CFG_PRINTFGLEN], [ AC_CACHE_CHECK(for width of printf .g, ac_cv_pts_cfg_printfglen, [ AC_TRY_RUN([ #define __USE_SVID 1 #define __USE_GNU 1 #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { unsigned i; char tmp[64], pat[10], *p; FILE *f=fopen("conftestval","w"); if (!f) return 1; for (i=1;i<61;i++) { sprintf(pat, "%%.%ug", i); sprintf(tmp, pat, 1.0/3); if (tmp[0]=='0' && tmp[1]=='.') { p=tmp+2; while (*p=='3') p++; if (*p!='\0') break; } } if (i>1) fprintf(f,".%u",i-1); return 0; }], [ac_cv_pts_cfg_printfglen=\""`cat conftestval`"\"], [ac_cv_pts_cfg_printfglen=""], [AC_MSG_ERROR(cross compiling not supported by .._PTS_CFG_PRINTFGLEN)] ) test x"$ac_cv_pts_cfg_printfglen" = x && ac_cv_pts_cfg_printfglen=no ]) if test x"$ac_cv_pts_cfg_printfglen" = xno; then :; else AC_DEFINE_UNQUOTED(PTS_CFG_PRINTFGLEN, $ac_cv_pts_cfg_printfglen) fi ]) dnl by pts@fazekas.hu at Thu Dec 12 20:20:41 CET 2002 AC_DEFUN([AC_PTS_HAVE_SYSTEMF], [ echo no-original >conftestval AC_CACHE_CHECK(for working system(3), ac_cv_pts_systemf, [ AC_TRY_RUN([ #include #include /* system() */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { (void)argc; (void)argv; if (0!=system("echo t >conftestval && echo \"let it\" be e >conftestval")) { FILE *f=fopen("conftestval","w"); if (f) { fprintf(f,"runtime-error\n"); fclose(f); } } return 0; } ], [ac_cv_pts_systemf="`cat conftestval`"; ac_cv_pts_systemf="${ac_cv_pts_systemf:-invalid}"], [ac_cv_pts_systemf=compile-error], [AC_MSG_ERROR(cross compiling not supported by .._PTS_HAVE_VSNPRINTF)] ) # echo "($ac_cv_pts_systemf)" # if test x"$ac_cv_pts_systemf" = x'"let it" be e '; then if test x"$ac_cv_pts_systemf" = x't && echo "let it" be e '; then # Win32 COMMAND.COM ac_cv_pts_systemf=win32 elif test x"$ac_cv_pts_systemf" = x"let it be e"; then # UNIX /bin/sh ac_cv_pts_systemf=unix fi ]) if test x"$ac_cv_pts_systemf" = xwin32; then ac_cv_pts_have_systemf=yes AC_DEFINE(HAVE_PTS_SYSTEMF) AC_DEFINE(HAVE_PTS_SYSTEMF_WIN32) elif test x"$ac_cv_pts_systemf" = xunix; then ac_cv_pts_have_systemf=yes AC_DEFINE(HAVE_PTS_SYSTEMF) AC_DEFINE(HAVE_PTS_SYSTEMF_UNIX) elif test x"$ac_cv_pts_systemf" = x"invalid"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"compile-error"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"runtime-error"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"no-original"; then ac_cv_pts_have_systemf=no else ac_cv_pts_have_systemf=yes # ac_cv_pts_systemf=other AC_DEFINE(HAVE_PTS_SYSTEMF) AC_DEFINE(HAVE_PTS_SYSTEMF_OTHER) fi ]) dnl by pts@fazekas.hu at Fri Mar 22 16:40:22 CET 2002 AC_DEFUN([AC_PTS_HAVE_POPEN_B], [ AC_CACHE_CHECK(for binary popen_b, ac_cv_pts_have_popen_b, [ AC_TRY_RUN([ #define _XOPEN_SOURCE 1 /* popen() on Digital UNIX */ #define _POSIX_SOURCE 1 /* popen() */ #define _POSIX_C_SOURCE 2 /* popen() */ #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *p=popen("echo Ko rt5","rb"); int i; (void)argc; (void)argv; if (p==0) return 1; if (getc(p)!='K' || getc(p)!='o' || getc(p)!=' ') return 2; if (getc(p)!='r' || getc(p)!='t') return 3; if (getc(p)!='f'-'a'+'0') return 4; if (getc(p)!='\n') return 5; if (getc(p)!=-1) return 6; if (0!=pclose(p)) return 7; p=popen("cat >conftestval","wb"); if (p==0) return 31; for (i=0;i<666;i++) putc(i,p); if (ferror(p)) return 32; if (0!=pclose(p)) return 33; p=fopen("conftestval","rb"); if (p==0) return 34; for (i=0;i<666;i++) if (getc(p)!=(i&255)) return 35; if (fclose(p)!=0) return 36; return 0; } ], [ac_cv_pts_have_popen_b=yes], [ac_cv_pts_have_popen_b=no], [AC_MSG_ERROR(cross compiling not supported by .._PTS_HAVE_POPEN_B)] ) ]) dnl AC_DEFINE_UNQUOTED(HAVE_PTS_POPEN_B, $ac_cv_pts_have_popen_b) if test x"$ac_cv_pts_have_popen_b" = xyes; then AC_DEFINE(HAVE_PTS_POPEN_B) fi ]) dnl by pts@fazekas.hu at Fri Mar 22 16:40:22 CET 2002 AC_DEFUN([AC_PTS_HAVE_POPEN_], [ AC_CACHE_CHECK(for binary popen_, ac_cv_pts_have_popen_, [ AC_TRY_RUN([ #define _XOPEN_SOURCE 1 /* popen() on Digital UNIX */ #define _POSIX_SOURCE 1 /* popen() */ #define _POSIX_C_SOURCE 2 /* popen() */ #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *p=popen("echo Ko rt5","r"); int i; (void)argc; (void)argv; if (p==0) return 1; if (getc(p)!='K' || getc(p)!='o' || getc(p)!=' ') return 2; if (getc(p)!='r' || getc(p)!='t') return 3; if (getc(p)!='f'-'a'+'0') return 4; if (getc(p)!='\n') return 5; if (getc(p)!=-1) return 6; if (0!=pclose(p)) return 7; p=popen("cat >conftestval","w"); if (p==0) return 31; for (i=0;i<666;i++) putc(i,p); if (ferror(p)) return 32; if (0!=pclose(p)) return 33; p=fopen("conftestval","rb"); if (p==0) return 34; for (i=0;i<666;i++) if (getc(p)!=(i&255)) return 35; if (fclose(p)!=0) return 36; return 0; } ], [ac_cv_pts_have_popen_=yes], [ac_cv_pts_have_popen_=no], [AC_MSG_ERROR(cross compiling not supported by .._PTS_HAVE_POPEN_)] ) ]) dnl AC_DEFINE_UNQUOTED(HAVE_PTS_POPEN_, $ac_cv_pts_have_popen_) if test x"$ac_cv_pts_have_popen_" = xyes; then AC_DEFINE(HAVE_PTS_POPEN_) fi ]) dnl by pts@fazekas.hu at Fri Mar 22 19:36:26 CET 2002 dnl huge BUGFIX at Tue Jun 11 13:38:30 CEST 2002 dnl on kempelen: ac_cv_pts_vsnprintf=bad AC_DEFUN([AC_PTS_HAVE_VSNPRINTF], [ AC_CACHE_CHECK(for working vsnprintf, ac_cv_pts_vsnprintf, [ AC_TRY_RUN([ #if 0 /* autoconf-2.54 */ extern "C" void std::exit (int) throw (); using std::exit; extern "C" void std::exit (int); using std::exit; extern "C" void exit (int) throw (); extern "C" void exit (int); void exit (int); #endif #ifdef __cplusplus extern "C" void exit(int); #endif #define _BSD_SOURCE 1 /* vsnprintf */ #define _POSIX_SOURCE 1 #define _POSIX_C_SOURCE 2 #include #include #include static int myprintf(int max, char *dstr, char *fmt, ...) { int i; va_list ap; #if defined(__STDC__) va_start(ap, fmt); #else va_start(ap); #endif i=vsnprintf(dstr, max, fmt, ap); va_end(ap); return i; } int c99t[]={13,9,10,10,10}, oldt[]={-1,9,-1,0,-1}, sun99t[]={13,9,10,-1,10}; /* wincrtt[]={-1,9,10,-1,-1}, but it modifies the string in a completely * bogus way (passes 1 test of 5) */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char buf[40]; int i; int g[5], gg; int *t=oldt; FILE *f=fopen("conftestval","w"); (void)argc; (void)argv; if (f) { for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='X'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -1234567L); if (i==c99t[0]) t=c99t; /* oldt[0]!=c99t[0] */ g[0]=(i==t[0] && 0==memcmp(buf, "Alma--123\0X", 11)); /* printf("(%s) %d %d\n", buf, i, g[0]); */ for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='Y'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -123L); g[1]=(i==t[1] && 0==memcmp(buf, "Alma--123\0Y", 11)); /* printf("(%s) %d %d\n", buf, i, g[1]); */ for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='Z'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -1234L); g[2]=(i==t[2] && 0==memcmp(buf, "Alma--123\0Z", 11)); /* printf("(%s) %d %d\n", buf, i, g[2]); */ buf[0]='#'; i=myprintf(0, buf, "%s-%ld", "Alma", -1234L); if (t==c99t && i==sun99t[3]) t=sun99t; g[3]=(i==t[3] && buf[0]=='#'); /* printf("(%s) %d %d\n", buf, i, g[3]); */ buf[0]=buf[1]='$'; i=myprintf(1, buf, "%s-%ld", "Alma", -1234L); g[4]=(i==t[4] && buf[0]=='\0' && buf[1]=='$'); /* printf("(%s) %d %d\n", buf, i, g[4]); */ gg=g[0] && g[1] && g[2] && g[3] && g[4]; fputs(!gg ? "bad\n" : t==oldt ? "old\n" : t==sun99t ? "sun99\n" : "c99\n", f); fclose(f); } return 0; } ], [ac_cv_pts_vsnprintf="`cat conftestval`"; ac_cv_pts_vsnprintf="${ac_cv_pts_vsnprintf:-invalid}"], [ac_cv_pts_vsnprintf=no], [AC_MSG_ERROR(cross compiling not supported by .._PTS_HAVE_VSNPRINTF)] ) ]) if test x"$ac_cv_pts_vsnprintf" = xold; then ac_cv_pts_have_vsnprintf=yes AC_DEFINE(HAVE_PTS_VSNPRINTF) AC_DEFINE(HAVE_PTS_VSNPRINTF_OLD) elif test x"$ac_cv_pts_have_vsnprintf" = xc99; then ac_cv_pts_have_vsnprintf=yes AC_DEFINE(HAVE_PTS_VSNPRINTF) AC_DEFINE(HAVE_PTS_VSNPRINTF_C99) else ac_cv_pts_have_vsnprintf=no ac_cv_pts_vsnprintf=no fi ]) dnl by pts@fazekas.hu at Sun Mar 31 17:26:01 CEST 2002 AC_DEFUN([AC_PTS_HAVE_ERRNO_DECL], [ AC_CACHE_CHECK([for errno in errno.h],ac_cv_pts_errno_decl, [ AC_TRY_COMPILE([#include ],[int i = errno], ac_cv_pts_errno_decl=yes,ac_cv_pts_have_errno_decl=no)]) if test x"$ac_cv_pts_errno_decl" = x"yes"; then AC_DEFINE(HAVE_ERRNO_DECL, 1, [ ]) fi ]) dnl by pts@fazekas.hu at Sun Mar 31 22:19:16 CEST 2002 dnl modeled after Autoconf internal AC_EGREP_CPP dnl AC_PTS_SED_EGREP_CPP(SED-PATTERN, EGREP-PATTERN, PROGRAM, [ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND]]) AC_DEFUN(AC_PTS_SED_EGREP_CPP, [AC_REQUIRE_CPP()dnl cat > conftest.$ac_ext <&AC_FD_CC | dnl Prevent m4 from eating regexp character classes: changequote(, )dnl sed -n '$1' | egrep '$2' >/dev/null 2>&1; then changequote([, ])dnl ifelse([$4], , :, [rm -rf conftest* $4]) ifelse([$5], , , [else rm -rf conftest* $5 ])dnl fi rm -f conftest* ]) dnl by pts@fazekas.hu at Sun Mar 31 22:23:48 CEST 2002 dnl Digital UNIX OSF/1 has it in _some_ cases. AC_DEFUN([AC_PTS_HAVE_GETSOCKNAME_SIZE_T], [ AC_CACHE_CHECK(whether getsockname accepts size_t, ac_cv_pts_have_getsockname_size_t, [ AC_PTS_SED_EGREP_CPP([/getsockname/,/)/p], [size_t], [#include ], [ac_cv_pts_have_getsockname_size_t=yes], [ac_cv_pts_have_getsockname_size_t=no] ) ]) if test x"$ac_cv_pts_have_getsockname_size_t" = xyes; then AC_DEFINE(HAVE_PTS_GETSOCKNAME_SIZE_T) fi ]) dnl by pts@fazekas.hu at Sun Mar 31 22:23:48 CEST 2002 dnl Digital UNIX OSF/1 has it. AC_DEFUN([AC_PTS_HAVE_GETSOCKNAME_SOCKLEN_T], [ AC_CACHE_CHECK(whether getsockname accepts socklen_t, ac_cv_pts_have_getsockname_socklen_t, [ AC_PTS_SED_EGREP_CPP([/getsockname/,/)/p], [socklen_t], [#include ], [ac_cv_pts_have_getsockname_socklen_t=yes], [ac_cv_pts_have_getsockname_socklen_t=no] ) ]) if test x"$ac_cv_pts_have_getsockname_socklen_t" = xyes; then AC_DEFINE(HAVE_PTS_GETSOCKNAME_SOCKLEN_T) fi ]) dnl by pts@fazekas.hu at Sun Mar 31 23:50:05 CEST 2002 dnl Digital UNIX OSF/1 has it. AC_DEFUN([AC_PTS_ENABLE_DEBUG], [ AC_MSG_CHECKING([for --enable-debug]) AC_SUBST(ENABLE_DEBUG) AC_ARG_ENABLE(debug, [ --enable-debug[=val] val: no, assert(default), yes, checker], [], []) ENABLE_DEBUG="$enable_debug" if test x"$enable_debug" = xno; then AC_MSG_RESULT(no) elif test x"$enable_debug" = x || test x"$enable_debug" = xassert; then AC_MSG_RESULT(assert) ENABLE_DEBUG=assert elif test x"$enable_debug" = xyes; then AC_MSG_RESULT(yes) elif test x"$enable_debug" = xchecker; then AC_MSG_RESULT(checker) else AC_MSG_RESULT("?? $enable_debug") AC_MSG_ERROR(Invalid --enable--debug option specified.) fi ]) dnl by pts@fazekas.hu at Thu Apr 4 13:25:20 CEST 2002 dnl Keeps conftest* AC_DEFUN(AC_PTS_TRY_COMPILE_NORM, [cat > conftest.$ac_ext <&AC_FD_CC cat conftest.$ac_ext >&AC_FD_CC ifelse([$4], , , [ $4 ])dnl fi rm -f conftest*]) dnl by pts@fazekas.hu at Thu Apr 4 13:00:08 CEST 2002 dnl Checks whether `gcc' can link C++ programs (and thus libstdc++ is dnl avoided). AC_DEFUN([AC_PTS_GCC_LINKS_CXX], [ AC_REQUIRE([AC_LANG_CPLUSPLUS]) AC_REQUIRE([AC_PROG_CXX]) AC_CACHE_CHECK(whether gcc can link C++ code, ac_cv_pts_gcc_links_cxx, [ CXX_saved="$CXX" LIBS_saved="$LIBS" CXX_new="$CXX" ac_ext_saved="$ac_ext" AC_PTS_TRY_COMPILE_NORM([ #include struct B { virtual int f()=0; int x() { return f(); } }; struct C1: public B { virtual int f() {return 1;}}; struct C2: public B { virtual int f() {return 2;}}; C1 global; /* global.x() will cause segfault in i386-uclibc-gcc */ ],[ /* vvv (B*) cast added for gcc-3.1 */ B *p=(ferror(stderr))?(B*)new C1():(B*)new C2(); /* Imp: argc... */ /* if (p==0) throw long(42); */ /* doesn't work with -fno-rtti */ int ok2=p->x()==2; delete p; return !(ok2 && global.x()==1); ],[ case x"$CC" in xgcc-*) CXX="$CC" ;; # gcc-3.2 x*-gcc-*) CXX="$CC" ;; # x*-gcc) CXX="$CC" ;; # i386-uclibc-gcc *) CXX=gcc ;; esac CXX_new="$CXX" ac_ext="$ac_objext" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes else LIBS="$LIBS_saved c_lgcc.cpp" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes-with-help else LIBS="$LIBS_saved c_lgcc3.cpp" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes-with-help3 else ac_cv_pts_gcc_links_cxx=no; CXX_new="$CXX_saved"; fi fi fi ],[ac_cv_pts_gcc_links_cxx=compilation-failed]) CXX="$CXX_saved" LIBS="$LIBS_saved" ac_ext="$ac_ext_saved" ]) AC_SUBST(LDXX) case x"$ac_cv_pts_gcc_links_cxx" in xyes-with-help) LDXX="$CXX_new"; AC_DEFINE(HAVE_PTS_C_LGCC_CPP_REQUIRED) ;; xyes-with-help3) LDXX="$CXX_new"; AC_DEFINE(HAVE_PTS_C_LGCC3_CPP_REQUIRED) ;; xyes) LDXX="$CXX_new" ;; xno) LDXX="$CXX_new" ;; *) AC_MSG_ERROR([Compilation failed, aborting.]) ;; esac ]) dnl by pts@fazekas.hu at Sat Apr 6 10:56:48 CEST 2002 dnl based on AC_PROG_CXX_G from acspecific.m4 of autoconf dnl Appends the specified flags to CXXFLAGS, so it will affect subsequent AC_* dnl tests. dnl Example: AC_PTS_PROG_CXXFLAGS(nrne, -fno-rtti -fno-exceptions) AC_DEFUN(AC_PTS_PROG_CXXFLAGS, [AC_REQUIRE([AC_PROG_CXX]) AC_CACHE_CHECK(whether ${CXX-g++} accepts $2, ac_cv_prog_cxx_$1, [echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} $2 -c conftest.cc 2>&1`" then ac_cv_prog_cxx_$1=yes; else ac_cv_prog_cxx_$1=no; fi rm -f conftest* ]) if test $ac_cv_prog_cxx_$1 = yes; then CXXFLAGS="$CXXFLAGS $2"; fi ]) dnl by pts@fazekas.hu at Sat Apr 6 10:56:48 CEST 2002 dnl based on AC_PROG_CXX_G from acspecific.m4 of autoconf dnl Appends the specified flags to CXXFLAGSB, so it won't affect subsequent dnl AC_* tests. dnl Example: AC_PTS_PROG_CXXFLAGSB(apwaw, -ansi -pedantic -Wall -W) AC_DEFUN(AC_PTS_PROG_CXXFLAGSB, [AC_REQUIRE([AC_PROG_CXX]) AC_SUBST(CXXFLAGSB) AC_CACHE_CHECK(whether ${CXX-g++} accepts $2, ac_cv_prog_cxx_$1, [echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} $2 -c conftest.cc 2>&1`" then ac_cv_prog_cxx_$1=yes; else ac_cv_prog_cxx_$1=no; fi rm -f conftest* ]) if test $ac_cv_prog_cxx_$1 = yes; then CXXFLAGSB="$CXXFLAGSB $2"; fi ]) dnl by pts@fazekas.hu at Sat Apr 6 10:56:48 CEST 2002 dnl based on AC_PROG_CXX_G from acspecific.m4 of autoconf dnl Appends the specified flags to CFLAGS, so it will affect subsequent AC_* dnl tests. dnl Example: AC_PTS_PROG_CFLAGS(nrne, -fno-rtti -fno-exceptions) AC_DEFUN(AC_PTS_PROG_CFLAGS, [AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK(whether ${CC-gcc} accepts $2, ac_cv_prog_cc_$1, [echo 'void f(void);void f(void){}' > conftest.c if test -z "`${CC-gcc} $2 -c conftest.c 2>&1`" then ac_cv_prog_cc_$1=yes; else ac_cv_prog_cc_$1=no; fi rm -f conftest* ]) if test $ac_cv_prog_cc_$1 = yes; then CFLAGS="$CFLAGS $2"; fi ]) dnl by pts@fazekas.hu at Sat Apr 6 10:56:48 CEST 2002 dnl based on AC_PROG_CXX_G from acspecific.m4 of autoconf dnl Appends the specified flags to CFLAGSB, so it won't affect subsequent dnl AC_* tests. dnl Example: AC_PTS_PROG_CFLAGSB(apwaw, -ansi -pedantic -Wall -W) AC_DEFUN(AC_PTS_PROG_CFLAGSB, [AC_REQUIRE([AC_PROG_CC]) AC_SUBST(CFLAGSB) AC_CACHE_CHECK(whether ${CC-gcc} accepts $2, ac_cv_prog_cc_$1, [echo 'void f(void);void f(void){}' > conftest.c if test -z "`${CC-gcc} $2 -c conftest.c 2>&1`" then ac_cv_prog_cc_$1=yes; else ac_cv_prog_cc_$1=no; fi rm -f conftest* ]) if test $ac_cv_prog_cc_$1 = yes; then CFLAGSB="$CFLAGSB $2"; fi ]) dnl by pts@fazekas.hu at Sat Apr 6 11:49:59 CEST 2002 dnl Similar to AC_C_CHAR_UNSIGNED, but without the dnl `warning: AC_TRY_RUN called without default to allow cross compiling'. AC_DEFUN(AC_PTS_C_CHAR_UNSIGNED, [AC_CACHE_CHECK(whether char is unsigned, ac_cv_c_char_unsigned, [if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. AC_EGREP_CPP(yes, [#ifdef __CHAR_UNSIGNED__ yes #endif ], ac_cv_c_char_unsigned=yes, ac_cv_c_char_unsigned=no) else AC_TRY_RUN( [/* volatile prevents gcc2 from optimizing the test away on sparcs. */ #if !defined(__STDC__) || __STDC__ != 1 #define volatile #endif int main() { volatile char c = 255; return(c < 0); }], ac_cv_c_char_unsigned=yes, ac_cv_c_char_unsigned=no, [AC_MSG_ERROR(cross compiling not supported by .._PTS_C_CHAR_UNSIGNED)]) fi]) if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then AC_DEFINE(__CHAR_UNSIGNED__) fi ]) dnl by pts@fazekas.hu at Sun Apr 14 22:08:04 CEST 2002 dnl Ripped from autoconf's acgeneral.m4. Tests with `test -x'. dnl AC_PTS_PATH_XPROG(VARIABLE, PROG-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN(AC_PTS_PATH_XPROG, [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_$1="[$]$1" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="ifelse([$4], , $PATH, [$4])" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_$1="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" dnl If no 3rd arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$3], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$3" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test -n "[$]$1"; then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) dnl by pts@fazekas.hu at Sun Apr 14 21:50:13 CEST 2002 dnl Usage: AC_PTS_WARN_PROG(zip, [zip might become useful for /Compression/ZIP]) AC_DEFUN(AC_PTS_WARN_PROG, [AC_PTS_PATH_XPROG(pts_$1, $1) if test x"$ac_cv_path_pts_$1" = x; then AC_MSG_WARN($1 would provide increased functionality to this program:) AC_MSG_WARN($2) fi ]) dnl Usage: AC_PTS_ERR_PROG(make, [make is required for compiling this program]) AC_DEFUN(AC_PTS_ERR_PROG, [AC_PTS_PATH_XPROG(pts_$1, $1) if test x"$ac_cv_path_pts_$1" = x; then AC_MSG_WARN($1 is required:) AC_MSG_ERROR($2) fi ]) dnl by pts@fazekas.hu at Sat Jun 1 15:00:44 CEST 2002 dnl ac_n=... autoconf2.13 -> autoconf2.50 dnl Usage: AC_PTS_RUN_OK(CMDLINE, ACTION-OF-EXITCODE-0, ACTION-IF-ERROR) AC_DEFUN(AC_PTS_RUN_OK, [ac_n="${ac_n:-$ECHO_N}" echo $ac_n "running $1""... $ac_c" 1>&AC_FD_MSG echo "configure:__oline__: running $1" >&AC_FD_CC if >&AC_FD_CC 2>&AC_FD_CC $1; then : AC_MSG_RESULT(ok) $2 else AC_MSG_RESULT(error) $3 fi ]) dnl by pts@fazekas.hu at Sat Jun 1 15:13:36 CEST 2002 AC_DEFUN(AC_PTS_OK, [echo "configure:__oline__: all OK" >&AC_FD_CC ]) dnl __EOF__ sam2p-0.49.2/configure.in0000644000175100017510000002001412211371426013335 0ustar ptsptsdnl dnl configure.in -- for sam2p dnl by pts@fazekas.hu at Thu Nov 1 22:46:51 CET 2001 dnl Mon Mar 4 08:56:35 CET 2002 dnl dnl Dat: autoheader stops reading the file at the 1st error dnl Imp: concat (TCL, Ruby) dnl Imp: stringify dnl Imp: C and C++ dnl Imp: warnings dnl OK : traditional C dnl Imp: ctype dnl Imp: check for socklen_t dnl Process this file with autoconf to produce a configure script. AC_INIT(gensi.cpp) AC_CONFIG_HEADER(config.h) AC_PTS_ENABLE_DEBUG AC_MSG_CHECKING([for --enable-lzw]) AC_ARG_ENABLE(lzw, [ --enable-lzw enable built-in LZW (de)compression (def: no)], [], []) if test x1 = x"`perl -e 'print time>1056165811'`"; then # After 19 June 2003: default: yes if test x"$enable_lzw" = x"no"; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) AC_DEFINE(USE_BUILTIN_LZW) dnl AC_MSG_WARN(LZW was patented till 19 June 2003; ask permission from Unisys to use it!) fi else if test x"$enable_lzw" = x"yes"; then AC_MSG_RESULT(yes) AC_DEFINE(USE_BUILTIN_LZW) AC_MSG_WARN(LZW is patented till 19 June 2003; ask permission from Unisys to use it!) else AC_MSG_RESULT(no) fi fi dnl Sun Jul 7 23:58:11 CEST 2002 AC_MSG_CHECKING([for --enable-zip]) AC_ARG_ENABLE(zip, [ --enable-zip enable built-in ZIP compression (def: yes)], [], []) if test x"$enable_zip" = x"no"; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) AC_DEFINE(USE_BUILTIN_ZIP) fi dnl Sun Jul 7 23:58:11 CEST 2002 AC_MSG_CHECKING([for --enable-fax]) AC_ARG_ENABLE(fax, [ --enable-fax enable built-in Fax compression (def: yes)], [], []) if test x"$enable_fax" = x"no"; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) AC_DEFINE(USE_BUILTIN_FAXE) fi AC_MSG_CHECKING([for --enable-gif]) AC_ARG_ENABLE(gif, [ --enable-gif enable reading and writing GIF images (def: no)], [], []) if test x"$enable_gif" = x"yes"; then AC_MSG_RESULT(yes) AC_DEFINE(USE_IN_GIF) AC_DEFINE(USE_OUT_GIF) AC_MSG_WARN(GIF is a resistered trademark of Compuserve; ask permission from them to use it!) else AC_MSG_RESULT(no) fi dnl Checks for programs. dnl AC_PROG_CC AC_LANG_CPLUSPLUS CXXFLAGS=" " dnl ^^^ set it to non-empty, so AC_PROG_CXX won't include `-g' CCC="$CCC g++" dnl ^^^ check g++ before c++ (see acspecific.m4, grep AC_PROG_CXX) AC_PROG_CXX AC_SUBST(GFLAG) if test x"$ac_cv_prog_cxx_g" = xyes; then GFLAG=-g; else GFLAG=""; fi dnl ac_cv_prog_cc_g also AC_PTS_PROG_CXXFLAGS(fs, -fsigned-char) AC_PTS_PROG_CXXFLAGS(nrne, -fno-rtti -fno-exceptions) dnl ^^^ `g++ -fno-rtti': disables `typeinfo' (??) and run-time type identification dnl ^^^ `g++ -fno-exceptions': disables catch and throw AC_PTS_PROG_CXXFLAGSB(apwaw, -ansi -pedantic -Wall -W) dnl vvv gcc-3.2 gives too many stupid warnings with -Wtraditional dnl AC_PTS_PROG_CXXFLAGSB(-Wtraditional) AC_PTS_PROG_CXXFLAGSB(ptscxxopts, -felide-constructors -Wstrict-prototypes dnl -Wpointer-arith -Wcast-align -Winline dnl -Wcast-qual -Wmissing-prototypes) AC_PTS_CHECK_IGNORING(nebfcmd,-W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations) if test x"$ac_cv_pts_ignoring_nebfcmd" = xyes then ac_cv_prog_cxx_nebfcmd=no fi AC_PTS_PROG_CXXFLAGSB(nebfcmd,-Wnested-externs -Wbad-function-cast -Wmissing-declarations) dnl vvv g++ version egcs-2.91.60 + gcc version 2.7.2.3 requires dnl `g++ -fno-rtti -fno-exceptions' for AC_PTS_GCC_LINKS_CXX to be `yes' AC_PTS_GCC_LINKS_CXX AC_PTS_WARN_PROG(cjpeg, [cjpeg is required for /Compression/IJG]) AC_PTS_WARN_PROG(djpeg, [djpeg is required for loading JPEG files]) AC_PTS_WARN_PROG(tif22pnm, [tif22pnm is required for loading TIFF files]) AC_PTS_WARN_PROG(tifftopnm, [tifftopnm might become useful for loading TIFF files]) AC_PTS_WARN_PROG(pngtopnm, [pngtopnm might become useful for loading PNG files]) dnl AC_PTS_WARN_PROG(gs, [gs is required for /Compression/Fax, and might become recommended for /Compression/ZIP]) AC_PTS_WARN_PROG(gs, [gs is recommended for viewing PS files[,] and might become recommended for /Compression/ZIP]) AC_PTS_WARN_PROG(lzw_codec, [lzw_codec might become recommended for /Compression/LZW]) AC_PTS_WARN_PROG(gzip, [gzip might become useful for /Compression/ZIP]) AC_PTS_WARN_PROG(zip, [zip might become useful for /Compression/ZIP]) AC_PTS_ERR_PROG(bash, [bash is required for compiling this program]) AC_PTS_ERR_PROG(make, [make is required for compiling this program]) AC_PTS_ERR_PROG(perl, [perl is required for compiling this program]) dnl AC_PTS_ERR_PROG(touch, [touch is required for compiling this program]) dnl ^^^ as of 0.37, touch is not required #AC_CHECK_PROG(ac_pts_cjpeg, cjpeg, yes) dnl Checks for C/C++ language features AC_PTS_HAVE_STDC AC_PTS_HAVE_SWITCH_ENUM_BUG AC_PTS_ENSURE_ASCII_SYSTEM AC_C_CONST AC_PTS_C_VOLATILE AC_PTS_HAVE_STATIC_CONST dnl Checks for libraries. dnl Checks for header files. dnl AC_CHECK_HEADERS(stdio.h); exit 42 dnl AC_CHECK_HEADERS(stdio.h stdlib.h unistd.h string.h strings.h) dnl Dat: getc_in_stdio fails for uClibc-0.9.14 _and_ `i386-uclibc-gcc -ansi' CXXFLAGS_save="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -ansi" AC_PTS_CHECK_HEADER(stdio.h, getc, getc_in_stdio, [return argc>42? getc(stdin)*0+1:0;]) AC_PTS_CHECK_HEADER(stdio.h, fgetc, fgetc_in_stdio, [return argc>42?fgetc(stdin)*0+1:0;]) AC_PTS_CHECK_HEADER(stdio.h, putc, putc_in_stdio, [return argc>42? putc(' ',stdout)*0+1:0;]) AC_PTS_CHECK_HEADER(stdio.h, fputc, fputc_in_stdio, [return argc>42?fputc(' ',stdout)*0+1:0;]) CXXFLAGS="$CXXFLAGS_save" AC_PTS_CHECK_HEADER(stdio.h, sprintf, sprintf_in_stdio, [char s[42]="X"; sprintf(s, "Hello, World!"); return *s!='H';] ) AC_PTS_CHECK_HEADER(stdlib.h, atoi, atoi_in_stdlib, [return atoi("42")!=42;]) AC_PTS_CHECK_HEADER(unistd.h, write, write_in_unistd, [return write(1,"what",0)!=0;]) AC_PTS_CHECK_HEADER(stdlib.h, system, system_in_stdlib, [/*>255 OK*/return system("true")!=0;]) AC_PTS_CHECK_HEADER(sys/stat.h, lstat, lstat_in_sys_stat,[struct stat st; return 0!=lstat("/",&st);]) AC_PTS_CHECK_STRING AC_PTS_CHECK_MALLOC AC_FUNC_ALLOCA AC_PTS_CFG_PRINTFGLEN AC_PTS_CFG_P_TMPDIR AC_PTS_HAVE_POPEN_ if test $ac_cv_pts_have_popen_ = yes; then ac_cv_pts_have_popen_b=no fi AC_PTS_HAVE_POPEN_B AC_PTS_HAVE_VSNPRINTF AC_PTS_HAVE_SYSTEMF dnl Checks for integral/pointer sizes. dnl AC_C_CHAR_UNSIGNED AC_PTS_CHECK_POINTERS dnl AC_PTS_CHECK_INTEGRALS -- alread in AC_PTS_CHECK_POINTERS dnl AC_REQUIRE([AC_PTS_CHECK_POINTERS]) dnl AC_REQUIRE([AC_PTS_CHECK_INTEGRALS]) dnl Dat: POINTERS, INTEGRALS order would result in `(cached)' without AC_REQUIRE dnl DAT: newer autoconfs disallow AC_REQUIRE(...) outside macros dnl ac_cv_alma=korte # Dat: automagically inserted into config.cache dnl AC_DEFINE(PTS_INT128_T, 42) # Dat: includes to conftest.h, config.h dnl cat confdefs.h # Dat: contains already AC_DEFINE()d symbols dnl Checks for typedefs, structures, and compiler characteristics. dnl AC_TYPE_SIZE_T AC_PTS_CHECK_INTEGRAL_TYPE(size_t, unsigned) dnl AC_PTS_CHECK_INTEGRAL_TYPE(time_t, unsigned) dnl AC_PTS_CHECK_INTEGRAL_TYPE(mode_t, int) dnl AC_PTS_CHECK_INTEGRAL_TYPE(off_t, long) dnl AC_PTS_CHECK_INTEGRAL_TYPE(pid_t, int) dnl AC_PTS_CHECK_INTEGRAL_TYPE(dev_t, unsigned long) dnl dnl ^^^ Dat: unsigned PTS_INT64_T on Linux i386 dnl AC_PTS_CHECK_INTEGRAL_TYPE(uid_t, unsigned) dnl AC_PTS_CHECK_INTEGRAL_TYPE(gid_t, unsigned) dnl AC_PTS_CHECK_INTEGRAL_TYPE(size_tt, signed) dnl Dat: AC_TYPE_SIGNAL is OK, there should be no AC_PTS_CHECK_* substitute dnl AC_PTS_TYPE_GETGROUPS dnl ^^^ doesn't work wth CPPFLAGS=-traditional AC_PTS_CHECK_SIZEOF(bool, -1) dnl ^^^ Dat: 0 #if (PC: 1, Digital Unix: 8, Solaris: 4) dnl ^^^ Dat: autoconf-2.54 AC_CHECK_SIZEOF checks sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h inttypes.h stdint.h unistd.h dnl Checks for library functions. dnl (None!) dnl Finishing. dnl AC_OUTPUT(config.h) -- bad!! dnl skipping AC_OUTPUT -- bad!! AC_OUTPUT(Makehelp) dnl AC_PTS_RUN_OK([perl -x -S ./ccdep.pl $CXX], [], [AC_MSG_ERROR(cannot compute depends)]) rm -f Makedep AC_PTS_RUN_OK([make Makedep], [], [AC_MSG_ERROR(cannot compute depends)]) AC_PTS_OK echo "configure done. Now you should run: make; make install" dnl end of configure.in sam2p-0.49.2/config2.h0000644000175100017510000002152512211371426012534 0ustar ptspts#ifndef CONFIG2_H #define CONFIG2_H 1 #include /* NDEBUG==1 means: no assertions */ #if NDEBUG # define ASSERT_SIDE(x) x /* assert with side effect */ # define ASSERT_SIDE2(x,y) x /* assert with side effect */ #else # define ASSERT_SIDE(x) assert(x) # define ASSERT_SIDE2(x,y) assert(x y) #endif #if _MSC_VER > 1000 # include "config-vc6.h" #else # if USE_CONFIG_MINGW_H # include "config-mingw.h" # else # if USE_CONFIG_UCLIBC_H # include "config-uclibc.h" # else # include "config.h" # endif # endif #endif #if 0 /* vvv i386 Debian slink gcc */ #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG 4 #define SIZEOF_LONG_LONG 8 #endif #if SIZEOF_CHAR_P!=SIZEOF_LONG && SIZEOF_INT>=4 typedef unsigned slen_t; typedef signed slendiff_t; # define SIZEOF_SLEN_T SIZEOF_INT # define SLEN_P "" #else typedef unsigned long slen_t; typedef signed long slendiff_t; # define SIZEOF_SLEN_T SIZEOF_LONG # define SLEN_P "l" #endif #if SIZEOF___INT64>SIZEOF_LONG # define HAVE_LONG_LONG 1 # define PTS_CFG_LONGEST __int64 /* may be used as signed CFG_LONGEST */ # define SIZEOF_CFG_LONGEST SIZEOF___INT64 #elif SIZEOF_LONG_LONG>SIZEOF_LONG # define HAVE_LONG_LONG 1 # define PTS_CFG_LONGEST long long /* may be used as signed CFG_LONGEST */ # define SIZEOF_CFG_LONGEST SIZEOF_LONG_LONG #elif SIZEOF_VERY_LONG>SIZEOF_LONG # define HAVE_LONG_LONG 1 # define PTS_CFG_LONGEST very long /* may be used as signed CFG_LONGEST */ # define SIZEOF_CFG_LONGEST SIZEOF_VERY_LONG #else # undef HAVE_LONG_LONG # define PTS_CFG_LONGEST long # define SIZEOF_CFG_LONGEST SIZEOF_LONG #endif #define NULLP ((void*)0) #define USE_IN_TIFF 1 #define USE_IN_JPEG 1 #define USE_IN_PNG 1 #define USE_IN_PCX 1 #define USE_IN_XPM 1 /* #define USE_IN_GIF 1 -- defined in */ #define USE_IN_PNM 1 #define USE_IN_BMP 1 #define USE_IN_PIP 1 /* simple paletted format defined by pts, but not implemented */ #define USE_IN_TGA 1 #define USE_IN_LBM 1 #define USE_IN_JAI 1 #define USE_IN_PDF 1 #define USE_IN_PS 1 /* #define USE_OUT_GIF 1 -- moved to config.h */ #define USE_IN_XPM_MAPPING 1 #define USE_BIG_MEMORY 1 #define USE_DICT_MAPPING 1 /* at Tue Jan 18 16:18:34 CET 2005 */ #define USE_ZLIB_MEM 1 /** Quotes a filename to be displayed in error messages */ /* #define FNQ(str) (str) */ #define FNQ(filename) SimBuffer::B().appendFnq(SimBuffer::Static(filename)) #define FNQ2(beg,len) SimBuffer::B().appendFnq(SimBuffer::Static(beg,len),true) #define FNQ2STDOK(beg,len) SimBuffer::B().appendFnq(SimBuffer::Static(beg,len),false) #define param_assert assert #undef __VA_START_STDC__ #ifdef __STDC__ # define __VA_START_STDC__ 1 #endif #if _MSC_VER > 1000 # undef __PROTOTYPES__ # define __PROTOTYPES__ 1 # undef __VA_START_STDC__ # define __VA_START_STDC__ 1 # pragma warning(disable: 4127) /* conditional expression is constant */ # pragma warning(disable: 4244) /* =' : conversion from 'int ' to 'unsigned char ', possible loss of data */ # pragma warning(disable: 4250) /* 'SimBuffer::B' : inherits 'SimBuffer::Flat::getLength' via dominance */ # pragma warning(disable: 4514) /* 'each_char' : unreferenced inline function has been removed */ # pragma warning(disable: 4512) /* 'PipeE' : assignment operator could not be generated */ # pragma warning(disable: 4310) /* cast truncates constant value */ # pragma warning(disable: 4355) /* 'this' : used in base member initializer list */ #endif #if __VA_START_STDC__ # define PTS_va_start(ap, fmt) va_start(ap, fmt) #else # define PTS_va_start(ap, fmt) va_start(ap) #endif #if HAVE_STATIC_CONST # define BEGIN_STATIC_ENUM(basetype,type) typedef basetype type; static const type # define BEGIN_STATIC_ENUM1(type) static const type # define END_STATIC_ENUM() ; #else /* VC6.0 */ # define BEGIN_STATIC_ENUM(basetype,type) enum type { # define BEGIN_STATIC_ENUM1(type) enum { # define END_STATIC_ENUM() }; #endif #if ((defined(__STDC__) || defined(__PROTOTYPES__)) && !defined(NO_PROTO)) || defined(__cplusplus) # define _(args) args # define OF(args) args # define ___(arg2s,arg1s,argafter) arg2s /* Dat: no direct comma allowed in args :-( */ #else # define _(args) () # define OF(args) () # define ___(arg2s,arg1s,argafter) arg1s argafter /* Dat: no direct comma allowed in args :-( */ #endif #if SIZEOF_BOOL!=1 #define bool PTS_bool #define true 1 #define false 0 typedef unsigned char bool; #endif #ifdef const # undef const # define PTS_const # undef HAVE_CONST #else # define PTS_const const # define HAVE_CONST 1 #endif #ifdef volatile # undef volatile # define PTS_volatile # undef HAVE_VOLATILE #else # define PTS_volatile volatile # define HAVE_VOLATILE 1 #endif #ifdef NEED_STRING_H /* We use: memset(), memmove(), strncpy(), memcpy(), memcmp() */ #if HAVE_MEMCMPY_BUILTIN # undef memcpy # define memcpy dummy_memcpy # undef memcmp # define memcmp dummy_memcmp #endif #ifdef HAVE_strcpy_in_string # include #elif HAVE_strcpy_in_strings # include #else # error no strcpy #endif #if HAVE_MEMCMPY_BUILTIN # undef memcmp # undef memcpy #endif #endif #ifdef NEED_MALLOC #if HAVE_malloc_in_stdlib # include #elif HAVE_PTS_STDC && HAVE_malloc_in_malloc # include #elif HAVE_PTS_STDC # error malloc() not found #elif HAVE_PROTOTYPES void *malloc(PTS_size_t size); void *realloc(void *ptr, PTS_size_t size); void free(void *ptr); #else void *malloc(); void *realloc(); void free(); #endif #endif #ifdef NEED_ALLOCA /* Make alloca work the best possible way. * Imp: AIX requires this to be the 1st thing in the file?? */ #ifdef __GNUC__ # ifndef atarist # ifndef alloca # define alloca __builtin_alloca # endif # endif /* atarist */ #elif defined(__BORLANDC__) # include #elif HAVE_ALLOCA_H # include #elif defined(_AIX) #pragma alloca /* indented to avoid choking of pre-ANSI compilers */ #elif !defined alloca /* predefined by HP cc +Olibcalls */ char *alloca (); #endif #endif /* NEED_ALLOCA */ #ifdef NEED_SIGN_EXTEND_CHAR /* We remove any previous definition of `SIGN_EXTEND_CHAR', since ours (we hope) works properly with all combinations of machines, compilers, `char' and `unsigned char' argument types. (Per Bothner suggested the basic approach.) */ #undef SIGN_EXTEND_CHAR #if HAVE_PTS_STDC # define SIGN_EXTEND_CHAR(c) ((signed char)(c)) #else /* not __STDC__ */ /* As in Harbison and Steele. */ # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128) #endif #endif /* by pts@fazekas.hu at Fri Mar 22 17:01:27 CET 2002 */ #if defined(HAVE_PTS_POPEN_) # define HAVE_PTS_POPEN 1 # define CFG_PTS_POPEN_B "" #elif defined(HAVE_PTS_POPEN_B) # define HAVE_PTS_POPEN 1 # define CFG_PTS_POPEN_B "b" #else # undef HAVE_PTS_POPEN #endif #undef NEED_LONG_LONG #undef NEED_LONG_DOUBLE /** Filename, directory and quoting conventions for the host OS. * 0: UNIX * 1: DOS/Win3.1 * 2: WinNT * 3: Win9X * 4: VMS * 5: Mac * 6... * * Imp: implement other than UNIX */ #define COTY_UNIX 0 #define COTY_DOS 1 #define COTY_WINNT 2 #define COTY_WIN9X 3 #define COTY_VMS 4 #define COTY_MAC 5 #define COTY_OTHER 6 #if HAVE_PTS_SYSTEMF_UNIX # define OS_COTY COTY_UNIX #else # if HAVE_PTS_SYSTEMF_WIN32 # define OS_COTY COTY_WIN9X # else # define OS_COTY COTY_OTHER # endif #endif /* vvv Imp: autodetect this */ #if defined(__MSDOS__) || defined(__CYGWIN__) || defined(__MINGW32__) || _MSC_VER > 1000 # define HAVE_DOS_BINARY 1 #else # undef HAVE_DOS_BINARY #endif /* #define PTS_dynamic_cast(ptrtype,ptr) dynamic_cast(ptr) -- would include special G++ symbols into .o */ #define PTS_dynamic_cast(ptrtype,ptr) ((ptrtype)(ptr)) /** Suppress effect of -Wcast-align warning */ #define PTS_align_cast(ptrtype,ptr) ((ptrtype)(void*)(ptr)) /** Suppress effect of -Wcast-align warning */ #define PTS_calign_cast(ptrtype,ptr) ((ptrtype)(void const*)(ptr)) #undef HAVE_LZW #if USE_BUILTIN_LZW # define HAVE_LZW 1 #else # define HAVE_LZW 1 /* try to use external lzw_codec */ #endif /* #define USE_BUILTIN_FAXE 1 */ /* in config.h */ #undef USE_BUILTIN_FAXD /* sure */ /* #define USE_BUILTIN_FAXD 1 */ /* in config.h */ #ifndef __cplusplus #undef true #undef false #ifdef __BEOS__ typedef unsigned char bool; #else typedef int bool; #endif #define true ((bool)1) #define false ((bool)0) #endif /* by pts@fazekas.hu at Tue Sep 3 18:47:47 CEST 2002 */ #if OBJDEP && defined(__cplusplus) && HAVE_PTS_C_LGCC_CPP_REQUIRED # warning REQUIRES: c_lgcc.o #endif #if OBJDEP && defined(__cplusplus) && HAVE_PTS_C_LGCC3_CPP_REQUIRED # warning REQUIRES: c_lgcc3.o #endif /* at Wed Aug 21 18:28:24 CEST 2002 */ #if HAVE_getc_in_stdio # define MACRO_GETC getc #else # if HAVE_fgetc_in_stdio # define MACRO_GETC fgetc # else # error getc() or fgetc() is required # endif #endif #if HAVE_putc_in_stdio # define MACRO_PUTC putc #else # if HAVE_fputc_in_stdio # define MACRO_PUTC fputc # else # error putc() or fputc() is required # endif #endif #endif /* config2.h */ sam2p-0.49.2/config.h.in0000644000175100017510000001071412211371426013055 0ustar ptspts/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if using alloca.c. */ #undef C_ALLOCA /* Define if type char is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ #undef __CHAR_UNSIGNED__ #endif /* Define to empty if the keyword does not work. */ #undef const /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if you have the ANSI # stringizing operator in cpp. */ #undef HAVE_STRINGIZE /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* A type name of a signed integral type of exactly 16 bits. Always defined. */ #undef PTS_INT16_T /* A type name of a signed integral type of exactly 32 bits. Always defined. */ #undef PTS_INT32_T /* A type name of a signed integral type of exactly 64 bits. Maybe left * 0-defined. */ #undef PTS_INT64_T /* A type name of a signed integral type of exactly 128 bits. Maybe left * 0-defined. */ #undef PTS_INT128_T /* A type name of a signed integral type which has space to hold a pointer. * Always defined. */ #undef PTS_INTP_T /* Imp: document this */ #undef PTS_INTP_OK /* Imp: document this */ #undef PTS_mode_t /* Imp: document this */ #undef PTS_off_t /* Imp: document this */ #undef PTS_pid_t /* Imp: document this */ #undef PTS_size_t /* Just a dummy, non-existent type. */ #undef PTS_size_tt /* Imp: document this */ #undef PTS_uid_t /* Imp: document this */ #undef PTS_gid_t /* Imp: document this */ #undef PTS_dev_t /* Does the C compiler support prototypes? */ #undef HAVE_PROTOTYPES /* Define to empty if the keyword does not work. */ #undef volatile /* Imp: document this */ #undef HAVE_strcpy_in_string /* Imp: document this */ #undef HAVE_strcpy_in_strings /* Imp: document these */ #undef HAVE_MEMCMPY_BUILTIN #undef HAVE_getc_in_stdio #undef HAVE_fgetc_in_stdio #undef HAVE_putc_in_stdio #undef HAVE_fputc_in_stdio #undef HAVE_atoi_in_stdlib #undef HAVE_malloc_in_malloc #undef HAVE_malloc_in_stdlib #undef HAVE_memcpy_in_stringxs #undef HAVE_sprintf_in_stdio #undef HAVE_write_in_unistd #undef HAVE_system_in_stdlib #undef HAVE_lstat_in_sys_stat #undef HAVE_PTS_STDC #undef HAVE_SWITCH_ENUM_BUG #undef HAVE_ASCII_SYSTEM #undef PTS_CFG_P_TMPDIR /** "" or ".16", so composing "%.16g" for printing doubles with printf(3) * will just print enough digits */ #define PTS_CFG_PRINTFGLEN ".16" /* Is the file c_gcc.cpp required for gcc when linking C++ programs? */ #undef HAVE_PTS_C_LGCC_CPP_REQUIRED #undef HAVE_PTS_C_LGCC3_CPP_REQUIRED /** Does the C library have a working vsnprintf()? */ #undef HAVE_PTS_VSNPRINTF #undef HAVE_PTS_VSNPRINTF_OLD #undef HAVE_PTS_VSNPRINTF_C99 /** What shell does the C library system(3) function call? */ #undef HAVE_PTS_SYSTEMF #undef HAVE_PTS_SYSTEMF_WIN32 #undef HAVE_PTS_SYSTEMF_UNIX #undef HAVE_PTS_SYSTEMF_OTHER /** popen("...","wb") and "rb" works binary */ #undef HAVE_PTS_POPEN_B /** popen("...","w") and "r" works binary */ #undef HAVE_PTS_POPEN_ /* The number of bytes in a __int64. */ #undef SIZEOF___INT64 /* The number of bytes in a bool. */ #undef SIZEOF_BOOL /* The number of bytes in a char. */ #undef SIZEOF_CHAR /* The number of bytes in a char *. */ #undef SIZEOF_CHAR_P /* The number of bytes in a int. */ #undef SIZEOF_INT /* The number of bytes in a long. */ #undef SIZEOF_LONG /* The number of bytes in a long long. */ #undef SIZEOF_LONG_LONG /* The number of bytes in a short. */ #undef SIZEOF_SHORT /* The number of bytes in a very long. */ #undef SIZEOF_VERY_LONG /* The number of bytes in a void *. */ #undef SIZEOF_VOID_P /* Can have static const int VARNAME=1; inside a class { ... } ? */ #undef HAVE_STATIC_CONST /* sam2p-specific */ #undef USE_BUILTIN_ZIP #undef USE_BUILTIN_FAXE #undef USE_BUILTIN_LZW #undef USE_IN_GIF #undef USE_OUT_GIF sam2p-0.49.2/configure0000755000175100017510000065425112211371426012753 0ustar ptspts#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="gensi.cpp" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS ENABLE_DEBUG CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT GFLAG CXXFLAGSB LDXX pts_cjpeg pts_djpeg pts_tif22pnm pts_tifftopnm pts_pngtopnm pts_gs pts_lzw_codec pts_gzip pts_zip pts_bash pts_make pts_perl CXXCPP EGREP ALLOCA LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CXXCPP_set=${CXXCPP+set} ac_env_CXXCPP_value=$CXXCPP ac_cv_env_CXXCPP_set=${CXXCPP+set} ac_cv_env_CXXCPP_value=$CXXCPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-debug=val val: no, assert(default), yes, checker --enable-lzw enable built-in LZW (de)compression (def: no) --enable-zip enable built-in ZIP compression (def: yes) --enable-fax enable built-in Fax compression (def: yes) --enable-gif enable reading and writing GIF images (def: no) Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" echo "$as_me:$LINENO: checking for --enable-debug" >&5 echo $ECHO_N "checking for --enable-debug... $ECHO_C" >&6 # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" fi; ENABLE_DEBUG="$enable_debug" if test x"$enable_debug" = xno; then echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 elif test x"$enable_debug" = x || test x"$enable_debug" = xassert; then echo "$as_me:$LINENO: result: assert" >&5 echo "${ECHO_T}assert" >&6 ENABLE_DEBUG=assert elif test x"$enable_debug" = xyes; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 elif test x"$enable_debug" = xchecker; then echo "$as_me:$LINENO: result: checker" >&5 echo "${ECHO_T}checker" >&6 else echo "$as_me:$LINENO: result: \"?? $enable_debug\"" >&5 echo "${ECHO_T}\"?? $enable_debug\"" >&6 { { echo "$as_me:$LINENO: error: Invalid --enable--debug option specified." >&5 echo "$as_me: error: Invalid --enable--debug option specified." >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: checking for --enable-lzw" >&5 echo $ECHO_N "checking for --enable-lzw... $ECHO_C" >&6 # Check whether --enable-lzw or --disable-lzw was given. if test "${enable_lzw+set}" = set; then enableval="$enable_lzw" fi; if test x1 = x"`perl -e 'print time>1056165811'`"; then # After 19 June 2003: default: yes if test x"$enable_lzw" = x"no"; then echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define USE_BUILTIN_LZW 1 _ACEOF fi else if test x"$enable_lzw" = x"yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define USE_BUILTIN_LZW 1 _ACEOF { echo "$as_me:$LINENO: WARNING: LZW is patented till 19 June 2003; ask permission from Unisys to use it!" >&5 echo "$as_me: WARNING: LZW is patented till 19 June 2003; ask permission from Unisys to use it!" >&2;} else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi echo "$as_me:$LINENO: checking for --enable-zip" >&5 echo $ECHO_N "checking for --enable-zip... $ECHO_C" >&6 # Check whether --enable-zip or --disable-zip was given. if test "${enable_zip+set}" = set; then enableval="$enable_zip" fi; if test x"$enable_zip" = x"no"; then echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define USE_BUILTIN_ZIP 1 _ACEOF fi echo "$as_me:$LINENO: checking for --enable-fax" >&5 echo $ECHO_N "checking for --enable-fax... $ECHO_C" >&6 # Check whether --enable-fax or --disable-fax was given. if test "${enable_fax+set}" = set; then enableval="$enable_fax" fi; if test x"$enable_fax" = x"no"; then echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define USE_BUILTIN_FAXE 1 _ACEOF fi echo "$as_me:$LINENO: checking for --enable-gif" >&5 echo $ECHO_N "checking for --enable-gif... $ECHO_C" >&6 # Check whether --enable-gif or --disable-gif was given. if test "${enable_gif+set}" = set; then enableval="$enable_gif" fi; if test x"$enable_gif" = x"yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define USE_IN_GIF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_OUT_GIF 1 _ACEOF { echo "$as_me:$LINENO: WARNING: GIF is a resistered trademark of Compuserve; ask permission from them to use it!" >&5 echo "$as_me: WARNING: GIF is a resistered trademark of Compuserve; ask permission from them to use it!" >&2;} else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CXXFLAGS=" " CCC="$CCC g++" ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C++ compiler default output" >&5 echo $ECHO_N "checking for C++ compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi : ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x"$ac_cv_prog_cxx_g" = xyes; then GFLAG=-g; else GFLAG=""; fi echo "$as_me:$LINENO: checking whether ${CXX-g++} accepts -fsigned-char" >&5 echo $ECHO_N "checking whether ${CXX-g++} accepts -fsigned-char... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_fs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} -fsigned-char -c conftest.cc 2>&1`" then ac_cv_prog_cxx_fs=yes; else ac_cv_prog_cxx_fs=no; fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_fs" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_fs" >&6 if test $ac_cv_prog_cxx_fs = yes; then CXXFLAGS="$CXXFLAGS -fsigned-char"; fi echo "$as_me:$LINENO: checking whether ${CXX-g++} accepts -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking whether ${CXX-g++} accepts -fno-rtti -fno-exceptions... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_nrne+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} -fno-rtti -fno-exceptions -c conftest.cc 2>&1`" then ac_cv_prog_cxx_nrne=yes; else ac_cv_prog_cxx_nrne=no; fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_nrne" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_nrne" >&6 if test $ac_cv_prog_cxx_nrne = yes; then CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions"; fi echo "$as_me:$LINENO: checking whether ${CXX-g++} accepts -ansi -pedantic -Wall -W" >&5 echo $ECHO_N "checking whether ${CXX-g++} accepts -ansi -pedantic -Wall -W... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_apwaw+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} -ansi -pedantic -Wall -W -c conftest.cc 2>&1`" then ac_cv_prog_cxx_apwaw=yes; else ac_cv_prog_cxx_apwaw=no; fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_apwaw" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_apwaw" >&6 if test $ac_cv_prog_cxx_apwaw = yes; then CXXFLAGSB="$CXXFLAGSB -ansi -pedantic -Wall -W"; fi echo "$as_me:$LINENO: checking whether ${CXX-g++} accepts -felide-constructors -Wstrict-prototypes -Wpointer-arith -Wcast-align -Winline -Wcast-qual -Wmissing-prototypes" >&5 echo $ECHO_N "checking whether ${CXX-g++} accepts -felide-constructors -Wstrict-prototypes -Wpointer-arith -Wcast-align -Winline -Wcast-qual -Wmissing-prototypes... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_ptscxxopts+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} -felide-constructors -Wstrict-prototypes -Wpointer-arith -Wcast-align -Winline -Wcast-qual -Wmissing-prototypes -c conftest.cc 2>&1`" then ac_cv_prog_cxx_ptscxxopts=yes; else ac_cv_prog_cxx_ptscxxopts=no; fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_ptscxxopts" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_ptscxxopts" >&6 if test $ac_cv_prog_cxx_ptscxxopts = yes; then CXXFLAGSB="$CXXFLAGSB -felide-constructors -Wstrict-prototypes -Wpointer-arith -Wcast-align -Winline -Wcast-qual -Wmissing-prototypes"; fi XTRA="-W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations" CC_bak="$CC" CC="${CC:-cc} -Werror -W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations" CXX_bak="$CXX" CXX="${CXX:-c++} -Werror -W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations" echo "$as_me:$LINENO: checking for ignored -W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations" >&5 echo $ECHO_N "checking for ignored -W -Wall -Wnested-externs -Wbad-function-cast -Wmissing-declarations... $ECHO_C" >&6 if test "${ac_cv_pts_ignoring_nebfcmd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_ignoring_nebfcmd=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_pts_ignoring_nebfcmd=yes fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_pts_ignoring_nebfcmd" >&5 echo "${ECHO_T}$ac_cv_pts_ignoring_nebfcmd" >&6 CC="$CC_bak" CXX="$CXX_bak" if test x"$ac_cv_pts_ignoring_nebfcmd" = xyes then ac_cv_prog_cxx_nebfcmd=no fi echo "$as_me:$LINENO: checking whether ${CXX-g++} accepts -Wnested-externs -Wbad-function-cast -Wmissing-declarations" >&5 echo $ECHO_N "checking whether ${CXX-g++} accepts -Wnested-externs -Wbad-function-cast -Wmissing-declarations... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_nebfcmd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else echo 'void f(void);void f(void){}' > conftest.cc if test -z "`${CXX-g++} -Wnested-externs -Wbad-function-cast -Wmissing-declarations -c conftest.cc 2>&1`" then ac_cv_prog_cxx_nebfcmd=yes; else ac_cv_prog_cxx_nebfcmd=no; fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_nebfcmd" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_nebfcmd" >&6 if test $ac_cv_prog_cxx_nebfcmd = yes; then CXXFLAGSB="$CXXFLAGSB -Wnested-externs -Wbad-function-cast -Wmissing-declarations"; fi echo "$as_me:$LINENO: checking whether gcc can link C++ code" >&5 echo $ECHO_N "checking whether gcc can link C++ code... $ECHO_C" >&6 if test "${ac_cv_pts_gcc_links_cxx+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else CXX_saved="$CXX" LIBS_saved="$LIBS" CXX_new="$CXX" ac_ext_saved="$ac_ext" cat > conftest.$ac_ext < struct B { virtual int f()=0; int x() { return f(); } }; struct C1: public B { virtual int f() {return 1;}}; struct C2: public B { virtual int f() {return 2;}}; C1 global; /* global.x() will cause segfault in i386-uclibc-gcc */ int main() { /* vvv (B*) cast added for gcc-3.1 */ B *p=(ferror(stderr))?(B*)new C1():(B*)new C2(); /* Imp: argc... */ /* if (p==0) throw long(42); */ /* doesn't work with -fno-rtti */ int ok2=p->x()==2; delete p; return !(ok2 && global.x()==1); ; return 0; } EOF if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case x"$CC" in xgcc-*) CXX="$CC" ;; # gcc-3.2 x*-gcc-*) CXX="$CC" ;; # x*-gcc) CXX="$CC" ;; # i386-uclibc-gcc *) CXX=gcc ;; esac CXX_new="$CXX" ac_ext="$ac_objext" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes else LIBS="$LIBS_saved c_lgcc.cpp" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes-with-help else LIBS="$LIBS_saved c_lgcc3.cpp" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} && ./conftest${ac_exeext} then ac_cv_pts_gcc_links_cxx=yes-with-help3 else ac_cv_pts_gcc_links_cxx=no; CXX_new="$CXX_saved"; fi fi fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_pts_gcc_links_cxx=compilation-failed fi rm -f conftest* CXX="$CXX_saved" LIBS="$LIBS_saved" ac_ext="$ac_ext_saved" fi echo "$as_me:$LINENO: result: $ac_cv_pts_gcc_links_cxx" >&5 echo "${ECHO_T}$ac_cv_pts_gcc_links_cxx" >&6 case x"$ac_cv_pts_gcc_links_cxx" in xyes-with-help) LDXX="$CXX_new"; cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_C_LGCC_CPP_REQUIRED 1 _ACEOF ;; xyes-with-help3) LDXX="$CXX_new"; cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_C_LGCC3_CPP_REQUIRED 1 _ACEOF ;; xyes) LDXX="$CXX_new" ;; xno) LDXX="$CXX_new" ;; *) { { echo "$as_me:$LINENO: error: Compilation failed, aborting." >&5 echo "$as_me: error: Compilation failed, aborting." >&2;} { (exit 1); exit 1; }; } ;; esac # Extract the first word of "cjpeg", so it can be a program name with args. set dummy cjpeg; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_cjpeg+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_cjpeg" in /*) ac_cv_path_pts_cjpeg="$pts_cjpeg" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_cjpeg="$pts_cjpeg" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_cjpeg="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_cjpeg="$ac_cv_path_pts_cjpeg" if test -n "$pts_cjpeg"; then echo "$as_me:$LINENO: result: $pts_cjpeg" >&5 echo "${ECHO_T}$pts_cjpeg" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_cjpeg" = x; then { echo "$as_me:$LINENO: WARNING: cjpeg would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: cjpeg would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: cjpeg is required for /Compression/IJG" >&5 echo "$as_me: WARNING: cjpeg is required for /Compression/IJG" >&2;} fi # Extract the first word of "djpeg", so it can be a program name with args. set dummy djpeg; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_djpeg+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_djpeg" in /*) ac_cv_path_pts_djpeg="$pts_djpeg" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_djpeg="$pts_djpeg" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_djpeg="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_djpeg="$ac_cv_path_pts_djpeg" if test -n "$pts_djpeg"; then echo "$as_me:$LINENO: result: $pts_djpeg" >&5 echo "${ECHO_T}$pts_djpeg" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_djpeg" = x; then { echo "$as_me:$LINENO: WARNING: djpeg would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: djpeg would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: djpeg is required for loading JPEG files" >&5 echo "$as_me: WARNING: djpeg is required for loading JPEG files" >&2;} fi # Extract the first word of "tif22pnm", so it can be a program name with args. set dummy tif22pnm; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_tif22pnm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_tif22pnm" in /*) ac_cv_path_pts_tif22pnm="$pts_tif22pnm" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_tif22pnm="$pts_tif22pnm" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_tif22pnm="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_tif22pnm="$ac_cv_path_pts_tif22pnm" if test -n "$pts_tif22pnm"; then echo "$as_me:$LINENO: result: $pts_tif22pnm" >&5 echo "${ECHO_T}$pts_tif22pnm" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_tif22pnm" = x; then { echo "$as_me:$LINENO: WARNING: tif22pnm would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: tif22pnm would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: tif22pnm is required for loading TIFF files" >&5 echo "$as_me: WARNING: tif22pnm is required for loading TIFF files" >&2;} fi # Extract the first word of "tifftopnm", so it can be a program name with args. set dummy tifftopnm; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_tifftopnm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_tifftopnm" in /*) ac_cv_path_pts_tifftopnm="$pts_tifftopnm" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_tifftopnm="$pts_tifftopnm" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_tifftopnm="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_tifftopnm="$ac_cv_path_pts_tifftopnm" if test -n "$pts_tifftopnm"; then echo "$as_me:$LINENO: result: $pts_tifftopnm" >&5 echo "${ECHO_T}$pts_tifftopnm" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_tifftopnm" = x; then { echo "$as_me:$LINENO: WARNING: tifftopnm would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: tifftopnm would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: tifftopnm might become useful for loading TIFF files" >&5 echo "$as_me: WARNING: tifftopnm might become useful for loading TIFF files" >&2;} fi # Extract the first word of "pngtopnm", so it can be a program name with args. set dummy pngtopnm; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_pngtopnm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_pngtopnm" in /*) ac_cv_path_pts_pngtopnm="$pts_pngtopnm" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_pngtopnm="$pts_pngtopnm" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_pngtopnm="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_pngtopnm="$ac_cv_path_pts_pngtopnm" if test -n "$pts_pngtopnm"; then echo "$as_me:$LINENO: result: $pts_pngtopnm" >&5 echo "${ECHO_T}$pts_pngtopnm" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_pngtopnm" = x; then { echo "$as_me:$LINENO: WARNING: pngtopnm would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: pngtopnm would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: pngtopnm might become useful for loading PNG files" >&5 echo "$as_me: WARNING: pngtopnm might become useful for loading PNG files" >&2;} fi # Extract the first word of "gs", so it can be a program name with args. set dummy gs; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_gs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_gs" in /*) ac_cv_path_pts_gs="$pts_gs" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_gs="$pts_gs" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_gs="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_gs="$ac_cv_path_pts_gs" if test -n "$pts_gs"; then echo "$as_me:$LINENO: result: $pts_gs" >&5 echo "${ECHO_T}$pts_gs" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_gs" = x; then { echo "$as_me:$LINENO: WARNING: gs would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: gs would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: gs is recommended for viewing PS files, and might become recommended for /Compression/ZIP" >&5 echo "$as_me: WARNING: gs is recommended for viewing PS files, and might become recommended for /Compression/ZIP" >&2;} fi # Extract the first word of "lzw_codec", so it can be a program name with args. set dummy lzw_codec; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_lzw_codec+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_lzw_codec" in /*) ac_cv_path_pts_lzw_codec="$pts_lzw_codec" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_lzw_codec="$pts_lzw_codec" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_lzw_codec="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_lzw_codec="$ac_cv_path_pts_lzw_codec" if test -n "$pts_lzw_codec"; then echo "$as_me:$LINENO: result: $pts_lzw_codec" >&5 echo "${ECHO_T}$pts_lzw_codec" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_lzw_codec" = x; then { echo "$as_me:$LINENO: WARNING: lzw_codec would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: lzw_codec would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: lzw_codec might become recommended for /Compression/LZW" >&5 echo "$as_me: WARNING: lzw_codec might become recommended for /Compression/LZW" >&2;} fi # Extract the first word of "gzip", so it can be a program name with args. set dummy gzip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_gzip+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_gzip" in /*) ac_cv_path_pts_gzip="$pts_gzip" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_gzip="$pts_gzip" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_gzip="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_gzip="$ac_cv_path_pts_gzip" if test -n "$pts_gzip"; then echo "$as_me:$LINENO: result: $pts_gzip" >&5 echo "${ECHO_T}$pts_gzip" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_gzip" = x; then { echo "$as_me:$LINENO: WARNING: gzip would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: gzip would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: gzip might become useful for /Compression/ZIP" >&5 echo "$as_me: WARNING: gzip might become useful for /Compression/ZIP" >&2;} fi # Extract the first word of "zip", so it can be a program name with args. set dummy zip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_zip+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_zip" in /*) ac_cv_path_pts_zip="$pts_zip" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_zip="$pts_zip" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_zip="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_zip="$ac_cv_path_pts_zip" if test -n "$pts_zip"; then echo "$as_me:$LINENO: result: $pts_zip" >&5 echo "${ECHO_T}$pts_zip" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_zip" = x; then { echo "$as_me:$LINENO: WARNING: zip would provide increased functionality to this program:" >&5 echo "$as_me: WARNING: zip would provide increased functionality to this program:" >&2;} { echo "$as_me:$LINENO: WARNING: zip might become useful for /Compression/ZIP" >&5 echo "$as_me: WARNING: zip might become useful for /Compression/ZIP" >&2;} fi # Extract the first word of "bash", so it can be a program name with args. set dummy bash; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_bash+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_bash" in /*) ac_cv_path_pts_bash="$pts_bash" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_bash="$pts_bash" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_bash="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_bash="$ac_cv_path_pts_bash" if test -n "$pts_bash"; then echo "$as_me:$LINENO: result: $pts_bash" >&5 echo "${ECHO_T}$pts_bash" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_bash" = x; then { echo "$as_me:$LINENO: WARNING: bash is required:" >&5 echo "$as_me: WARNING: bash is required:" >&2;} { { echo "$as_me:$LINENO: error: bash is required for compiling this program" >&5 echo "$as_me: error: bash is required for compiling this program" >&2;} { (exit 1); exit 1; }; } fi # Extract the first word of "make", so it can be a program name with args. set dummy make; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_make+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_make" in /*) ac_cv_path_pts_make="$pts_make" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_make="$pts_make" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_make="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_make="$ac_cv_path_pts_make" if test -n "$pts_make"; then echo "$as_me:$LINENO: result: $pts_make" >&5 echo "${ECHO_T}$pts_make" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_make" = x; then { echo "$as_me:$LINENO: WARNING: make is required:" >&5 echo "$as_me: WARNING: make is required:" >&2;} { { echo "$as_me:$LINENO: error: make is required for compiling this program" >&5 echo "$as_me: error: make is required for compiling this program" >&2;} { (exit 1); exit 1; }; } fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_pts_perl+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$pts_perl" in /*) ac_cv_path_pts_perl="$pts_perl" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_pts_perl="$pts_perl" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -x $ac_dir/$ac_word; then ac_cv_path_pts_perl="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi pts_perl="$ac_cv_path_pts_perl" if test -n "$pts_perl"; then echo "$as_me:$LINENO: result: $pts_perl" >&5 echo "${ECHO_T}$pts_perl" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test x"$ac_cv_path_pts_perl" = x; then { echo "$as_me:$LINENO: WARNING: perl is required:" >&5 echo "$as_me: WARNING: perl is required:" >&2;} { { echo "$as_me:$LINENO: error: perl is required for compiling this program" >&5 echo "$as_me: error: perl is required for compiling this program" >&2;} { (exit 1); exit 1; }; } fi #AC_CHECK_PROG(ac_pts_cjpeg, cjpeg, yes) ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6 ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi echo "$as_me:$LINENO: checking whether cc supports prototypes" >&5 echo $ECHO_N "checking whether cc supports prototypes... $ECHO_C" >&6 if test "${ac_cv_pts_have_prototypes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int foo(int x) { return 0; } int main () { return foo(10); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_prototypes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_pts_have_prototypes=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_prototypes" >&5 echo "${ECHO_T}$ac_cv_pts_have_prototypes" >&6 if test x"$ac_cv_pts_have_prototypes" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PROTOTYPES 1 _ACEOF fi echo "$as_me:$LINENO: checking whether cc compiles standard C" >&5 echo $ECHO_N "checking whether cc compiles standard C... $ECHO_C" >&6 if test "${ac_cv_pts_have_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined(__STDC__) && __STDC__ /* note: the starting spaces are deliberate in the next line */ #if 0 nope #endif #else #if defined(__cplusplus) && __cplusplus #if 0 nope #endif #else nope #endif #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "nope" >/dev/null 2>&1; then ac_cv_pts_have_stdc=no else if test x"$ac_cv_pts_have_prototypes" = xyes; then ac_cv_pts_have_stdc=yes else ac_cv_pts_have_stdc=no fi fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_stdc" >&5 echo "${ECHO_T}$ac_cv_pts_have_stdc" >&6 if test x"$ac_cv_pts_have_stdc" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_STDC 1 _ACEOF fi echo "$as_me:$LINENO: checking for switch(enum) bug" >&5 echo $ECHO_N "checking for switch(enum) bug... $ECHO_C" >&6 if test "${ac_cv_pts_have_switch_enum_bug+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_HAVE_SWITCH_ENUM_BUG" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_HAVE_SWITCH_ENUM_BUG" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ enum what { foo, bar }; int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { switch ((enum what)1) { case foo: return 1; case bar: return 0; } return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_switch_enum_bug=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_have_switch_enum_bug=yes fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_switch_enum_bug" >&5 echo "${ECHO_T}$ac_cv_pts_have_switch_enum_bug" >&6 if test x"$ac_cv_pts_have_switch_enum_bug" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SWITCH_ENUM_BUG 1 _ACEOF fi echo "$as_me:$LINENO: checking for ASCII system" >&5 echo $ECHO_N "checking for ASCII system... $ECHO_C" >&6 if test "${ac_cv_pts_have_ascii_system+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if 'a'!=97 || '!'!=33 #error You need an ASCII system to compile this. #else ascii_yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ascii_yes" >/dev/null 2>&1; then ac_cv_pts_have_ascii_system=yes else ac_cv_pts_have_ascii_system=no fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_ascii_system" >&5 echo "${ECHO_T}$ac_cv_pts_have_ascii_system" >&6 if test x"$ac_cv_pts_have_ascii_system" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ASCII_SYSTEM 1 _ACEOF fi if test x"$ac_cv_pts_have_ascii_system" != xyes; then { { echo "$as_me:$LINENO: error: you need an ASCII system" >&5 echo "$as_me: error: you need an ASCII system" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for C keyword volatile" >&5 echo $ECHO_N "checking for C keyword volatile... $ECHO_C" >&6 if test "${ac_cv_pts_have_volatile+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ volatile int i; int main () { i=5; i++; return i-6; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_volatile=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_pts_have_volatile=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_volatile" >&5 echo "${ECHO_T}$ac_cv_pts_have_volatile" >&6 if test x"$ac_cv_pts_have_volatile" = xno; then cat >>confdefs.h <<\_ACEOF #define volatile _ACEOF fi echo "$as_me:$LINENO: checking whether c++ supports static const" >&5 echo $ECHO_N "checking whether c++ supports static const... $ECHO_C" >&6 if test "${ac_cv_pts_have_static_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #undef const class A { public: static const int i=1; }; int main () { return A::i==0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_static_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_pts_have_static_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_static_const" >&5 echo "${ECHO_T}$ac_cv_pts_have_static_const" >&6 if test x"$ac_cv_pts_have_static_const" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STATIC_CONST 1 _ACEOF fi CXXFLAGS_save="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -ansi" echo "$as_me:$LINENO: checking for working getc in stdio.h" >&5 echo $ECHO_N "checking for working getc in stdio.h... $ECHO_C" >&6 if test "${ac_cv_pts_getc_in_stdio+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return argc>42? getc(stdin)*0+1:0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_getc_in_stdio=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_getc_in_stdio=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_getc_in_stdio" >&5 echo "${ECHO_T}$ac_cv_pts_getc_in_stdio" >&6 if test x"$ac_cv_pts_getc_in_stdio" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_getc_in_stdio 1 _ACEOF fi echo "$as_me:$LINENO: checking for working fgetc in stdio.h" >&5 echo $ECHO_N "checking for working fgetc in stdio.h... $ECHO_C" >&6 if test "${ac_cv_pts_fgetc_in_stdio+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return argc>42?fgetc(stdin)*0+1:0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_fgetc_in_stdio=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_fgetc_in_stdio=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_fgetc_in_stdio" >&5 echo "${ECHO_T}$ac_cv_pts_fgetc_in_stdio" >&6 if test x"$ac_cv_pts_fgetc_in_stdio" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_fgetc_in_stdio 1 _ACEOF fi echo "$as_me:$LINENO: checking for working putc in stdio.h" >&5 echo $ECHO_N "checking for working putc in stdio.h... $ECHO_C" >&6 if test "${ac_cv_pts_putc_in_stdio+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return argc>42? putc(' ',stdout)*0+1:0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_putc_in_stdio=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_putc_in_stdio=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_putc_in_stdio" >&5 echo "${ECHO_T}$ac_cv_pts_putc_in_stdio" >&6 if test x"$ac_cv_pts_putc_in_stdio" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_putc_in_stdio 1 _ACEOF fi echo "$as_me:$LINENO: checking for working fputc in stdio.h" >&5 echo $ECHO_N "checking for working fputc in stdio.h... $ECHO_C" >&6 if test "${ac_cv_pts_fputc_in_stdio+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return argc>42?fputc(' ',stdout)*0+1:0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_fputc_in_stdio=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_fputc_in_stdio=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_fputc_in_stdio" >&5 echo "${ECHO_T}$ac_cv_pts_fputc_in_stdio" >&6 if test x"$ac_cv_pts_fputc_in_stdio" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_fputc_in_stdio 1 _ACEOF fi CXXFLAGS="$CXXFLAGS_save" echo "$as_me:$LINENO: checking for working sprintf in stdio.h" >&5 echo $ECHO_N "checking for working sprintf in stdio.h... $ECHO_C" >&6 if test "${ac_cv_pts_sprintf_in_stdio+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; sprintf(s, "Hello, World!"); return *s!='H'; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_sprintf_in_stdio=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_sprintf_in_stdio=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_sprintf_in_stdio" >&5 echo "${ECHO_T}$ac_cv_pts_sprintf_in_stdio" >&6 if test x"$ac_cv_pts_sprintf_in_stdio" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_sprintf_in_stdio 1 _ACEOF fi echo "$as_me:$LINENO: checking for working atoi in stdlib.h" >&5 echo $ECHO_N "checking for working atoi in stdlib.h... $ECHO_C" >&6 if test "${ac_cv_pts_atoi_in_stdlib+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return atoi("42")!=42; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_atoi_in_stdlib=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_atoi_in_stdlib=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_atoi_in_stdlib" >&5 echo "${ECHO_T}$ac_cv_pts_atoi_in_stdlib" >&6 if test x"$ac_cv_pts_atoi_in_stdlib" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_atoi_in_stdlib 1 _ACEOF fi echo "$as_me:$LINENO: checking for working write in unistd.h" >&5 echo $ECHO_N "checking for working write in unistd.h... $ECHO_C" >&6 if test "${ac_cv_pts_write_in_unistd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { return write(1,"what",0)!=0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_write_in_unistd=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_write_in_unistd=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_write_in_unistd" >&5 echo "${ECHO_T}$ac_cv_pts_write_in_unistd" >&6 if test x"$ac_cv_pts_write_in_unistd" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_write_in_unistd 1 _ACEOF fi echo "$as_me:$LINENO: checking for working system in stdlib.h" >&5 echo $ECHO_N "checking for working system in stdlib.h... $ECHO_C" >&6 if test "${ac_cv_pts_system_in_stdlib+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { /*>255 OK*/return system("true")!=0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_system_in_stdlib=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_system_in_stdlib=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_system_in_stdlib" >&5 echo "${ECHO_T}$ac_cv_pts_system_in_stdlib" >&6 if test x"$ac_cv_pts_system_in_stdlib" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_system_in_stdlib 1 _ACEOF fi echo "$as_me:$LINENO: checking for working lstat in sys/stat.h" >&5 echo $ECHO_N "checking for working lstat in sys/stat.h... $ECHO_C" >&6 if test "${ac_cv_pts_lstat_in_sys_stat+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { struct stat st; return 0!=lstat("/",&st); return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_lstat_in_sys_stat=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_lstat_in_sys_stat=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_lstat_in_sys_stat" >&5 echo "${ECHO_T}$ac_cv_pts_lstat_in_sys_stat" >&6 if test x"$ac_cv_pts_lstat_in_sys_stat" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_lstat_in_sys_stat 1 _ACEOF fi echo "$as_me:$LINENO: checking for working strcpy in string.h" >&5 echo $ECHO_N "checking for working strcpy in string.h... $ECHO_C" >&6 if test "${ac_cv_pts_strcpy_in_string+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; strcpy(s, "Hello, World!"); return *s!='H'; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_strcpy_in_string=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_strcpy_in_string=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_strcpy_in_string" >&5 echo "${ECHO_T}$ac_cv_pts_strcpy_in_string" >&6 if test x"$ac_cv_pts_strcpy_in_string" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_strcpy_in_string 1 _ACEOF fi ac_cv_pts_have_string=no if test x"$ac_cv_pts_strcpy_in_string" = xyes; then ac_cv_pts_have_string=yes ac_cv_pts_string_header=string else echo "$as_me:$LINENO: checking for working strcpy in strings.h" >&5 echo $ECHO_N "checking for working strcpy in strings.h... $ECHO_C" >&6 if test "${ac_cv_pts_strcpy_in_strings+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; strcpy(s, "Hello, World!"); return *s!='H'; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_strcpy_in_strings=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_strcpy_in_strings=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_strcpy_in_strings" >&5 echo "${ECHO_T}$ac_cv_pts_strcpy_in_strings" >&6 if test x"$ac_cv_pts_strcpy_in_strings" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_strcpy_in_strings 1 _ACEOF fi if test x"$ac_cv_pts_strcpy_in_strings" = xyes; then ac_cv_pts_have_string=yes ac_cv_pts_string_header=strings fi fi if test x"$ac_cv_pts_have_string" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRING 1 _ACEOF fi CC_bak="$CC" CC="${CC:-cc} -Werror" echo "$as_me:$LINENO: checking for working memcpy in $ac_cv_pts_string_header.h" >&5 echo $ECHO_N "checking for working memcpy in $ac_cv_pts_string_header.h... $ECHO_C" >&6 if test "${ac_cv_pts_memcpy_in_stringxs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include <$ac_cv_pts_string_header.h> #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; memcpy(s, "Hello, World!", 2); return *s!='H'; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_memcpy_in_stringxs=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_memcpy_in_stringxs=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_memcpy_in_stringxs" >&5 echo "${ECHO_T}$ac_cv_pts_memcpy_in_stringxs" >&6 if test x"$ac_cv_pts_memcpy_in_stringxs" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_memcpy_in_stringxs 1 _ACEOF fi CC="$CC_bak" echo "$as_me:$LINENO: checking whether memcmp and memcpy are built-in" >&5 echo $ECHO_N "checking whether memcmp and memcpy are built-in... $ECHO_C" >&6 if test "${ac_cv_pts_have_memcmpy_builtin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_pts_have_memcmpy_builtin=no if test x"$ac_cv_pts_have_string" = xyes; then if test x"$ac_cv_pts_memcpy_in_stringxs" = xno; then if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_STRING" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_STRING" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char s[42]="X"; memcpy(s, "Hello, World!", 2); return memcmp(s, "H", 1)!=0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_memcmpy_builtin=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: missing memcmp and memcpy" >&5 echo "$as_me: error: missing memcmp and memcpy" >&2;} { (exit 1); exit 1; }; } fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_memcmpy_builtin" >&5 echo "${ECHO_T}$ac_cv_pts_have_memcmpy_builtin" >&6 if test x"$ac_cv_pts_have_memcmpy_builtin" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MEMCMPY_BUILTIN 1 _ACEOF fi echo "$as_me:$LINENO: checking for working malloc in stdlib.h" >&5 echo $ECHO_N "checking for working malloc in stdlib.h... $ECHO_C" >&6 if test "${ac_cv_pts_malloc_in_stdlib+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char *p=(char*)malloc(42); if (p!=0) free((void*)p); return p==0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_malloc_in_stdlib=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_malloc_in_stdlib=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_malloc_in_stdlib" >&5 echo "${ECHO_T}$ac_cv_pts_malloc_in_stdlib" >&6 if test x"$ac_cv_pts_malloc_in_stdlib" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_malloc_in_stdlib 1 _ACEOF fi if test x"$ac_cv_pts_malloc_in_stdlib" != xyes; then echo "$as_me:$LINENO: checking for working malloc in malloc.h" >&5 echo $ECHO_N "checking for working malloc in malloc.h... $ECHO_C" >&6 if test "${ac_cv_pts_malloc_in_malloc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_HEADER" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ #undef const #undef volatile #undef inline #include #include "confdefs.h" int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char *p=malloc(42); if (p!=0) free(p); return p==0; return 1; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_malloc_in_malloc=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_malloc_in_malloc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_malloc_in_malloc" >&5 echo "${ECHO_T}$ac_cv_pts_malloc_in_malloc" >&6 if test x"$ac_cv_pts_malloc_in_malloc" = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_malloc_in_malloc 1 _ACEOF fi fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo "$as_me:$LINENO: checking for working alloca.h" >&5 echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 if test "${ac_cv_working_alloca_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 if test $ac_cv_working_alloca_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi echo "$as_me:$LINENO: checking for alloca" >&5 echo $ECHO_N "checking for alloca... $ECHO_C" >&6 if test "${ac_cv_func_alloca_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 if test $ac_cv_func_alloca_works = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.$ac_objext cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 if test "${ac_cv_os_cray+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined(CRAY) && ! defined(CRAY2) webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 echo "${ECHO_T}$ac_cv_os_cray" >&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 if test "${ac_cv_c_stack_direction+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int find_stack_direction () { static char *addr = 0; auto char dummy; if (addr == 0) { addr = &dummy; return find_stack_direction (); } else return (&dummy > addr) ? 1 : -1; } int main () { exit (find_stack_direction () < 0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi echo "$as_me:$LINENO: checking for width of printf .g" >&5 echo $ECHO_N "checking for width of printf .g... $ECHO_C" >&6 if test "${ac_cv_pts_cfg_printfglen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CFG_PRINTFGLEN" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CFG_PRINTFGLEN" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define __USE_SVID 1 #define __USE_GNU 1 #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { unsigned i; char tmp[64], pat[10], *p; FILE *f=fopen("conftestval","w"); if (!f) return 1; for (i=1;i<61;i++) { sprintf(pat, "%%.%ug", i); sprintf(tmp, pat, 1.0/3); if (tmp[0]=='0' && tmp[1]=='.') { p=tmp+2; while (*p=='3') p++; if (*p!='\0') break; } } if (i>1) fprintf(f,".%u",i-1); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_cfg_printfglen=\""`cat conftestval`"\" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_cfg_printfglen="" fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi test x"$ac_cv_pts_cfg_printfglen" = x && ac_cv_pts_cfg_printfglen=no fi echo "$as_me:$LINENO: result: $ac_cv_pts_cfg_printfglen" >&5 echo "${ECHO_T}$ac_cv_pts_cfg_printfglen" >&6 if test x"$ac_cv_pts_cfg_printfglen" = xno; then :; else cat >>confdefs.h <<_ACEOF #define PTS_CFG_PRINTFGLEN $ac_cv_pts_cfg_printfglen _ACEOF fi echo "$as_me:$LINENO: checking for tmpdir" >&5 echo $ECHO_N "checking for tmpdir... $ECHO_C" >&6 if test "${ac_cv_pts_cfg_p_tmpdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CFG_P_TMPDIR" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CFG_P_TMPDIR" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define __USE_SVID 1 #define __USE_GNU 1 #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *f=fopen("conftestval","w"); if (!f) return 1; fputs(P_tmpdir,f); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_cfg_p_tmpdir=\""`cat conftestval`"\" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_cfg_p_tmpdir=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_cfg_p_tmpdir" >&5 echo "${ECHO_T}$ac_cv_pts_cfg_p_tmpdir" >&6 cat >>confdefs.h <<_ACEOF #define PTS_CFG_P_TMPDIR $ac_cv_pts_cfg_p_tmpdir _ACEOF echo "$as_me:$LINENO: checking for binary popen_" >&5 echo $ECHO_N "checking for binary popen_... $ECHO_C" >&6 if test "${ac_cv_pts_have_popen_+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_HAVE_POPEN_" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_HAVE_POPEN_" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _XOPEN_SOURCE 1 /* popen() on Digital UNIX */ #define _POSIX_SOURCE 1 /* popen() */ #define _POSIX_C_SOURCE 2 /* popen() */ #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *p=popen("echo Ko rt5","r"); int i; (void)argc; (void)argv; if (p==0) return 1; if (getc(p)!='K' || getc(p)!='o' || getc(p)!=' ') return 2; if (getc(p)!='r' || getc(p)!='t') return 3; if (getc(p)!='f'-'a'+'0') return 4; if (getc(p)!='\n') return 5; if (getc(p)!=-1) return 6; if (0!=pclose(p)) return 7; p=popen("cat >conftestval","w"); if (p==0) return 31; for (i=0;i<666;i++) putc(i,p); if (ferror(p)) return 32; if (0!=pclose(p)) return 33; p=fopen("conftestval","rb"); if (p==0) return 34; for (i=0;i<666;i++) if (getc(p)!=(i&255)) return 35; if (fclose(p)!=0) return 36; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_popen_=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_have_popen_=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_popen_" >&5 echo "${ECHO_T}$ac_cv_pts_have_popen_" >&6 if test x"$ac_cv_pts_have_popen_" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_POPEN_ 1 _ACEOF fi if test $ac_cv_pts_have_popen_ = yes; then ac_cv_pts_have_popen_b=no fi echo "$as_me:$LINENO: checking for binary popen_b" >&5 echo $ECHO_N "checking for binary popen_b... $ECHO_C" >&6 if test "${ac_cv_pts_have_popen_b+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_HAVE_POPEN_B" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_HAVE_POPEN_B" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _XOPEN_SOURCE 1 /* popen() on Digital UNIX */ #define _POSIX_SOURCE 1 /* popen() */ #define _POSIX_C_SOURCE 2 /* popen() */ #include int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *p=popen("echo Ko rt5","rb"); int i; (void)argc; (void)argv; if (p==0) return 1; if (getc(p)!='K' || getc(p)!='o' || getc(p)!=' ') return 2; if (getc(p)!='r' || getc(p)!='t') return 3; if (getc(p)!='f'-'a'+'0') return 4; if (getc(p)!='\n') return 5; if (getc(p)!=-1) return 6; if (0!=pclose(p)) return 7; p=popen("cat >conftestval","wb"); if (p==0) return 31; for (i=0;i<666;i++) putc(i,p); if (ferror(p)) return 32; if (0!=pclose(p)) return 33; p=fopen("conftestval","rb"); if (p==0) return 34; for (i=0;i<666;i++) if (getc(p)!=(i&255)) return 35; if (fclose(p)!=0) return 36; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_have_popen_b=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_have_popen_b=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_have_popen_b" >&5 echo "${ECHO_T}$ac_cv_pts_have_popen_b" >&6 if test x"$ac_cv_pts_have_popen_b" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_POPEN_B 1 _ACEOF fi echo "$as_me:$LINENO: checking for working vsnprintf" >&5 echo $ECHO_N "checking for working vsnprintf... $ECHO_C" >&6 if test "${ac_cv_pts_vsnprintf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_HAVE_VSNPRINTF" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_HAVE_VSNPRINTF" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if 0 /* autoconf-2.54 */ extern "C" void std::exit (int) throw (); using std::exit; extern "C" void std::exit (int); using std::exit; extern "C" void exit (int) throw (); extern "C" void exit (int); void exit (int); #endif #ifdef __cplusplus extern "C" void exit(int); #endif #define _BSD_SOURCE 1 /* vsnprintf */ #define _POSIX_SOURCE 1 #define _POSIX_C_SOURCE 2 #include #include #include static int myprintf(int max, char *dstr, char *fmt, ...) { int i; va_list ap; #if defined(__STDC__) va_start(ap, fmt); #else va_start(ap); #endif i=vsnprintf(dstr, max, fmt, ap); va_end(ap); return i; } int c99t[]={13,9,10,10,10}, oldt[]={-1,9,-1,0,-1}, sun99t[]={13,9,10,-1,10}; /* wincrtt[]={-1,9,10,-1,-1}, but it modifies the string in a completely * bogus way (passes 1 test of 5) */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { char buf[40]; int i; int g[5], gg; int *t=oldt; FILE *f=fopen("conftestval","w"); (void)argc; (void)argv; if (f) { for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='X'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -1234567L); if (i==c99t[0]) t=c99t; /* oldt[0]!=c99t[0] */ g[0]=(i==t[0] && 0==memcmp(buf, "Alma--123\0X", 11)); /* printf("(%s) %d %d\n", buf, i, g[0]); */ for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='Y'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -123L); g[1]=(i==t[1] && 0==memcmp(buf, "Alma--123\0Y", 11)); /* printf("(%s) %d %d\n", buf, i, g[1]); */ for (i=0;i<(int)sizeof(buf)-1;i++) buf[i]='Z'; buf[i]='\0'; i=myprintf(10, buf, "%s-%ld", "Alma", -1234L); g[2]=(i==t[2] && 0==memcmp(buf, "Alma--123\0Z", 11)); /* printf("(%s) %d %d\n", buf, i, g[2]); */ buf[0]='#'; i=myprintf(0, buf, "%s-%ld", "Alma", -1234L); if (t==c99t && i==sun99t[3]) t=sun99t; g[3]=(i==t[3] && buf[0]=='#'); /* printf("(%s) %d %d\n", buf, i, g[3]); */ buf[0]=buf[1]='$'; i=myprintf(1, buf, "%s-%ld", "Alma", -1234L); g[4]=(i==t[4] && buf[0]=='\0' && buf[1]=='$'); /* printf("(%s) %d %d\n", buf, i, g[4]); */ gg=g[0] && g[1] && g[2] && g[3] && g[4]; fputs(!gg ? "bad\n" : t==oldt ? "old\n" : t==sun99t ? "sun99\n" : "c99\n", f); fclose(f); } return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_vsnprintf="`cat conftestval`"; ac_cv_pts_vsnprintf="${ac_cv_pts_vsnprintf:-invalid}" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_vsnprintf=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_vsnprintf" >&5 echo "${ECHO_T}$ac_cv_pts_vsnprintf" >&6 if test x"$ac_cv_pts_vsnprintf" = xold; then ac_cv_pts_have_vsnprintf=yes cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_VSNPRINTF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_VSNPRINTF_OLD 1 _ACEOF elif test x"$ac_cv_pts_have_vsnprintf" = xc99; then ac_cv_pts_have_vsnprintf=yes cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_VSNPRINTF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_VSNPRINTF_C99 1 _ACEOF else ac_cv_pts_have_vsnprintf=no ac_cv_pts_vsnprintf=no fi echo no-original >conftestval echo "$as_me:$LINENO: checking for working system(3)" >&5 echo $ECHO_N "checking for working system(3)... $ECHO_C" >&6 if test "${ac_cv_pts_systemf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_HAVE_VSNPRINTF" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_HAVE_VSNPRINTF" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include /* system() */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { (void)argc; (void)argv; if (0!=system("echo t >conftestval && echo \"let it\" be e >conftestval")) { FILE *f=fopen("conftestval","w"); if (f) { fprintf(f,"runtime-error\n"); fclose(f); } } return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_systemf="`cat conftestval`"; ac_cv_pts_systemf="${ac_cv_pts_systemf:-invalid}" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_systemf=compile-error fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi # echo "($ac_cv_pts_systemf)" # if test x"$ac_cv_pts_systemf" = x'"let it" be e '; then if test x"$ac_cv_pts_systemf" = x't && echo "let it" be e '; then # Win32 COMMAND.COM ac_cv_pts_systemf=win32 elif test x"$ac_cv_pts_systemf" = x"let it be e"; then # UNIX /bin/sh ac_cv_pts_systemf=unix fi fi echo "$as_me:$LINENO: result: $ac_cv_pts_systemf" >&5 echo "${ECHO_T}$ac_cv_pts_systemf" >&6 if test x"$ac_cv_pts_systemf" = xwin32; then ac_cv_pts_have_systemf=yes cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF_WIN32 1 _ACEOF elif test x"$ac_cv_pts_systemf" = xunix; then ac_cv_pts_have_systemf=yes cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF_UNIX 1 _ACEOF elif test x"$ac_cv_pts_systemf" = x"invalid"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"compile-error"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"runtime-error"; then ac_cv_pts_have_systemf=no elif test x"$ac_cv_pts_systemf" = x"no-original"; then ac_cv_pts_have_systemf=no else ac_cv_pts_have_systemf=yes # ac_cv_pts_systemf=other cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_PTS_SYSTEMF_OTHER 1 _ACEOF fi echo "$as_me:$LINENO: checking whether char is unsigned" >&5 echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6 if test "${ac_cv_c_char_unsigned+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __CHAR_UNSIGNED__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then ac_cv_c_char_unsigned=yes else ac_cv_c_char_unsigned=no fi rm -f conftest* else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_C_CHAR_UNSIGNED" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_C_CHAR_UNSIGNED" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* volatile prevents gcc2 from optimizing the test away on sparcs. */ #if !defined(__STDC__) || __STDC__ != 1 #define volatile #endif int main() { volatile char c = 255; return(c < 0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_char_unsigned=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_char_unsigned=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5 echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6 if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then cat >>confdefs.h <<\_ACEOF #define __CHAR_UNSIGNED__ 1 _ACEOF fi if test x"$ac_cv_sizeof_char" = x; then echo "$as_me:$LINENO: checking size of char" >&5 echo $ECHO_N "checking size of char... $ECHO_C" >&6 if test "${ac_cv_sizeof_char+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_sizeof_char_p=-1;ac_cv_sizeof_short=-1;ac_cv_sizeof_int=-1 ac_cv_sizeof_long=-1 if test "$cross_compiling" = yes; then ac_cv_sizeof_char=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #undef const #undef volatile #undef inline #include int main(){FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "ac_cv_sizeof_char=%d\n", sizeof(char)); fprintf(f, "ac_cv_sizeof_char_p=%d\n", sizeof(char*)); fprintf(f, "ac_cv_sizeof_short=%d\n", sizeof(short)); fprintf(f, "ac_cv_sizeof_int=%d\n", sizeof(int)); fprintf(f, "ac_cv_sizeof_long=%d\n", sizeof(long)); return 0; /* exit(0); -- return is more portable */ } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "`cat conftestval`" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5 echo "${ECHO_T}$ac_cv_sizeof_char" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR_P $ac_cv_sizeof_char_p _ACEOF cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF fi if test $ac_cv_sizeof_char = -1; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_INTEGRALS" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_INTEGRALS" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: checking size of short" >&5 echo $ECHO_N "checking size of short... $ECHO_C" >&6 if test "${ac_cv_sizeof_short+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_short=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(short)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_short=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_short=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 echo "${ECHO_T}$ac_cv_sizeof_short" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6 if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_int=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(int)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_int=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6 if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_long=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(long)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_long=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF echo "$as_me:$LINENO: checking size of long long" >&5 echo $ECHO_N "checking size of long long... $ECHO_C" >&6 if test "${ac_cv_sizeof_long_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_long_long=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(long long)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long_long=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_long_long=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF if test $ac_cv_sizeof_long_long = 8 then ac_cv_sizeof___int64=0; ac_cv_sizeof_very_long=0; fi echo "$as_me:$LINENO: checking size of very long" >&5 echo $ECHO_N "checking size of very long... $ECHO_C" >&6 if test "${ac_cv_sizeof_very_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_very_long=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(very long)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_very_long=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_very_long=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_very_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_very_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_VERY_LONG $ac_cv_sizeof_very_long _ACEOF if test $ac_cv_sizeof_very_long = 8; then ac_cv_sizeof___int64=0; fi echo "$as_me:$LINENO: checking size of __int64" >&5 echo $ECHO_N "checking size of __int64... $ECHO_C" >&6 if test "${ac_cv_sizeof___int64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof___int64=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(__int64)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof___int64=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof___int64=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof___int64" >&5 echo "${ECHO_T}$ac_cv_sizeof___int64" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF___INT64 $ac_cv_sizeof___int64 _ACEOF # echo $ac_cv_sizeof_long_long if test $ac_cv_sizeof_char != 1; then { { echo "$as_me:$LINENO: error: sizeof(char)!=1" >&5 echo "$as_me: error: sizeof(char)!=1" >&2;} { (exit 1); exit 1; }; } fi if test $ac_cv_sizeof_short = 2; then ac_cv_pts_int16_t=short elif test $ac_cv_sizeof_int = 2; then ac_cv_pts_int16_t=int else { { echo "$as_me:$LINENO: error: cannot find inttype: sizeof(inttype)==2" >&5 echo "$as_me: error: cannot find inttype: sizeof(inttype)==2" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<_ACEOF #define PTS_INT16_T $ac_cv_pts_int16_t _ACEOF if test $ac_cv_sizeof_int = 4; then ac_cv_pts_int32_t=int elif test $ac_cv_sizeof_long = 4; then ac_cv_pts_int32_t=long elif test $ac_cv_sizeof_long -lt 4; then { { echo "$as_me:$LINENO: error: sizeof(long)<4" >&5 echo "$as_me: error: sizeof(long)<4" >&2;} { (exit 1); exit 1; }; } else { { echo "$as_me:$LINENO: error: cannot find inttype: sizeof(inttype)==4" >&5 echo "$as_me: error: cannot find inttype: sizeof(inttype)==4" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<_ACEOF #define PTS_INT32_T $ac_cv_pts_int32_t _ACEOF if test $ac_cv_sizeof_long = 8; then ac_cv_pts_int64_t=long elif test $ac_cv_sizeof_long_long = 8; then ac_cv_pts_int64_t="long long" elif test $ac_cv_sizeof_very_long = 8; then ac_cv_pts_int64_t="very long" elif test $ac_cv_sizeof___int64 = 8; then ac_cv_pts_int64_t="__int64" else ac_cv_pts_int64_t=0 { echo "$as_me:$LINENO: WARNING: cannot find inttype: sizeof(inttype)==8" >&5 echo "$as_me: WARNING: cannot find inttype: sizeof(inttype)==8" >&2;} fi cat >>confdefs.h <<_ACEOF #define PTS_INT64_T $ac_cv_pts_int64_t _ACEOF if test $ac_cv_sizeof_long = 16; then ac_cv_pts_int128_t=long elif test $ac_cv_sizeof_long_long = 16; then ac_cv_pts_int128_t="long long" elif test $ac_cv_sizeof_very_long = 16; then ac_cv_pts_int128_t="very long" else ac_cv_pts_int128_t=0 { echo "$as_me:$LINENO: WARNING: cannot find inttype: sizeof(inttype)==16" >&5 echo "$as_me: WARNING: cannot find inttype: sizeof(inttype)==16" >&2;} fi cat >>confdefs.h <<_ACEOF #define PTS_INT128_T $ac_cv_pts_int128_t _ACEOF echo "$as_me:$LINENO: checking size of char *" >&5 echo $ECHO_N "checking size of char *... $ECHO_C" >&6 if test "${ac_cv_sizeof_char_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_char_p=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(char *)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_char_p=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_char_p=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_char_p" >&5 echo "${ECHO_T}$ac_cv_sizeof_char_p" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR_P $ac_cv_sizeof_char_p _ACEOF echo "$as_me:$LINENO: checking size of void *" >&5 echo $ECHO_N "checking size of void *... $ECHO_C" >&6 if test "${ac_cv_sizeof_void_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_void_p=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(void *)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_void_p=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_void_p=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5 echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF echo "$as_me:$LINENO: checking for an integral type to hold a ptr" >&5 echo $ECHO_N "checking for an integral type to hold a ptr... $ECHO_C" >&6 if test "${ac_cv_pts_intp_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test $ac_cv_sizeof_char_p != $ac_cv_sizeof_void_p; then { { echo "$as_me:$LINENO: error: $ac_cv_sizeof_char_p==sizeof(char*)!=sizeof(void*)" >&5 echo "$as_me: error: $ac_cv_sizeof_char_p==sizeof(char*)!=sizeof(void*)" >&2;} { (exit 1); exit 1; }; } fi if test $ac_cv_sizeof_char_p -le 2; then ac_cv_pts_intp_t=$ac_cv_pts_int16_t elif test $ac_cv_sizeof_char_p -le 4; then ac_cv_pts_intp_t=$ac_cv_pts_int32_t elif test $ac_cv_sizeof_char_p -le 8; then ac_cv_pts_intp_t=$ac_cv_pts_int64_t elif test $ac_cv_sizeof_char_p -le 16; then ac_cv_pts_intp_t=$ac_cv_pts_int128_t else # :; fi; if true; then echo "$as_me:$LINENO: result: not found!" >&5 echo "${ECHO_T}not found!" >&6 { { echo "$as_me:$LINENO: error: no integral type for sizeof(char*)==$ac_cv_sizeof_char_p" >&5 echo "$as_me: error: no integral type for sizeof(char*)==$ac_cv_sizeof_char_p" >&2;} { (exit 1); exit 1; }; } fi fi cat >>confdefs.h <<_ACEOF #define PTS_INTP_T $ac_cv_pts_intp_t _ACEOF echo "$as_me:$LINENO: result: $ac_cv_pts_intp_t" >&5 echo "${ECHO_T}$ac_cv_pts_intp_t" >&6 echo "$as_me:$LINENO: checking for ptr <-> integral conversion" >&5 echo $ECHO_N "checking for ptr <-> integral conversion... $ECHO_C" >&6 if test "${ac_cv_pts_intp_ok+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_POINTERS" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_POINTERS" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* #include "confdefs.h" -- automatic */ int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif /* #ifndef __cplusplus; #define const; #endif -- automatic config.h */ {char const*p="The quick brown fox."+5; PTS_INTP_T i; while (*p!='r') p++; /* prevent compiler optimisations */ i=(PTS_INTP_T)p; while (*p!='w') p++; /* prevent compiler optimisations */ return p!=(char*)(i+2); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_pts_intp_ok=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_pts_intp_ok=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi if test x"$ac_cv_pts_intp_ok" = xyes; then cat >>confdefs.h <<\_ACEOF #define PTS_INTP_OK 1 _ACEOF fi echo "$as_me:$LINENO: result: $ac_cv_pts_intp_ok" >&5 echo "${ECHO_T}$ac_cv_pts_intp_ok" >&6 echo "$as_me:$LINENO: checking for integral type size_t" >&5 echo $ECHO_N "checking for integral type size_t... $ECHO_C" >&6 if test "${ac_cv_integral_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cross compiling not supported by .._PTS_CHECK_INTEGRAL_TYPEX" >&5 echo "$as_me: error: cross compiling not supported by .._PTS_CHECK_INTEGRAL_TYPEX" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* #include "confdefs.h" -- automatic */ #include #if STDC_HEADERS #include #include #endif #include #if HAVE_UNISTD_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif #define MY_TYPE size_t int main #ifdef __STDC__ (int argc, char **argv) #else (argc, argv) int argc; char **argv; #endif { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, 0<(MY_TYPE)-1 ? "unsigned " : "signed "); if (sizeof(MY_TYPE)==1) fprintf(f, "char"); else if (sizeof(MY_TYPE)==sizeof(char)) fprintf(f, "char"); else if (sizeof(MY_TYPE)==sizeof(short)) fprintf(f, "short"); else if (sizeof(MY_TYPE)==sizeof(int)) fprintf(f, "int"); else if (sizeof(MY_TYPE)==sizeof(long)) fprintf(f, "long"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT16_T)) fprintf(f, "PTS_INT16_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT32_T)) fprintf(f, "PTS_INT32_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT64_T)) fprintf(f, "PTS_INT64_T"); else if (sizeof(MY_TYPE)==sizeof(PTS_INT128_T)) fprintf(f, "PTS_INT128_T"); else return 3; /* fprintf(f, "???"); */ if (ferror(f)) return 2; /* printf("\n"); */ return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_integral_type_size_t="`cat conftestval`"; else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test x"unsigned" = x; then echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; { { echo "$as_me:$LINENO: error: This is fatal." >&5 echo "$as_me: error: This is fatal." >&2;} { (exit 1); exit 1; }; }; fi ac_cv_integral_type_size_t="unsigned" echo -n "substituting " fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi cat >>confdefs.h <<_ACEOF #define PTS_size_t $ac_cv_integral_type_size_t _ACEOF echo "$as_me:$LINENO: result: $ac_cv_integral_type_size_t" >&5 echo "${ECHO_T}$ac_cv_integral_type_size_t" >&6 echo "$as_me:$LINENO: checking size of bool" >&5 echo $ECHO_N "checking size of bool... $ECHO_C" >&6 if test "${ac_cv_sizeof_bool+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_bool=-1 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main() { FILE *f=fopen("conftestval", "w"); if (!f) return 1; fprintf(f, "%d\n", sizeof(bool)); return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_bool=`cat conftestval` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_sizeof_bool=0 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_bool" >&5 echo "${ECHO_T}$ac_cv_sizeof_bool" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_BOOL $ac_cv_sizeof_bool _ACEOF ac_config_files="$ac_config_files Makehelp" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makehelp" ) CONFIG_FILES="$CONFIG_FILES Makehelp" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@ENABLE_DEBUG@,$ENABLE_DEBUG,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@GFLAG@,$GFLAG,;t t s,@CXXFLAGSB@,$CXXFLAGSB,;t t s,@LDXX@,$LDXX,;t t s,@pts_cjpeg@,$pts_cjpeg,;t t s,@pts_djpeg@,$pts_djpeg,;t t s,@pts_tif22pnm@,$pts_tif22pnm,;t t s,@pts_tifftopnm@,$pts_tifftopnm,;t t s,@pts_pngtopnm@,$pts_pngtopnm,;t t s,@pts_gs@,$pts_gs,;t t s,@pts_lzw_codec@,$pts_lzw_codec,;t t s,@pts_gzip@,$pts_gzip,;t t s,@pts_zip@,$pts_zip,;t t s,@pts_bash@,$pts_bash,;t t s,@pts_make@,$pts_make,;t t s,@pts_perl@,$pts_perl,;t t s,@CXXCPP@,$CXXCPP,;t t s,@EGREP@,$EGREP,;t t s,@ALLOCA@,$ALLOCA,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi rm -f Makedep ac_n="${ac_n:-$ECHO_N}" echo $ac_n "running make Makedep""... $ac_c" 1>&6 echo "configure:7504: running make Makedep" >&5 if >&5 2>&5 make Makedep; then : echo "$as_me:$LINENO: result: ok" >&5 echo "${ECHO_T}ok" >&6 else echo "$as_me:$LINENO: result: error" >&5 echo "${ECHO_T}error" >&6 { { echo "$as_me:$LINENO: error: cannot compute depends" >&5 echo "$as_me: error: cannot compute depends" >&2;} { (exit 1); exit 1; }; } fi echo "configure:7517: all OK" >&5 echo "configure done. Now you should run: make; make install" sam2p-0.49.2/COPYING0000644000175100017510000004307612211371426012074 0ustar ptspts GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. sam2p-0.49.2/README0000644000175100017510000037377412211371426011734 0ustar ptsptsREADME for sam2p by pts@fazekas.hu at Sun Dec 30 19:30:17 CET 2001 -- Fri Mar 22 19:25:03 CET 2002 Sat Apr 27 00:39:12 CEST 2002 Wed Jul 3 01:20:40 CEST 2002 Wed Feb 5 19:46:51 CET 2003 grammatical corrections by Steve Turner at Mon Jan 10 00:53:46 CET 2005 This is the README file for sam2p, a raster to PostScript/PDF image conversion program. This file contains a 5-minute turbo tutorial for new and impatient users (search for the phrase `Turbo tutorial' in your text editor). As of now, this README file is the only, and definitive, documentation of sam2p. sam2p is a UNIX command line utility written in ANSI C++ that converts many raster (bitmap) image formats into Adobe PostScript or PDF files and several other formats. The images are not vectorized. sam2p gives full control to the user to specify standards-compliance, compression, and bit depths. In some cases sam2p can compress an image 100 times smaller than the PostScript output of many other common image converters. sam2p provides ZIP, RLE and LZW (de)compression filters even on Level1 PostScript devices. A testimonial from Grant Ingram, UK: Anyway this is just a quick note to say thanks for writing the sam2p utility which I am using to create EPS figures of photographs for my thesis -- it works very well producing image sizes that are some 3% of the ones produced by ImageMagick. Does sam2p generate small EPS (and PDF) files? A testimonial from Tom Schneider, US: -rw------- 1 toms delila 88628 Mar 3 17:38 prototype-small.eps -rw------- 1 toms delila 7979299 Feb 24 12:25 prototype.eps Good GRIEF you have written a nice program!!!! The file is 90 fold smaller than the one from Imagemagick's convert. That image that was 90x smaller had been bugging me because it was so large that xdvi would strongly hesitate while I passed by the page. Now it just has a minor delay, thanks to you. Many thanks to Steve Turner for reviewing and making corrections to this documentation. The author of sam2p recommends his program over other image converters because of the following reasons: -- sam2p produces much smaller output -- sam2p gives the user complete control over the data layout of the output image. This includes Compression, SampleFormat and TransferEncoding. -- sam2p is fast -- sam2p doesn't depend on external libraries. (But it does depend on external programs for _reading_ JPEG, TIFF and PNG files.) -- sam2p supports the mainstream image formats of today without compromise. sam2p has many file format fine-tuning features that are missing from most other converter utilities. For example: TIFF ZIP compression, TIFF LZW compression, TIFF JPEG compression, transparent PNG files, BMP RLE-4 and RLE-8 compression, etc. -- sam2p supports all levels (versions) of the PostScript language and output images have the smallest file size allowed by the LanguageLevel. -- PostScript ZIP, RLE and LZW compression is provided for _all_ LanguageLevels (!), even for PSL1 (which appeared in 1980). You can print your ZIP-compressed images onto your ancient printer of the 1980s. -- sam2p supports all versions of PDF, and as with PostScript, output images have the smallest file size allowed by the version. -- output images of sam2p are always compliant to the standard selected by the user -- output images of sam2p are real-world compatible, i.e the author has tested them with many common image processing programs, for example: Ghostscript, pdfTeX, xpdf, Acrobat Reader, The GIMP, ImageMagick, xv, Acrobat Distiller, QuarkXPress, InDesign. The author has also tested PostScript files on HP and OkiData printers. -- sam2p converts every pixel faithfully, preserving all the 24 RGB bits intact. There is no quality or information loss unless you ask for it. -- sam2p uses only a minimal number of libraries. You don't have to install 33Mb of ballast software to use sam2p. Image libraries (libtiff etc.) are _not_ used, the math library is not used, libstdc++ is not used, zlib is not used. Long-term limitations: -- only DeviceRGB color space, with the Indexed, Gray and RGB image types -- Indexed images are limited to a maximum of 256 colors -- alpha channel and transparency supported only for Indexed images: only one color may be transparent -- the entire input image is read into memory. During operation both the input and the output images may be held in memory. Status ~~~~~~ sam2p is currently beta software. It is available from: http://www.inf.bme.hu/~pts/sam2p/ http://www.inf.bme.hu/~pts/sam2p-latest.tar.gz http://sam2p.sf.net/ The documentation is incomplete, but -- together with the examples -- it is quite useful. Please have a look at the home page to find articles and more documentation (the PDF docs are much more eye-pleasing than this README). The source code contains valuable comments, but they may be hard to find unless you're deeply into developing sam2p. The author is developing sam2p in his free time. (He is studying and working in non-free time.) The imaging model is complete. Image output routines are stable and adequate. Reasonable defaults are provided for all command line options. sam2p can usually find the best SampleFormat automatically. There is an educated (but not perfect) default guess for the Compression. See subsection {OutputRule combinations} about all planned formats. The most important short-term limitations: -- The code hasn't been extensively tested. The author welcomes bug reports. -- The code hasn't been profiled for speed bottlenecks. (Although it seems to be faster than ImageMagick convert(1) in most situations.) Turbo tutorial ~~~~~~~~~~~~~~ Quick compilation instructions: 1. ./configure --enable-lzw --enable-gif 2. make 3. Copy the `sam2p' executable to your $PATH, or invoke it as `./sam2p'. Quick try: -- ./sam2p examples/pts2.pbm try.eps -- ./sam2p examples/pts2.pbm try.pdf -- ./sam2p examples/pts2.pbm try.ps -- ./sam2p examples/pts2.pbm try.png -- ./sam2p examples/pts2.pbm try.tiff -- ./sam2p examples/pts2.pbm try.xpm -- ./sam2p examples/pts2.pbm try.bmp -- ./sam2p examples/pts2.pbm try.jpg A really short User's guide """"""""""""""""""""""""""" To convert an image, call: ./sam2p Example: ./sam2p examples/pts2.pbm try.eps To print an image as a full PostScript page, call: ./sam2p [MARGIN-SPECS] ps: - | lpr Example: ./sam2p -m:1cm examples/pts2.pbm ps: - | lpr To convert an image to be included as EPS (Encapsulated PostScript) into (La)TeX documents, call: ./sam2p Example: ./sam2p examples/pts2.pbm test.eps In file.tex: \usepackage{graphicx} ... \includegraphics{test} To convert an image to be included as PDF into pdf(La)TeX documents, call: ./sam2p Example: ./sam2p examples/pts2.pbm test.pdf In file.tex: \usepackage{graphicx} ... \includegraphics{test} If you have a large image file (possibly originating from dumb software), you can reduce the image size and keep the same filename. (Please note that some meta-information may be lost using this method.) This operation is _DANGEROUS_ if you don't have a backup, because due to a software or hardware problem, sam2p might clobber time image file so the actual image gets lost. To overwrite a file in-place, call: ./sam2p -- Example: ./sam2p test.tiff -- You may specify a compression method (or supply other command line options) to make a file even smaller, call: ./sam2p [OPTIONS] Example: ./sam2p -c:zip test.tiff test2.tiff See the detailed documentation of available command-line options elsewhere in this document. You may also read section {FAQ} for more information. Too see a list about the supported input and output image file formats, call: ./sam2p Example output: This is sam2p v0.39. Available Loaders: JAI PNG JPEG TIFF PNM BMP GIF LBM XPM PCX TGA. Available Appliers: XWD Meta Empty BMP PNG TIFF6 TIFF6-JAI JPEG-JAI JPEG PNM GIF89a XPM PSL1C PSL23+PDF PDF-JAI PSL2-JAI l1fa85g P-TrOpBb. Usage: [...] The list of ``Available Loaders'' lists the input image file formats. All except for JAI are self-explanatory. JAI is JPEG-as-is, it means reading a JPEG file and writing back the exactly same image into an other JPEG variant, without quality loss. From the list of ``Available Appliers'' one can derive the supported output image file formats. XWD, BMP, PNG, TIFF6, JPEG, PNM, GIF89a and XPM are self-explanatory. TIFF6-JAI, JPEG-JAI, PDF-JAI and PSL2-JAI are JPEG variants into which JAI files (see above) can be saved. While the names of the remaining appliers may be quite cryptic to the beginner user; most of those appliers provide sam2p's excellent support for writing PS, EPS and PDF files. sam2p operation modes ~~~~~~~~~~~~~~~~~~~~~ sam2p is a command line utility (i.e, without a graphical user interface), so it can be used by composing a command line with the appropriate options and parameters, and launching it. See sections ``Turbo tutorial'' and ``One-liner mode'' for more details. sam2p is not interactive, it doesn't ask questions; thus it is completely suitable for batch processing and automation. sam2p doesn't log errors, but its STDERR can be redirected to a log file quite easily. There are three modes sam2p can operate in: -- one-liner mode: (since sam2p 0.37) the user, perhaps, has to type a long command line, specifying the input and the output file name, output file format, compression options, etc. Most of the functionality of sam2p is available in a quite intuitive way in one-liner mode. Users of the `convert' utility from ImageMagick and `tiff2ps' and `tiffcp' will find that one-liner mode of sam2p is very similar to them. This mode is recommended for impatient users. Due to the nature of sam2p development, some new functionality of job mode might be missing from one-liner mode. Please report this as a bug. -- job mode: the user has to write a ``job'' file (recommended extension: .job), which specifies all conversion parameters, including the input and output file name. The name of the job file must be passed to sam2p. This mode is recommended for expert users who want to retain full control of all aspects of the final output. All functionality is available in job mode. This is especially useful in repetative but time separated jobs. -- GUI mode: This is completely experimental, and will be very probably dropped in the near future. Try executing sam2p.tk (TCL/Tk is required). Please don't use GUI mode, use one-liner mode instead! The flexability of a one-liner (or job) mode is nearly imposible to encompas in a GUI. No more documentation is provided for GUI mode. There might be a Micro$oft Windoze version of sam2p available in the near future, but very probably you won't get real GUI with radio boxes, lists and file selection dialogs. You'll have to start sam2p from the DOS prompt... One-liner mode ~~~~~~~~~~~~~~ This section contains a reference-style summary for the one-liner mode. The author knows that this section is quite incomprehensible, and a bit old. He is planning to completely rewrite it to be readable for the novice user. The order of the arguments and options is significant. Input file extension is discarded. The file format is recognised by its magic number. Output file extension gives a hint for /FileFormat: .ps :\ .eps : \ where PS: implies scale to fit page .epsi : > PSL1 PSLC PSL2 PSL3 and .epsf : / EPS: implies no scale changes [E]PS::/ also see Q9 in FAQs below .pdf : \ PDF1.0 PDF1.2 (and) PDF: : / PDFB1.0 PDFB1.2 .gif : GIF89a .pnm : PNM (for use with transparency) .pbm : PNM /SampleFormat/Gray1 .pgm : PNM /SampleFormat/Gray8 .ppm : PNM /SampleForamt/Rgb8 .pam : PAM .pip : PIP .empty : Empty .meta : Meta .jpeg : JPEG .jpg : " .tiff : TIFF .tif : " .png : PNG .xpm : XPM .bmp : BMP /Compression/RLE .rle : BMP /Compression/RLE Options (case insensitive): -- --tmpremove {true|false} : remove temporary files after completion. Set to false for debugging. Default: true. -- -j -j:job : display in-memory .job file -- -j:warn : be verbose and display warnings about impossible combinations in the .job file -- -j:quiet : print only error and fatal error messages, suppress warnings, notices etc. Must be put at the beginning of the command line to suppress initial banners, too. For example, `sam2p -j:quiet in.gif out.eps'. -- -s:Indexed1:Indexed4:Indexed8: Try /SampleFormats in this order, and try all others after these. Can be specified separately (e.g `-s Indexed1 -s Indexed2:Indexed8') -- -s:Indexed1:Indexed4:Indexed8:stop: Try only these /SampleFormats in this order. Can be specified separately (e.g `-s Indexed1:Indexed2 -s Indexed8:stop') -- -s:Indexed1:Indexed4:Indexed8:stopq: Try only these /SampleFormats in this order, be quiet (no warnings on failures). Can be specified separately (e.g `-s Indexed1:Indexed2 -s Indexed8:stop') -- -s:tr equivalent to `-s Transparent:Opaque:Mask:Transparent2:Transparent4:Transparent8' -- -l:... : /LoadHints(...) -- disabled: -a: /LoadHints(asis) extra /Compression/JAI; load JPEG files (and others as-is) -- -1 -ps:1 PSL1: : [tiff2ps] hint /FileFormat/PSL1 among /PSL* -- -1c -ps:1c -ps:c PSLC: : [pts] hint /FileFormat/PSLC among /PSL* -- -2 -ps:2 PSL2: EPS2: : [tiff2ps,imagemagick] default hint /FileFormat/PSL2 among /PSL* -- -3 -ps:3 PSL3: : [pts] hint /FileFormat/PSL3 among /PSL* -- -pdf:b0 PDFB1.0: : [pts] hint /FileFormat/PDFB1.0 among /PDF* (PDF 1.0 with inline image) -- -pdf:b2 PDFB1.2: : [pts] default hint /FileFormat/PDFB1.2 among /PDF* (PDF 1.2 with inline image; default because image processors usually keep inline images intact, so they wouldn't want to inefficiently recompress our image) -- -pdf:0 PDF1.0: : [pts] hint /FileFormat/PDF1.0 among /PDF* (PDF 1.0 with XObject image) -- -pdf:2 PDF1.2: : [pts] hint /FileFormat/PDF1.2 among /PDF* (PDF 1.2 with XObject image) -- EPS: EPSF: : [pts] hint /FileFormat/PSL2 or /FileFormat/PSL3 (for /Compression/ZIP) -- PDF: : [pts] hint /FileFormat/PDFB1.0 or /FileFormat/PDFB1.2 (for /Compression/ZIP) -- PS: : [pts] hint /Scale/RotateOK /FileFormat/PSL2 or /FileFormat/PSL3 (for /Compression/ZIP) -- PS2: : [imagemagick] hint /Scale/RotateOK /FileFormat/PSL2. Deprecated, please use PS:. -- -e:0 -e:none : /Scale/None -- -e -e:1 -e:scale : /Scale/OK -- -e:rot -e:rotate : /Scale/RotateOK -- GIF: GIF89a: : [imagemagick,pts] /FileFormat/GIF89a -- JPEG: JPG: : [imagemagick,pts] /FileFormat/JPEG -- TIFF: TIF: : [imagemagick,pts] /FileFormat/TIFF -- PNG: : [imagemagick] /FileFormat/PNG -- XPM: : [imagemagick] /FileFormat/XPM -- BMP: : [imagemagick] /FileFormat/BMP -- Empty: : [pts] /FileFormat/Empty -- Meta: : [pts] /FileFormat/Meta -- PIP: : [pts] /FileFormat/PIP -- PAM: : [pts] /FileFormat/PAM -- PNM: : [imagemagick] /FileFormat/PNM (for use with transparency) -- PBM: : [imagemagick] /FileFormat/PNM /SampleFormat/Gray1 -- PGM: : [imagemagick] /FileFormat/PNM /SampleFormat/Gray8 -- PPM: : [imagemagick] /FileFormat/PNM /SampleFormat/Rgb8 -- -t:bin : [pts] hint /TransferEncoding/Binary (default unless /PS*) -- -t:hex : [pts] hint /TransferEncoding/Hex (default for /PSL1 /PSLC) -- -t:a85 : [pts] hint /TransferEncoding/A85 (default for /PSL2 /PSL3) -- -t:ascii : [pts] hint /TransferEncoding/ASCII -- -t:lsb1 -f:lsb2msb : [pts,tiffcp] hint /TransferEncoding/LSBfirst -- -t:msb1 -f:msb2lsb : [pts,tiffcp] hint /TransferEncoding/MSBfirst -- -c:none : [pts,tiffcp] non-default hint /Compression/None -- -c:lzw : [pts,tiffcp] hint /Compression/LZW -- -c:lzw:(1..99) : [pts] hint /Compression/LZW /Predictor ... -- -c:zip : [pts,tiffcp] hint /Compression/ZIP -- -c:zip:(1..99) : [pts] hint /Compression/ZIP /Predictor ... -- -c:zip:(1..99):(-1..9) : [pts] hint /Compression/ZIP /Predictor ... /Effort ... -- -c:(rle|packbits) : [pts,tiffcp] hint /Compression/RLE -- -c:(rle|packbits):(0..) : [pts] hint /Compression/RLE /RecordSize ... -- -c:fax : [pts] hint /Compression/Fax -- -c:fax:(-1..) : [pts] hint /Compression/Fax /K ... -- -c:dct : [pts] hint /Compression/DCT /DCT<<>> -- -c:dct:... : [pts] hint /Compression/DCT /DCT<<...>> -- -c:jpeg : [pts,tiffcp] hint /Compression/JAI, /Compression/IJG -- -c:jpeg:(0..100) : [pts] hint /Compression/JAI, /Compression/IJG /Quality ... -- -c:ijgi : [pts,tiffcp] hint /Compression/IJG -- -c:ijg:(0..100) : [pts] hint /Compression/IJG /Quality ... -- -c:g4 : [pts] equivalent to -c:fax:-1 -- -c:g3 -c:g3:1d : [pts] equivalent to -c:fax:0, -c:fax -- -c:g3:2d : [pts] equivalent to -c:fax:-2 -- -c:jai : [pts] hint /Compression/JAI -- -m:dpi:(dimen) : set /ImageDPI to `dimen' -- -m:(dimen) \ : set all margins (/TopMargin,/BottomMargin, /LeftMargin, /RightMargin) to `dimen' -m:all:(dimen) \ : /LeftMargin, /RightMargin) to `dimen' -m:a:(dimen) : -- -m:horiz:(dimen) \ : set /LeftMargin and /RightMargin to `dimen' -m:h:(dimen) \ : -m:x:(dimen) : -- -m:vert:(dimen) \ : set /TopMargin and /BottomMargin to `dimen' -m:v:(dimen) \ : -m:y:(dimen) : -- -m:left:(dimen) \ : set /LeftMargin to `dimen' -m:l:(dimen) : -- -m:right:(dimen) \ : set /RightMargin to `dimen' -m:r:(dimen) : -- -m:top:(dimen) \ : set /TopMargin to `dimen' -m:t:(dimen) \ : -m:up:(dimen) \ : -m:u:(dimen) : -- -m:bottom:(dimen) \ : set /BottomMargin to `dimen' -m:b:(dimen) \ : -m:down:(dimen) \ : -m:d:(dimen) : -- -- : if given as last arg, then OutputFile:=InputFile -- -- : if given earlier than last arg, then treat other args as filenames -- -transparent:(rgb) Change the all pixels having the specified RGB color to transparent. Previously transparent pixels are not changed. See FAQ answer A44 for an exampe. Default and fallback compression types for each file format: -- PSL1 PSLC : /RLE -- PSL2 PDFB1.0 PDF1.0 : /JAI /RLE -- PSL3 PDFB1.2 PDF1.2 : /JAI /ZIP -- GIF89a : /LZW -- XPM PNM PAM PIP Empty Meta : )/None) -- JPEG : /JAI /IJG -- TIFF : /JAI /LZW? /RLE -- PNG : /ZIP -- BMP : /RLE Overview of job mode ~~~~~~~~~~~~~~~~~~~~ In the ``job mode'' sam2p doesn't accept any command line options. It must be controlled from the ``job'' files. In ''job mode'' sam2p expects a single command line argument: the name of the Job file (file format described in section {Jobs}). sam2p runs that single job, prints debug, info, notice, warning and error messages (etc.), and creates a single output file: a PS or a PDF. For multiple jobs and/or multiple output files, one has to run sam2p multiple times. The details about the output file format (including standards-compliance, compression and transfer encoding) are specified in the Job file and other files. Thus, in order to make use of the (basic and) advanced features of sam2p in job mode, you have to: 1. Understand the basic concepts (i.e read through this manual, and have a look at the examples). 2. Prepare the input raster (bitmap) graphics file in one of the supported input formats (see section {Supported input formats}). 3. Decide the name of the output file. 4. Decide some or all details of the output format. 5. Create a Job file that describes those details. 6. Invoke the program `sam2p' with the name of the Job file as a single command-line argument (or `-' if the Job file is fed on STDIN). 7. Read warning and error messages (printed to STDOUT and STDERR), and retry if necessary. Compilation and installation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ External software required for running sam2p: -- a UNIX system with a fairly standard BSD or POSIX C library (C++ libraries are not required), or a Win32 system with MSVCRT.DLL (install Wordpad to get MSVCRT.DLL) -- optionally: the libjpeg `cjpeg' utility for /Compression/IJG -- optionally: the libjpeg `djpeg' utility for reading JPEG files -- optionally: tif22pnm (uses libtiff) from the author of sam2p -- optionally: png22pnm (uses libpng) from the author of sam2p -- optionally: the Ghostscript `gs' utility for /Compression/DCT -- optionally: the Ghostscript `gs' utility for /Compression/Fax These do not work yet (in version 0.44): -- optionally: the `lzw_codec' utility for alternative /Compression/LZW -- optionally: the GNU `gzip' utility for alternative /Compression/ZIP -- optionally: the Info-ZIP `zip' utility for alternative /Compression/ZIP For Win32 compilation, see later. Software required for UNIX compilation: -- a UNIX system -- a working, GNU-compatible C++ compiler (preferably GNU G++ >=2.91. Known working compilers: g++-2.91 g++-2.95 g++-3.0 g++-3.1 g++-3.2) -- GNU Make (`make -v' should print `GNU Make') -- Perl >=5.004 (no external Perl modules are required) -- a Bourne-compatible shell (preferably GNU Bash >=2.0) -- the following libraries are _not_ required: libjpeg, libtiff, libpng, libungif, PDFlib, zlib, libm, libstdc++ -- optionally: GNU autoconf >=2.53 (version number is important, see AC_C_CONST) Compilation: # compile and install required programs autoconf # optional, for experts only export CC=gcc-3.2 CXX=g++-3.2 # optional, for experts only ./configure --enable-gif --enable-lzw make # the stand-alone utility `./sam2p' is now built make install # optional, may not work If installation doesn't work, please copy the file `sam2p' to somewhere in your $PATH, for example /usr/local/bin. Please also copy the README to a directory like /usr/share/doc/sam2p. There is no man page -- the documentation is the readme. Testing: ./sam2p ./sam2p examples/ptsbanner_zip.job ./sam2p examples/pts2.pbm try.eps gs test.ps # try other examples: examples/*.job On Debian systems, you'll need GNU Make, Perl, GNU Bash and any of the following packages for compilation: apt-get install libc6-dev gcc-2.95 g++-2.95 apt-get install libc6-dev gcc-3.0 g++-3.0 apt-get install libc6-dev gcc-3.1 g++-3.1 apt-get install libc6-dev gcc-3.2 g++-3.2 apt-get install libc6-dev gcc-3.3 g++-3.3 apt-get install libc6-dev gcc-3.4 g++-3.4 Please also run any of the following before ./configure: export CC=gcc-2.95 CXX=g++-2.95 export CC=gcc-3.0 CXX=g++-3.0 # or g++-3.1 etc. Optionally, you may install any of apt-get install gccchecker apt-get install autoconf sam2p has been tested with a wide variety of GNU C++ compilers, including g++-2.91, g++-2.95, g++-3.0, g++-3.1, g++-3.2, i386-uclibc-g++-2.95, checkerg++-2.95. The program must be compilable _without_ _warnings_ with any of g++-2.91, g++-2.95, g++-3.0, g++-3.1, g++-3.2. If there is a compilation error, send a brief e-mail to the author immediately! Portability ~~~~~~~~~~~ sam2p is quite portable on UNIX systems. It runs on: Debian GNU/Linux Slink 2.2.13 glibc-2.0.7 (development platform) Debian GNU/Linux Potato 2.2.18 glibc-2.1.3 Debian GNU/Linux Sid 2.4.17 glibc-2.2.5 Digital OSF1 V4.0 1229 alpha Slackware 8.0/8.1 2.4.5 libc-2.2.3 gcc-2.95.3 SunOS 5.7 Generic_106541-17 sun4u sparc SUNW,Ultra-2 gcc-2.95.2 SunOS 5.8 Generic_108528-12 sun4u sparc gcc-3.0.4 Also it runs on Win32 in command line (sam2p.exe) and GUI mode (vcsam2p.exe). Command line mode is stable and it is recommended on this platform. It should work on any Linux or BSD system without modification. Porting to other Unices should be quite easy. The author welcomes portability patches. Porting to non-UNIX systems may be hard. Reasons: -- Those systems might not have GNU Make, Perl or a Bourne-compatible shell installed. So the Makefile supplied won't work, and many man hours of extra work would be necessary. -- sam2p uses the popen(3) library call to communicate with external processes. This call might not be available on non-UNIX systems. -- sam2p expects that the $PATH contains the external binaries. Some systems tend to have empty or misconfigured $PATH. On some systems, `gs' is called `gswin32c.exe' etc. sam2p 0.38 has been compiled and run successfully on: -- Linux 2.2.8 Debian Slink, g++-2.91 -- Linux 2.4.18-ac3 Debian SID, g++-2.95, g++-3.0, g++-3.1, g++-3.2 Executable size: 318kB. -- Linux 2.4.2 Debian Potato, gcc version 2.95.2 20000220 (Debian GNU/Linux) No warnings. Compilation took 0:47, executable size: 330kB. -- Linux 2.2.16-3 Red Hat Linux release 6.2 (Zoot), gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) No warnings. Compilation took 0:44, executable size: 324kB. -- OSF1 V4.0 564 alpha, gcc version 2.7.2.2 (tons of: warning: cast discards `const' from pointer target type, tons of: warning: the meaning of `\x' varies with -traditional tons of: warning: cast increases required alignment of target type) Compilation took 5 minutes, executable size: 550kB. -- SunOS 5.7 Generic_106541-19 sun4u sparc SUNW,Ultra-2, gcc version 3.1 (some: warning: cast from `char*' to `int*' increases required alignment of target type) Compilation took 2:50, executable size: 437kB. -- SunOS 5.8 Generic_108528-15 sun4u sparc, gcc version 3.1.1 (some: warning: cast from `char*' to `int*' increases required alignment of target type) Compilation took 1:26, executable size: 437kB. -- Slackware 8.0/8.1, kernel 2.4.5, libc.6.so (libc-2.2.3) gcc-2.95.3 sam2p 0.42 has been compiled and run successfully on: -- Windows 98, Visual C++ 6.0 -- Windows 98, MSYS, MingGW, G++ 3.2 Win32 compilation instructions for command-line mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To compile sam2p.exe, the Win32 equivalent of the UNIX utility sam2p, you have to install these build dependencies first: -- MinGW and MSYS, available from http://www.mingw.org -- Perl 5.004 or newer (only perl.exe and perl5*.dll are required), available from http://www.perl.com. Note that this will be a long download and a bloated install, but after that, just copy perl.exe and the single perl5*.dll to your C:\WINDOWS directory, and uninstall the rest. To build sam2p: 1. Install all the build dependencies. 2. Open the MSYS terminal window from the start menu. 3. Run `explorer .' to figure out what is the current working directory. Let's call this directory the MSYS home. 4. Download the sam2p sources into the MSYS home: http://www.inf.bme.hu/~pts/sam2p-latest.tar.gz 5. Unpack the sources. Run: tar xzvf sam2p-latest.tar.gz tar xvf sam2p-latest.tar.gz # if the previous one doesn't work 6. Run `cd sam2p-*.*' to enter the sam2p source directory. It should contain a newer version of this README and the file sam2p_main.cpp. 7. Run `perl -edie' to check whether Perl is correctly installed. It should print a line beginning with `Died '. If no such line appears (or you get a `command not found' error message), go and install Perl first. Run `echo $PATH' to find out where MSYS is searching for perl.exe. Copy perl.exe to one of those directories. 8. Run ./configure --enable-gif --enable-lzw make 9. The file sam2p.exe is now created in the current directory. Use it. You may copy it to another directory right now: cp sam2p.exe 'C:\Program Files' 10. You should invoke sam2p.exe from the command line (COMMAND.COM or CMD.EXE) with the _appropriate_ arguments, described elsewhere in this document. Don't put it into the Start menu, it won't work. (a window will flash in and disappear, showing an error message that you haven't supplied the right arguments). 11. The file bts2.tth is also created. It is an important file, because it is required for the GUI compilation. 12. Don't forget to install tif22pnm.exe to load TIFF files, djpeg.exe to load JPEG files, cjpeg.exe to save JPEG files, and png22pnm.exe to load PNG files. The installation instructions for these programs are not given here. Win32 compilation instructions for GUI mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vcsam2p.exe is a preliminary, alpha-stage attempt to provide a Win32 GUI for sam2p.exe. Currently it can load and display images, but not cannot save them. vcsam2p.exe is not ready for production use. Feel free to enhance the code. Just remember to semd me copies. You'll need Visual Studio 6.0 installed. 1. Download the sam2p sources: http://www.inf.bme.hu/~pts/sam2p-latest.tar.gz 2. Download untarka.exe to be able to unpack the sources: http://www.inf.bme.hu/~pts/untarka.exe 3. Unpack the sources. Run: untarka.exe sam2p-latest.tar.gz A directory sam2p-*.* will be created, containing a newer version of this README and the file config-vc6.h 4. You'll need bts2.tth. You can get an old, possibly outdated and buggy version directly: http://www.inf.bme.hu/~pts/bts2.tth Or, you may compile sam2p under Linux (or Win32 command-line), and copy the generated bts2.tth from there. Copy bts2.tth to the same directory as config-vc6.h 5. Start the Visual C++ 6.0 environment. 6. File / Open Workspace / File type: Projects Filename: vcsam2p.dsp Build / Set Active Configuration: vcsam2p - Win32 Release Build / Build vcsam2p.exe Build / Execute vcsam2p.exe 7. Don't forget to install tif22pnm.exe to load TIFF files, djpeg.exe to load JPEG files, cjpeg.exe to save JPEG files, and png22pnm.exe to load PNG files. The installation instructions for these programs are not given here. Please report and fix bugs in vcsam2p.exe Copyright ~~~~~~~~~ sam2p is written and owned by Szab Pter . sam2p contains code from various people. sam2p may be used, modified and redistributed only under the terms of the GNU General Public License, found in the file COPYING in the distribution, or at http://www.fsf.org/licenses/gpl.html Supported input formats ~~~~~~~~~~~~~~~~~~~~~~~ -- PNM, PBM, PGM, PPM (preferred formats for non-transparent images) -- PNM+PGM, PNM+PBM. The input is a concatenation of a PNM and a P[GB]M file with the same dimensions. The second P[GB]M contains the alpha channel. -- XPM (preferred formats for indexed images with transparency) -- BMP -- GIF, with transparency -- LBM (IFF ILBM), with transparency -- TGA (Targa) -- baseline JPEG JFIF (limited by /Compression/JAI) -- PCX -- JPEG, is supported with libjpeg/djpeg -- TIFF, is supported with the author's tif22pnm, with transparency; also works in a limited way with tifftopnm (Debian package libtiff-tools) -- PNG, is supported with the author's png22pnm, with transparency (part of the tif22pnm sources); also works in a limited way with libpng/pngtopnm (Debian package graphics/pnmtopng); with transparency -- PS, EPS, PDF: Ghostscript is needed (`gs' or `gswin32c.exe'), see also FAQ question Q39. Note that only the major features of these file formats are supported. sam2p is able to load most of these files, but not all of them. Important, but unsupported input formats: -- XBM -- XWD -- Utah RLE Input image model ~~~~~~~~~~~~~~~~~ A (sampled, raster, bitmap) image is a rectangular array of pixels (dots) plus some metadata. Each pixel is represented by an unsigned integer which is BPC (BitsPerComponent) and CPP (ComponentsPerPixel) wide. The image coordinate system (X,Y) is defined as: upper left corner is (0,0), upper right corner is (Width-1,0), lower right corner is (Width-1,Height-1). (Note that this is the natural, traditional top->down, left->right system, and it is different from PostScript and PDF!). Some pixels of the image may be without color: they're transparent. A transparent pixel is not painted, so whatever was left under it on the paper, remains visible. (On the other hand, a colored pixel overrides the pixel below unconditionally. E.g a white pixel overrides a black pixel, a half-gray pixel, and also another white pixel; but a transparent pixel leaves the original one visible.). Notions referring to transparent pixels are: transparency, opacity, transparent, opaque, alpha channel, matte channel. Images are read from image files on disk. The file format is autodetected (see section {Supported input formats}), and it can also be specified in the Job file (NOT implemented yet). Not all file formats are able to specify all pixel data and metadata, so additional hints (such as the transparent color or the name of the image author) can be specified in Job files. Sample formats ~~~~~~~~~~~~~~ The image pixels could be packed to bytes according to several sample formats. Each output file (both EPS and PDF) has its own SampleFormat (notation: capitals). A color is either transparent or it is an opaque RGB triplet (8*3 bits). The number of colors is the number of colors actually _used_. So unused palette entries, and e.g unused #555555 in gray-4 are not counted. If PSLC is required, but the printer is only PSL1, then the color image will be printed grayscale. When _choosing_ the output format, sam2p doesn't degrade image quality. For example, if an image has only two colors: #000001 and #ffffff, sam2p won't allow the gray-1 sample format, but with #000000 and #ffffff, it will. The user is expected to have an image editor in which she can adjust image colors precisely (such as in the Dialogs/(Indexed palette) dialog of The GIMP). Supported Sample Formats: Name: Fast compatibility Slow compatibility Criteria for the image -- Comment(...) transparent: (specialisation of mask) all - the whole image is transparent -- implemented with empty image body opaque: (specialisation of mask and indexed-1) all - the whole image contains the same, opaque color -- implemented with `setrgbcolor', `fill' mask: (specialisation of transparent-2) all - a transparent and a non-transparent color (any may be missing) -- display a Warning if the whole image is transparent or opaque, because transparent or opaque would be a better choice -- implemented with a single call to `imagemask' indexed-1: all - exactly 2 non-transparent colors or 1 non-transparent color -- display a Warning if only 1 non-transparent color, because opaque would be a better choice -- display a Notice if colors are in black (#000000) and white (#ffffff), beacuse gray-1 would be a better choice -- implemented with a `setrgbcolor', `fill', and a single call to `imagemask' indexed-2: PSL2, PDF1.0?? PSLC 3 or 4 non-transparent colors or 1..2 non-transparent colors -- display a Warning if only 1..2 non-transparent colors, because opaque or indexed-1 would be a better choice -- display a Notice if colors are in (#000000, #555555, #aaaaaa, #ffffff), beacuse gray-2 would be a better choice -- implemented with the /Indexed color space or colorimage + manual palette lookup -- users with a PSL1 printer without PSLC should use transparent-* indexed-4: PSL2, PDF1.0?? PSLC 5..16 non-transparent colors or 1..4 non-transparent colors -- display a Warning if only 1..4 non-transparent colors, because opaque, indexed-1 or indexed-2 would be a better choice -- display a Warning if all components are #00 or #ff, because rgb-1 would be a better choice (3 bits over 4 bits) -- display a Notice if colors are in (#000000, #111111, ..., #ffffff), beacuse gray-4 would be a better choice -- implemented with the /Indexed color space or colorimage + manual palette lookup -- users with a PSL1 printer without PSLC should use transparent-* indexed-8: PSL2, PDF1.0?? PSLC 17..256 non-transparent colors or 1..16 non-transparent colors -- display a Warning if only 1..16 non-transparent colors, because opaque, indexed-1, indexed-2, indexed-4 would be a better choice -- display a Warning if all components are #00, #55, #aa or #ff, because rgb-2 would be a better choice (6 bits over 8 bits) -- display a Notice if all colors are gray, beacuse gray-8 would be a better choice -- implemented with the /Indexed color space or colorimage + manual palette lookup -- users with a PSL1 printer without PSLC should use transparent-* transparent-2: all - 0..1 transparent and 1..3 non-transparent colors -- display a Notice that color separation was done (which can decrease speed and compression) -- display a Warning if no transparent color, because `indexed-2' would be a better choice -- display a Warning if only 1 non-transparent color, because `mask' would be a better choice -- implemented with multiple calls to `setrgbcolor', `imagemask' transparent-4: all - a transparent and 1..15 non-transparent colors -- display a Notice that color separation was done (which can seriously decrease speed and compression) -- display a Warning if only 1..3 non-transparent colors, because `mask' or `transparent-2' would be a better choice -- implemented with multiple calls to `setrgbcolor', `imagemask' transparent-8: all - a transparent and 1..255 non-transparent colors -- display a Warning that color separation was done (which can seriously decrease speed and compression) -- display a Warning if only 1..15 non-transparent colors, because `mask', `transparent-2' or `transparent-4' would be a better choice -- implemented with multiple calls to `setrgbcolor', `imagemask' gray-1: all - colors are in black (#000000) and white (#ffffff) -- display a Warning if only 1 color, because opaque would be a better choice -- implemented with the multiple-argument `image' gray-2: all - colors are in (#000000, #555555, #aaaaaa, #ffffff) -- display a Warning if only 1..2 colors, because opaque, indexed-1, or gray-1 would be a better choice -- implemented with the multiple-argument `image' gray-4: all - colors are in (#000000, #111111, ..., #ffffff) -- display a Warning if only 1..4 colors, because opaque, indexed-1, gray-1, indexed-2 or gray-2 would be a better choice -- implemented with the multiple-argument `image' gray-8: all - colors must be gray -- display a Warning if only 1..16 colors, because opaque, indexed-1, gray-1, indexed-2, gray-2, indexed-4 or gray-4 would be a better choice -- implemented with the multiple-argument `image' rgb-1: PSLC, PDF1.0 - color components must be #00 or #ff (8 colors max) -- display a Warning if all colors are gray -- display a Warning if only 1..4 colors, because opaque, indexed-1, indexed-2 (or gray-*) would be a better choice -- implemented with `colorimage' rgb-2: PSLC, PDF1.0 - color components must be #00, #55, #aa or #ff (64 colors max) -- display a Warning if all colors are gray -- display a Warning if only 1..16 colors, because opaque, indexed-1, indexed-2 or indexed-4 (or gray-*) would be a better choice choice (this includes the case when color components are in #00, #ff) -- implemented with `colorimage' rgb-4: PSLC, PDF1.0 - color components must be #00, #11, ... #ff (4096 colors max) -- display a Warning if all colors are gray -- display a Warning if only 1..256 colors, because opaque, indexed-1, indexed-2, indexed-4 or indexed-8 (or gray-*) would be a better choice (this includes the case when color components are in #00, #55, #aa, #ff) -- implemented with `colorimage' rgb-8: PSLC, PDF1.0 - no transparency -- display a Warning if all colors are gray -- display a Warning if only 1..256 colors, because opaque, indexed-1, indexed-2, indexed-4 or indexed-8 (or gray-*) would be a better choice -- display a Warning if all color components are in #00, #11, ... #ff, because rgb-4 would be a better choice -- implemented with `colorimage' The following directed (acyclic) graph represents that some formats should be tried earlier than others to avoid most Warning and Notice messages. The graph was created according to the descriptions above. EarlierFormat LaterFormat transparent mask opaque mask opaque indexed-1 indexed-1 indexed-2 indexed-2 indexed-4 indexed-4 indexed-8 gray-1 gray-2 gray-2 gray-4 gray-4 gray-8 rgb-1 rgb-2 rgb-2 rgb-4 rgb-4 rgb-8 gray-1 indexed-1 gray-2 indexed-2 gray-4 indexed-4 gray-8 indexed-8 rgb-1 indexed-4 rgb-2 indexed-8 mask transparent-2 transparent-2 transparent-4 transparent-4 transparent-8 opaque gray-1 indexed-1 gray-2 indexed-2 gray-4 indexed-4 gray-8 opaque rgb-1 gray-1 rgb-1 gray-2 rgb-2 gray-4 rgb-4 gray-8 rgb-8 indexed-2 rgb-1 indexed-4 rgb-2 indexed-8 rgb-4 indexed-8 rgb-8 Every directed acyclic graph (DAG) has a topological ordering on its nodes. Such an ordering can be computed by the UNIX (Version 7 AT&T UNIX) utility tsort(1). Its output on the author's machine: opaque transparent gray-1 indexed-1 mask transparent-2 gray-2 indexed-2 transparent-4 rgb-1 gray-4 indexed-4 transparent-8 rgb-2 gray-8 indexed-8 rgb-4 rgb-8 This ordering should be taken into account when someone develops her Rule Profile. Rules having SampleFormats listed earlier should be earlier in the Rule Profile to avoid Warning and Notice messages. The availability (and also Warnings and Notices) of a Sample Format for a particular image can be easily decided after answering the following characteristic questions: -- Is transparency _used_? -- How many _used_ non-transparent colors are there? (257 if >=257) -- Is there a non-gray color? -- How many bits are required (maximum) for each component? Output rules ~~~~~~~~~~~~ Every detail of the output file format is precisely determined by the Output Rule. The Output Rule may be specified in the Job file, or is automatically chosen from several pre-defined output rules in the Output Profile (see section {Output profiles} elsewhere in this document). Output rule entries: -- FileFormat: enum (see section {Standards} for detailed information), no default /PSL1 -- PostScript Level1 /PSLC -- PostScript Level1 with the CMYK and `colorimage' extension /PSL2 -- PostScript Level2 (default) /PSL3 -- PostScript Level3 /PDFB1.0 -- PDF version 1.0, BI inline image, see 4.8.6 in PDFRef.pdf /PDFB1.2 -- PDF version 1.2, BI inline image, see 4.8.6 in PDFRef.pdf /PDF1.0 -- PDF version 1.0, XObject image, see 4.8.4 in PDFRef.pdf /PDF1.2 -- PDF version 1.2, XObject image, see 4.8.4 in PDFRef.pdf /GIF89a /Empty /Meta /PNM /PAM /PIP /TIFF /JPEG /PNG /XPM -- SampleFormat: enum, no default, see section {Sample formats} /Opaque /Transparent /Gray1 /Indexed1 /Mask /Transparent2 /Gray2 /Indexed2 /Transparent4 /Rgb1 /Gray4 /Indexed4 /Transparent8 /Rgb2 /Gray8 /Indexed8 /Rgb4 /Rgb8 /Asis -- accept contents of the JAI file /Bbox -- no image, only bounding box information -- WarningOK: boolean; this Output Rule is enabled iff WarningOK is true or SampleFormat causes no warnings, default: true -- TransferEncoding: enum, no default /Binary -- Binary (RawBits, see pbm(5), pgm(5), ppm(5)) (Binary integers are stored in any byte order allowed by /FileFormat) /ASCII -- ASCII (text, chars: 9,10,13,32..126), used with transparent and opaque /Hex /AHx -- Hex ((PSL1), PDF1.0, PSL2 ASCIIHexEncode filter) /A85 -- A85 (PSL2 PDF1.0, ASCII85Encode filter) /MSBfirst -- Binary data with integers stored in MSB first byte order. If 0x41424344 is represented as "ABCD", the byte order is called: big endian, MSB, MSB first (preferred), most significant byte first, most significant bit first, MSB-to-LSB, network byte order, m68k byte order. QuarkXPress 3 can read only TIFF files with MSB-to-LSB byte order. /LSBfirst -- Binary data with integers stored in LSB first byte order. If 0x41424344 is represented as "DCBA", the byte order is called: little endian, LSB, LSB first (preferred), least significant byte first, least significant bit first, LSB-to-MSB, VAX byte order, PC (i386) byte order. -- Compression: enum /None -- None (default) /LZW -- LZW (PSL2 PDF1.0 LZWEncode filter EarlyChange=true, UnitLength=8 LowBitFirst=false) /ZIP /Flate /Fl -- ZIP (PSL3 PDF1.2 FlateEncode filter without options) /RLE /RunLength /RunLengthEncoded /RL /PackBits -- RLE (PSL2 PDF1.0 RunLengthEncode filter, similar to TIFF PackBits) /Fax /CCITTFax /CCF -- Fax (PSL2 PDF1.0 CCITTFaxEncode filter, Uncompressed=true!, K=-1,0,1, EndOfLine=false, EncodedByteAlign=false, Columns=..., Rows=0, EndOfBlock=true, BlackIs1=false, DamagedRowsBeforeError=0) /DCT -- DCT (PSL2 PDF1.0 DCTEncode, options in JPEG stream) /IJG /JPEG /JPG /JFIF -- IJG (PSL2 PDF1.0 DCTEncode, options in JPEG stream; the IJG libjpeg library is used for compression, respecting the quality value 0..100). This requires /SampleFormat/Rgb8 or /SampleFormat/Gray8. This doesn't work with /SampleFormat/Asis. /JAI -- JAI (PSL2 PDF1.0 DCTEncode, options in JPEG stream; JPEG-as-is: the input file must be a JPEG file -- its contents are transferred unmodified into the /DCTDecode JPEG stream). This requires /SampleFormat/Asis, and doesn't work with any other /SampleFormats -- Predictor: enum (see later), default: 25, numbering same as PSL1 filter. 1 -- no predictor. (default) Must be this unless Compression is /LZW or /Flate 2 -- TIFF predictor 2 (horizontal differencing) 10 -- PNG predictor, None function 11 -- PNG predictor, Sub function 12 -- PNG predictor, Up function 13 -- PNG predictor, Average function 14 -- PNG predictor, Paeth function 15 -- PNG predcitor, individually chosen for each line (absolute minimum) This is the same as what libpng uses by default when creating PNG. 25 -- Pick 15 or 1 based on the SampleFormat: use 15 for Gray8 and Rgb8, and use 1 (no predictor) for everything else. This is the default. 45 -- PNG predcitor, individually chosen for each line (unsigned minimum) Don't use this, it is quite inefficient. 55 -- PNG predcitor, individually chosen for each line (signed minimum) Don't use this, it is quite inefficient. -- Transparent: color. Default: null. Specify a color forced to be transparent. Old transparency, if exists, is blacked! -- Hints: dict see below The Hints member of the Output Rule contains a dict with the following elements: -- TopMargin : dimen; desired vertical gap between the top line of the page and the top line of the raster. Default: 0. Ignored unless for PS and PDF output. See docs about `dimen' elsewhere in this document. -- BottomMargin : dimen; desired vertical gap between the bottom line of the raster and the bottom line of the page. Default: 0. Ignored unless for PS and PDF output. See docs about `dimen' elsewhere in this document. -- LeftMargin : dimen; desired horizontal gap between the left line of the page and the left line of the raster. Default: 0. Ignored unless for PS and PDF output. See docs about `dimen' elsewhere in this document. -- RightMargin : dimen; desired horizontal gap between the right line of the raster and the right line of the page. Default: 0. Ignored unless for PS and PDF output. See docs about `dimen' elsewhere in this document. -- ImageDPI : positive number; resolution of bitmap image in dots per inch. Default: 72, which means no scaling. -- Scale : enum /None -- don't scale (zoom, magnify) the image (default) /OK -- scale PS image to fit page (x factor == y factor) /RotateOK -- scale and/or rotate PS image to fit page (x factor == y factor) -- EncoderBPL : int >=1 (bits per scanline, <= rlen) -- EncoderCoumns : int >=1 (pixels per scanline) -- EncoderRows : int >=1 -- EncoderColors : int >=1 -- PredictorColumns : uint; also used if compression is /Fax (reasonable default) -- PredictorColors : 1..3; number of color _components_ (reasonable default) -- PredictorBPC : 1, 2, 4, 8 (reasonable default), /BitsPerComponent entry in PS and PDF -- Effort : -1..9, must be -1 unless Compression is /ZIP (-1 means 5, default) -- RecordSize : uint, default: 0. Compression must be /RLE -- K : int, default: 0 (-2..infty). Compression must be /Fax. -1 means G4 1d encoding, 0 meangs G3 1D encoding, -2 means G3 2D encoding with arbitrary height, positive value means G3 2D encoding with that height. -- Quality : 0..100, used by IJG libjpeg when compression is /IJG. default: 75 -- ColorTransform : 0..2. For IJG, this _must_ be 0 for Gray and 1 for RGB, so its value is ignored. For DCT, its value is respected: use 0 or 1 only. See DCTEncode in subsubsection 3.13.3 in PLRM.pdf, and for a better documentation: see the sources and docs of libjpeg. -- TransferCPL : number of data characters per line. Must be positive when TransferEncoding is /Hex or /A85, and must be zero otherwise. Default: 78 -- DCT : dict, default: <<>>. Additional parameters for the /DCTEncode filter -- Comment : string, default: empty -- Title : string, default: empty -- Subject : string, default: empty -- Author : string, default: empty -- Creator : string, default: empty -- Producer : string, default: empty -- Created : string, default: now -- Produced : string: default: now Metric units """""""""""" Certain parameters have type `dimen'. This is a metric dimension, measured in any of the following real-word distance metric units: -- 1 bp = 1 bp (big point) -- 1 in = 72 bp (inch) -- 1 pt = 72/72.27 bp (point) -- 1 pc = 12*72/72.27 bp (pica) -- 1 dd = 1238/1157*72/72.27 bp (didot point) [about 1.06601110141206 bp] -- 1 cc = 12*1238/1157*72/72.27 bp (cicero) -- 1 sp = 72/72.27/65536 bp (scaled point) -- 1 cm = 72/2.54 bp (centimeter) -- 1 mm = 7.2/2.54 bp (millimeter) Note: If it helps: American typesetters use 72 points per US inch, thus 10 pt text will yield 72 chars per normal line of US Letter (like an IBM Selectric) 12 pt text will yield 65 chars per normal line of US Letter (US normal typewritter). Each image pixel is assumed to be 1 bp wide and 1 bp tall. A dimen is an integer or real number, followed by optional whitespace and an optional unit (any of `bp', `in', `pt', `pc', `dd', `cc', `sp', `cm', `mm'). The default unit is `bp', i.e a bare number is a dimen measured in `bp'. The following dimens are all one inch long: `72', `72bp', `72 bp', `1in', `1 in', `2.54cm', `25.4mm', `72.27pt', `6pc', `4736286.72sp'. Note: MiniPS and TeX use the same units. OutputRule combinations ~~~~~~~~~~~~~~~~~~~~~~~ In the final version of sam2p, the following combinations will be supported: LZW >=2 Binary|Hex|A85 >=PSL2|>=PDF1.0 Mask|Gray*|RGB*|Indexed* LZW >=2 Binary|Hex|A85 >=PSL2|>=PDF1.0 Transparent+ ZIP >=2 Binary|Hex|A85 >=PSL3|>=PDF1.2 Mask|Gray*|RGB*|Indexed* ZIP >=2 Binary|Hex|A85 >=PSL3|>=PDF1.2 Transparent+ None|ZIP|LZW|RLE|Fax|DCT|IJG 1 Binary|Hex|A85 >=PSL2|>=PDF1.0 Mask|Gray*|RGB*|Indexed* None|ZIP|LZW|RLE|Fax|DCT|IJG 1 Binary|Hex|A85 >=PSL2|>=PDF1.0 Transparent+ None 1 ASCII >=PSL1|>=PDF1.0 Opaque None 1 ASCII >=PSL1|>=PDF1.0 Transparent ZIP 1 Binary|Hex|A85 >=PSL1 Gray*|RGB*|Indexed* ZIP 1 Binary|Hex|A85 >=PSL1 Mask|Gray1|Indexed1 ZIP 1 Binary|Hex|A85 >=PSL1 Transparent+ None 1 Binary|Hex|A85 >=PSL1 Gray*|RGB*|Indexed* None 1 Binary|Hex|A85 >=PSL1 Mask|Gray1|Indexed1 None 1 Binary|Hex|A85 >=PSL1 Transparent+ RLE 1 Binary|Hex|A85 >=PSL1 Gray*|RGB*|Indexed* RLE 1 Binary|Hex|A85 >=PSL1 Mask|Gray1|Indexed1 RLE 1 Binary|Hex|A85 >=PSL1 Transparent+ JAI 1 Binary|Hex|A85 >=PSL2|>=PDF1.0 Asis TTM files ~~~~~~~~~ TTM stands for Template Toy Macro. A TTM file is a dirty hack for generating templates with auto-calculated lengths and offsets. Currently they are used for generating PDF output files (/FileFormat/PDFB10 etc.). The syntax of a TTM file is MiniPS (i.e a minimalistic PostScript, similar to .job files). The TTM file must contain a single MiniPS array. The elements of the array are called chunks. Each chunk causes some bytes to be appended to the output file. Data is appended in the order the chunks are listed in the TTM file, but the data calculation order may be different. This way it is possible to write (calc) the length of a chunk not written (filled in) yet. The very first chunk has number zero. different. This way it is possible to write the length of a chunk not written yet. The very first chunk has number zero. The chunk types: -- string: backtick-sequences will be substituted (e.g ``w' to the width of the image, in pixels) by writeTemplate(). The result is appended to the output file. -- positive integer: The offset (zero-based byte-position of the very first character of chunk 0) of the specified chunk will be appended to the output file. Only chunks already appearead may be specified this way. If the specified chunk is an array, then printf("%10u") will be called to print the number (this is useful for making PDF xref tables), otherwise printf("%u") will be called. -- negative integer: The length (measured in bytes, after substitutions) of the specified chunk will be appended to the output file, using printf("%u"). Only chunks already calculated may be specified this way. -- zero: error -- array: the array is interpreted as a standalone TTM subfile, and the rules are applied recursively. This subfile contains sub-chunks, and the subchunks may be arrays themselves. -- other MiniPS types: error The chunks are calculated in the following order: first the array chunks are calculated (recursively) in order of appearance, followed by the non-array chunks in order of appearance. A TTM file can have up to 64 top-level chunks. Example: [ 1 %0 [ (pts) ] %1.0 -1 %2 ] The output file will be: `3pts0000000001' since chunk 1 has length 3 and offset 1. Example job file ~~~~~~~~~~~~~~~~ <<%sam2p job % This is file (named test0.job). /InputFile (test0.pbm) /OutputFile (test0.pdf) /Profile [ % This in-line profile is preferred over the defaults << /FileFormat/PDF10 /SampleFormat/Gray1 /TransferEncoding/Binary /Compression/Fax /Hints<> >> (pdf10.jib) run % elements found in external file ] >> See the directory examples/*.job in the sam2p sources. FAQ ~~~ Q1. Should I care about /LoadHints (,asis,) when loading JPEG files? A1. No, sam2p guesses it by magic (in both job mode and one-liner mode). However, you may want to set it manually in job mode: /LoadHints () % use djpeg /LoadHints (,asis,) % don't use djpeg % nothing: automatic guess, based on /Compression/JAI Q2. How do I convert a JPEG file to PostScript Level2 EPS? A2. In one-liner mode, just run: ./sam2p Example: ./sam2p try.jpg try.eps In one-liner mode, if you have both the djpeg and cjpeg utilities (budled with libjpeg from IJG (Independent JPEG Group)), _and_ you want to adjust quality vs size of the output, just run: ./sam2p -c:jpeg: Example: ./sam2p -c:jpeg:60 try.jpg try.eps In job mode, just run sam2p with the following .job file: <<%sam2p-job; % conversion is possible without external utilities cjpeg and djpeg % No quality loss, just verbatim adata copying. /InputFile (INPUT.jpg) /OutputFile (OUTPUT.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Asis /TransferEncoding/A85 /Compression/JAI >> ] >> Alternatively, to adjust quality vs size, use the following .job file: <<%sam2p-job; % external utilities cjpeg and djpeg are required % This uses a JPEG decompression (djpeg), plus lossy JPEG compression % (cjpeg), so there might be quality loss! /InputFile (INPUT.jpg) /OutputFile (OUTPUT.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Rgb8 /TransferEncoding/A85 /Compression/IJG /Hints << /Quality 40 % 0..100 (should be at least around 30) >> >> ] >> Q3. How do I convert a GIF file to PostScript Level2 EPS? A3. Check that sam2p has been compiled with GIF support: run sam2p, and examine its console output. It should contain a line: Available Loaders: ... GIF ... If GIF doesn't appear in the line, please recompile sam2p with: make clean ./configure --enable-gif --enable-lzw make cp sam2p /usr/local/bin After that, run sam2p again, and check for the line above again. In one-liner mode, just run: ./sam2p Example: ./sam2p try.gif try.eps In job mode, if the GIF file doesn't have transparent pixels, run sam2p with the following .job file: <<%sam2p-job; /InputFile (INPUT.gif) /OutputFile (OUTPUT.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/A85 /Compression/None >> ] >> If the GIF file has transparent pixels, run sam2p with the following .job file: <<%sam2p-job; /InputFile (INPUT.gif) /OutputFile (OUTPUT.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Transparent8 /TransferEncoding/A85 /Compression/None >> ] >> Q4. How do I covert a JPEG file to a TIFF/JPEG output file? A4. A TIFF/JPEG file is a TIFF file (_not_ a JPEG file!), in which the image data is compressed with JPEG (DCTEncode compression). The Compression TIFF tag value is 7. (There is also Compression==6, which corresponds to the old, obsolete JPEG format defined in the old TIFF6.0 spec.) In one-liner mode, autodetection is magical. Just run: ./sam2p Example: ./sam2p try.jpg try.tiff In job mode, run sam2p with the following .job file: <<%sam2p-job; /InputFile (INPUT.jpg) /OutputFile (OUTPUT.tiff) %/LoadHints (asis) % default for /Compression/JAI /Profile [ << /FileFormat/TIFF /SampleFormat/Asis /TransferEncoding/Binary /Compression/JAI >> ] >> See also {FAQ question Q5} for compatibility notes. Q5. The TIFF/JPEG file generated by sam2p is invalid! I cannot read it with any programs. A5. No, it isn't invalid, but most of the programs (including those found in libtiff) cannot deal with TIFF files with JPEG compression. Compatibility notes: -- tif22pnm 0.03 (from the author of sam2p) can read TIFF/JPEG files perfectly. That's because it calls the TIFFRGBAImageGet() function of libtiff, which works. -- sam2p 0.37 can read TIFF/JPEG files, beacuse it calls tif22pnm to do the job. Sam2p can write TIFF/JPEG files as well. -- GIMP 1.0.2: error message: `Unknown photometric number 6'. GIMP TIFF import filter cannot deal with the YCbCr color space (which is the most common and de facto standard color space in non-grayscale JPEG files). It works, however, with grayscale JPEGs. -- tifftopnm from libtiff-tools 3.4beta037-5.1: `unknown photometric: 6'. Ditto. (Unfortunately tifftopnm doesn't call TIFFRGBAImageGet(), it just tries to re-implement an obsolete version of the function.) -- `tiffcp -c jpeg' from libtiff-tools 3.4beta037-5.1 creates a perfectly legal TIFF/JPEG file. -- tiffcp from libtiff-tools 3.4beta037-5.1 cannot load a file created by itself (`tiffcp -c jpeg')! There is no problem with grayscale images, but color images have one component removed. -- xv 3.10a: Ditto. -- display from ImageMagick 4.04: strange error message about libraries: `JPEGLib: Wrong JPEG library version: library is 61, caller expects 62.' Simple conclusion: -- Use sam2p or `tiffcp -c jpeg' to create a TIFF/JPEG. (Be aware that `tiffcp -c jpeg' cannot read a TIFF/JPEG: it can only create one.) -- Use tif22pnm to load or decode a TIFF/JPEG. -- In your own C programs, call the TIFFRGBAImageGet() function to read TIFF image data. -- Don't use anything else if you want to avoid compatibility problems. Q6. Does sam2p support transparency and alpha channels? A6. sam2p supports only bilevel transparency (i.e a pixel is either fully opaque or fully transparent), and only with indexed images. Transparency is supported when loading indexed PNG, TIFF, PNM, GIF, LBM and XPM files. A PNM file with transparency is a regular PBM/PGM/PPM file with a PBM image appended to it as the alpha channel (black pixel is transparent). For transparent output, the user has to specify /Transparent, /Mask, /Transparent2, /Transparent4 or /Transparent8 as /SampleFormat. This works with: -- /FileFormat/PSL1+ /SampleFormat/Transparent -- /FileFormat/PDF1.0+ /SampleFormat/Transparent -- /FileFormat/PDFB1.0+ /SampleFormat/Transparent -- /FileFormat/PSL1+ /SampleFormat/Mask -- /FileFormat/PDF1.0+ /SampleFormat/Mask -- /FileFormat/PDFB1.0+ /SampleFormat/Mask -- /FileFormat/GIF89a /SampleFormat/Mask -- /FileFormat/PNM /SampleFormat/Mask -- /FileFormat/TIFF /SampleFormat/Mask -- /FileFormat/PNG /SampleFormat/Mask -- /FileFormat/XPM /SampleFormat/Mask -- /FileFormat/PSL1+ /SampleFromat/Transparent+ -- /FileFormat/GIF89a /SampleFormat/Transparent+ -- /FileFormat/PNM /SampleFormat/Transparent+ -- /FileFormat/TIFF /SampleFormat/Transparent+ -- /FileFormat/PNG /SampleFormat/Transparent+ -- /FileFormat/XPM /SampleFormat/Transparent+ Q7. How large is a pixel of PostScript and PDF files generated by sam2p in real-world metric units (inches or centimeters)? A7. 72 big points == 1 inch == 2.54 centimeters 1 pixel == 1 big point Q8. I have an image with transparent pixels. What happens if I convert it to /Rgb* or /Gray*? A8. Either of the following will happen: -- You get an error message, sam2p refuses to ignore transparency. Please use /SampleFormat/Transparent+, or call an image manipulation program to remove transparency from the image before feeding it to sam2p. -- Transparency information will be lost, and the color of formerly transparent pixels will be undefined. This would be a bug in sam2p, you should report it. However, if you loaded a GIF file, and transformed it to /Gray8 or /Rgb8, the original palette entry (RGB triplet) is faithfully preserved. Q9. How do I generate a PostScript page ready for immediate printing with margins and the image properly scaled to fit the page? How do I create a PostScript file that will automatically scale the image to the maximum when printed? A9. To print an image as a full PostScript page, call: ./sam2p [MARGIN-SPECS] ps: - | lpr Example: ./sam2p -m:1cm examples/pts2.pbm ps: - | lpr To create a PostScript file for printing, call: ./sam2p [MARGIN-SPECS] [ps:] Example: ./sam2p -m:1cm examples/pts2.pbm try.ps The `-m' option above is sets all four margins to `1 cm'. You can set the margins individually: Example: ./sam2p -m:left:7mm -m:right:1cm -m:top:0.5in \ -m:bottom:18bp examples/pts2.pbm try.ps As you can see in this example, you may specify dimensions in various metric units, see subsection {Metric units}. You are strongly encouraged to print raster images with sam2p. Be aware that The GIMP 1.2 printing plugin has several weird contrast setting problems (even for /Gray1 images); white pixels will be gray etc. Other utilities may add unnecessary text banners or scale the image inappropriately. In one-liner mode, sam2p guesses from the file extension and the selector (`ps:') whether the desired output file format is PostScript (fit single page) or Encapsulated PostScript (leave size as-is, suitable for inclusion into TeX documents). In job mode, without /Scale/OK and /Scale/RotateOK in /Hints, sam2p outputs EPS (Encapsulated PostScript) with /FileFormat/PSL*. EPS files should be included as figures into other documents (such as TeX and InDesign), not printed alone. If you just want to print a sampled image alone, please use your favourite graphics manipulation program instead of sam2p. In job mode, create a .job file for the EPS file, and add /Hints. For example: <<%sam2p-job; /InputFile (test.in) /OutputFile (test.ps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Rgb8 /TransferEncoding/A85 /Compression/None /Predictor 1 /Hints << /Scale/OK % or /Scale/RotateOK /LeftMargin 12 % measured as number/72 inches /Rightargin 12 % measured as number/72 inches /TopMargin 12 % measured as number/72 inches /BottomMargin 12 % measured as number/72 inches >> >> ] >> Q10. Do the EPS files created by sam2p conform to some specifications? The EPS output of sam2p conforms to the following Adobe specifications: 5001.DSC_Spec.pdf 5002.EPSF_Spec.pdf DSC and ADSC are: Adobe Document Structuring Conventions. They are comments with lines beginning with `%!' and `%%' in PS and EPS files. An excerpt: The following example illustrates the proper use of DSC comments in a typical page description that an application might produce when including an EPS file. For an EPS file that is represented as %!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 4 4 608 407 %%Title: (ARTWORK.EPS) %%CreationDate: (10/17/89) (5:04 PM) %%EndComments ...PostScript code for illustration.. showpage %%EOF DSC comments discussion: %!PS-Adobe-3.0 EPSF-3.0 (mandatory) %%BoundingBox: ... ... ... ... (mandatory) %%Extensions: CMYK (optional, for /PSLC) %%LanguageLevel: 2 (optional, for /PSL2) %%LanguageLevel: 3 (optional, for /PSL3) %%Creation (strongly recommended) %%Title (strongly recommended) %%CreationDate (strongly recommended) %%Trailer (optional) %%EOF (optional) %%DocumentData: Clean7Bit (optional) %%DocumentData: Binary (optional) Q11. I get the error message `sam2p: Error: applyProfile: invalid combination, no applicable OutputRule'. Help! A11. This error message means you have requested an invalid combination of FileFormat, SampleFormat, Compression etc. parameters. If you use one-liner mode, and you're sure that you've specified your will correctly in the command line, please report this error message as a sam2p bug (also specify -j in the command line). If you use job mode, please read on. Example 1: /Compression/Fax is not allowed in /PSL1. Solution 1: specify /FileFormat/PSL2 /Compression/Fax. Example 2: /Compression/IJG requires /SampleFormat/Gray8 or /SampleFormat/Rgb8. Please have a look at the messages `sam2p: Warning: check_rule: ...' to get more specific information. After that, correct your request. Solution 2: specify /Compression/IJG /SampleFormat/Rgb8. Another cause for this message is that your request cannot be applied to the image you've specified. In this case, there is no relevant `sam2p: Warning: check_rule: ...' message. Example 1: you've requested /SampleFormat/Indexed4, but the input image has more than 16 colors. Solution 1: specify /SampleFormat/Rgb8. Example 2: you've requested /SampleFormat/Indexed4, but the input image has transparency. Solution 2: specify /SampleFormat/Transparent8. It is possible, but very unlikely that this error message is caused by a bug in sam2p. Q12. Can I use /Compression/Fax when bits-per-pixel > 1 ? A12. With /FileFormat/PS* and /FileFormat/PDF*, you can (but you shouldn't, because of the possibly poor compression ratio). With /FileFormat/TIFF, you're not allowed to, because the TIFF specification forbids it. Example one-liners: sam2p -s:Indexed8 -c:fax test.gif test.pdf # OK sam2p -s:Indexed8 -c:fax test.gif test.eps # OK sam2p -s:Indexed8 -c:fax test.gif test.tiff # forbidden Q13. Bad luck? A13. Not for me. Q14. Can I use negative margins (i.e /TopMargin -20) to crop the output image? A14. No. Margins are ignored by sam2p unless /FileFormat is /PSL* or /PDF*. Even with these formats, the image is only moved, not cropped. Please use an image manipulation program (e.g The GIMP) to crop your images before feeding them to sam2p. Q15. When I try to print the PostScript output of sam2p, the edge of the image is missing (white). A15. Many printers cannot print to the edge of the paper (so that region is left white). Please increase the margins to a safe value, for example: ./sam2p -m:7mm test.ppm test.ps lpr test.ps See also {FAQ question Q9} for more information about margins. Q16. How do I report a bug in sam2p? A16. Please send an e-mail to the author (pts@fazekas.hu, see more in section {Copyright}) describing the problem. Don't forget to: -- download the latest version of sam2p, and try it with the same image -- describe what sam2p does (incorrectly) -- describe what sam2p should do if there was no bug -- run sam2p without arguments, and attach its output (STDOUT) to the bug report -- attach the exact command line with which you call sam2p to the bug report -- if you spot the bug in one-liner mode, specify the `-j' option in the command line, and attach the messages printed by sam2p (both STDOUT and STDERR) to the bug report -- if you spot the bug in job mode, attach the .job file you are using to the bug report -- attach the input image file to the bug report. Try to attach a file as small as possible. -- if sam2p runs successfully (i.e it prints `Success.'), and it creates an output image, but you think that the output image is incorrect, attach the output image to your bug report -- if you have a similar input image, for which sam2p works fine, attach it to the bug report Q17. How long does the LZW patent held by Unisys last? A17. mcb@cloanto.com (author of http://lzw.info) wrote: Thank you for your interest and mail. I must stress that the "exact" answers you may be looking for may come only from lawyers and courts, and I am none of these. If you consider the IBM, the BT and Unisys US patents, then the last of the three would be the Unisys one, expiring, as the article I think mentions, on June 19, 2003, 24:00. There cannot be other (new) patents on LZW, as far as I know. Please let me know if you find different information. Q18. I want to create an RGB PostScript image, but sam2p creates a Gray one, or it gives me an error message. For example: `./sam2p -1 -s:rgb1 examples/ptsbanner.gif test.eps'. A18. /PSL1 doesn't support RGB images. There are two solutions: -- Use /PSLC or /PSL2 or /PSL3 instead or drop the '-1' alltogether. Examples: ./sam2p -1c -s:rgb1 examples/ptsbanner.gif test.eps # /PSLC ./sam2p -2 -s:rgb1 examples/ptsbanner.gif test.eps # /PSL2 ./sam2p -s:rgb1 examples/ptsbanner.gif test.eps # /PSL2 or /PSL3 -- Use /Mask or /Transparent+. Note that you'll very probably get poor compression ratio. ./sam2p -1 -s:tr:stop examples/ptsbanner.gif test.eps # /PSL1 You can get more (and more useful) error messages from sam2p if you specify the `-j:warn' option. You may also try specifying `-s:rgb1:stop' instead of `-s:rgb1' to force sam2p try /SampleFormat/Rgb1 only. Q19. sam2p doesn't allow me to use /Compression /Fax. For example: `./sam2p -c fax examples/ptsbanner.gif test.eps'. The same command works fine without `-c fax'. A19. /Compression/Fax is intended to be used with images with 1 bit per pixel. However, in PostScript and PDF, you can use it for any image data, but compression ratio will be very poor for other than /Gray1, /Indexed1 or /Mask, of course. You can force sam2p to use /Fax by specifying the desired SampleFormat in option `-s'. Examples: sam2p -s:Indexed8 -c:fax test.gif test.pdf # OK sam2p -s:Indexed8 -c:fax test.gif test.eps # OK sam2p -s:Indexed8 -c:fax test.gif test.tiff # forbidden by TIFF std See {FAQ question Q12} for more information. Q20. Can sam2p convert images with transparency to PDF? A20. Only if the image has at most 1 non-transprent color (/SampleFormat/Mask). See {FAQ question Q6} for details. Although PDF-1.3 supports transparency masks for arbitrary PDF images, sam2p 0.39 doesn't. That's because the author of sam2p hasn't implemented it yet. Q21. I get the error message `sam2p: Warning: buildProfile: ignoring, no handlers for OutputRule'. Help! A21. This means that sam2p doesn't know how to do the conversion you've requested (and it even doesn't know whether the request is erroneous or not). This might be because your request is bad (it is impossible to be fulfilled), or your request is good, but sam2p doesn't know how to deal with it. If you think that the latter is the case, please report this message as a bug. See {FAQ question Q11} for more information. Q22. How do I compile with G++ 3.2? A22. See the answer in section {Compilation and installation}. Don't forget export CC=gcc-3.2 CXX=g++-3.2 Q23. How do I do a `make dist' without running configure again? A23. Just issue make MAKE_DIST=1 dist Q24. I cannot open a JPEG file in the Win32 version. A24. Make sure you have djpeg.exe on your PATH. Simply copy it to your C:\WINDOWS directory. Q25. I cannot open a TIFF file in the Win32 version. A25. Make sure you have tif22pnm.exe on your PATH. Simply copy it to your C:\WINDOWS directory. Q26. I cannot open a PNG file in the Win32 version. A26. Make sure you have png22pnm.exe on your PATH. Simply copy it to your C:\WINDOWS directory. Q27. What is tif22pnm? A27. tif22pnm is a TIFF -> PNM converter written by the author of sam2p. It can load more TIFF files correctly than tifftopnm, ImageMagick convert, xv and The GIMP. The TIFF loader code is based on GIMP 1.3, but has many bugfixes and improvements. sam2p uses tif22pnm to load TIFF files. You can download tif22pnm from http://www.inf.bme.hu/~pts/tif22pnm-latest.tar.gz Q28. What is png22pnm? A28. png22pnm is a PNG -> PNM converter compiled by the author of sam2p. It is based on the excellent pngtopnm utility, but doesn't depend on the NetPBM library (only libpng). sam2p uses png22pnm (or, as a fallback: pngtopm) to load PNG files. png22pnm is part of the tif22pnm package, so you can download it from http://www.inf.bme.hu/~pts/tif22pnm-latest.tar.gz Q29. Can sam2p convert a transparent GIF to PDF? A29. The PDF-1.3 file format supports transparent images, but sam2p doesn't. However, if the image contains at most two colors (including the transparent pixel), sam2p can create a working PDF-1.2 file; use Ghostscript to view it, because Acrobat Reader 5.0 is buggy. However, sam2p supports generating transparent EPS, GIF, PNG, PNM, XPM and TIFF files up to 256 colors. Q30. How do I build my own sam2p debian package? A30. Please download the newest sources from http://www.inf.bme.hu/~pts/sam2p-latest.tar.gz As root, run apt-get update apt-get install debmake fakeroot dpkg apt-get install make g++ gcc perl sed As normal user, run (in the directory containing sam2p_main.cpp): debian/rules clean rm -f build* debian/rules build fakeroot debian/rules binary ls -l ../sam2p_*.deb As root, substitute X and Y, and run: dpkg -i sam2p_X_Y.deb Please also install the tif22pnm and png22pnm packages from the author of sam2p (and the Debian standard libjpeg-progs package), available as Debian source from: http://www.inf.bme.hu/~pts/tif22pnm-latest.tar.gz Q31. Why not use libjpeg/libtiff/libpng/zlib or any other library with sam2p? A31. -- library and .h incompatibilities (the binary would be less portable across Linux systems) -- to avoid forced dependencies -- checkergcc wouldn't work Q32. How do I specify the page size when printing a .ps file (-m and -e command line options)? A32. You cannot. (Use -m to specify the margins.) The page size is autodetected by your printer when the page is printed. So you can print the same .ps file on different printers, and the margins will be all right on all of them. If you really have to specify the page size, edit the .ps file and insert the `a4 ' or `letter ' command after the last line of the first block of lines starting with %%. You may also use something like `1 dict dup /PageSize [ 595 842 ] put setpagedevice ' to exactly specify the page width and height in 1/72 inches. For example, change the PostScript file %!PS-Adobe-3.0 %%Pages: 1 %%DocumentData: Clean7Bit %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save ... % many lines omitted %%Trailer %%EOF to %!PS-Adobe-3.0 %%Pages: 1 %%DocumentData: Clean7Bit %%LanguageLevel: 1 %%EndComments %%Page: 1 1 1 dict dup /PageSize [ 595 842 ] put setpagedevice save ... % many lines omitted %%Trailer %%EOF Please note that PostScript is a programming language, so your changes might be undone by instructions later in the file. You might find the a2ping.pl utility (written by the author of sam2p) useful: a2ping.pl -v --papersize=a4 in.ps out.ps Q33. How do I control ZIP compression ratio? A33. Use sam2p -c:zip:1:0 in.img out.png # uncompressed ZIP carrier sam2p -c:zip:1:1 in.img out.png # normal compression sam2p -c:zip:1:9 in.img out.png # maximum compression Q34. ImageMagick convert creates smaller PNGs. Why? A34. I don't know the real reason. Probably because ImageMagick uses libpng, which is smarter than sam2p. You are probably trying to convert a JPEG or other true color photo to PNG. Try one of the following compression options: sam2p -c:zip:12:7 # 464727 bytes sam2p -c:zip:12:8 # 454271 bytes sam2p -c:zip:12:9 # 447525 bytes sam2p -c:zip:13:9 # 488748 bytes sam2p -c:zip:14:9 # 454182 bytes sam2p -c:zip:15:9 # 453080 bytes convert -quality ? # 454438 bytes Q35. Can sam2p convert large JPEGs to smaller ones (with loss of quality and resolution)? A35. sam2p cannot resize or scale images. So the pixel width and height of the input and output image cannot be changed. If you need that (for example you want to create thumbnails), use the famous convert(1) utility of ImageMagick. For example: convert -scale 444 -quality 50 in.jpg out.jpg # specify out width convert -scale x444 -quality 50 in.jpg out.jpg # specify out height convert -scale "10%" -quality 50 in.jpg out.jpg # specify scale ratio However, it is possible to specify the quality of the JPEG output of sam2p. The quality of 0 means ugly output with small file size, and the quality of 100 means nice output with big file sizes. You can specify intermediate integer quality values (50 and 75 are recommended). Be prepared that qualties above 30 (or so) may not work on all JPEG viewers. For example: sam2p -c ijg:10 large_input.jpg small_output.jpg sam2p uses the cjpeg(1) and djpeg(1) utilities from libjpeg to write and read JPEG files, respectively. If you need more control over your JPEG output, then forget sam2p, and please consult the documentation of those utilities. Q36. Can sam2p convert JPEG to GIF? A36. Yes, it can, but usually not directly. GIF allows a maximum of 256 different colors in an image. A typical RGB JPEG image contains many more colors, so it has to be quantized down to 256 colors first. For example, if the console output of ``sam2p in.jpg out.gif'' contains ``applyProfile: invalid combination, no applicable OutputRule'', then in.jpg must be quantized first: convert in.jpg out1.gif # does the quantization automatically sam2p out1.gif out2.gif # compresses the output image further From out1.gif and out2.gif keep the one with the smaller file size. It is common that convert(1) creates huge GIF files because LZW compression is disabled inside it. sam2p should be compiled with LZW compression and GIF input/output enabled. To check this, run sam2p, and examine its console output. It should contain a line: Available Appliers: ... GIF89a+LZW ... If GIF89a+LZW doesn't appear in the line, please recompile sam2p with: make clean ./configure --enable-gif --enable-lzw make cp sam2p /usr/local/bin , and try again. Q37. I need to transform GIF images of 15 colors to BMPs of 256 colors not compressed. sam2p converts it to BMP 16 colors... A37. Use sam2p -c none -s rgb8 in.gif out.bmp If you get an error message `Error: applyProfile: invalid combination, no applicable OutputRule', it very probably means that your GIF is transparent. Remove the transparent color within an image editor first. Q38. Can sam2p _load_ PDF or EPS files? A38. Yes, if you have Ghostscript installed, and your input EPS file is not too exotic. This has been tested on Linux only. If you experience problems loading EPS files, but no problems loading PDF files, please run a2ping.pl written by the author of sam2p to make your EPS file more compatible. Q39. Can sam2p load an EPS or PDF file with an arbitrary resoultion? A39. Yes. For example use one of sam2p -l:gs=-r216 in.eps out.png sam2p -l:gs=-r216 in.pdf out.png to have resoultion 216 DPI (image scaled 3 times to both directions). Without scaling, 72 DPI is the default. Q40. Can sam2p emit a multi-page PDF or a multi-page PS? A40. No, it can't. Emitting a multi-page document would need a fundamental change of the sam2p architecture. (Should the 2nd page be compressed with a different method? What if the 2nd contains too many colors? Should we keep all previous pages in memory?) I think another program should be written that is able to concatenate EPS/PS or PDF files. I've already written a PDF-merger called pdfconcat, available from http://www.inf.bme.hu/~pts/pdfconcat.c . An EPS-merger would be even easier. But I don't have time to implement these features directly into sam2p soon. Q41. Can sam2p read a multi-page TIFF? A41. sam2p reads only the first page. The auxilary utility tif22pnm could be patched so it extracts other pages, and a new command line option can be added to sam2p that passes the required page number to tif22pnm. But I don't have time to implement these features soon. By the way, multi-page TIFFs can be created with the following command: tiffcp -c g4 d1.tiff d2.tiff d3.tiff output.tiff Q42. Can sam2p convert a multi-page TIFF to a multi-page PDF? A42. No. There are two main problems: See also Q40 and Q41. Q43. How do I convert a TIFF image to a 1-bit black-and-white PDF? Should I use `sam2p -c:fax test.tif test.pdf'? A43. The above will ensure that fax compression is used. What you need for ensuring that the output is 1-bit black-and-white is: sam2p -s:gray1:stop test.tif test.pdf You can also specify a compression algorithm (I recommend -c:zip): sam2p -c:fax -s:gray1:stop test.tif test.pdf sam2p -c:lzw -s:gray1:stop test.tif test.pdf sam2p -c:zip -s:gray1:stop test.tif test.pdf If you get the error message sam2p: Error: applyProfile: invalid combination, no applicable OutputRule then your input test.tif is not really black-and-white. Open it in an image editing program and ensure that the colors are #000000 and #ffffff only. > The tiff is black and white, bilevel - I just want to avoid the > test.pdf from using 8bpp by default (like it does in imagemagick) The default for sam2p is not 8bpp. To see what the default is, run sam2p with the `-j' option and check `OutputRule #1' on the console output. What you are interested in is the /SampleFormat field. Q43. Acrobat Reader (5.0 and 6.0) cannot read the PDFs converted from a JPEG with sam2p. I get the message: `There was an error processing a page. Expected `EI' while parsing an image.'. (The same problem happens with Ghostscript 6.50 with a different error message. xpdf-1.0 reports: bad DCT trailer.) A43. Very probably the JPEG stream of your original input image file is rejected by the PDF viewers. (In fact, Ghostscript 7.x doesn't complain.) sam2p doesn't do strict JPEG validation when converting JPEG to PDF -- it just blindly assumes that the JPEG file is correct. To ensure this, you have to re-encode the JPEG. Instead of this: sam2p bad.jpeg bad.pdf do this: sam2p -c ijg:50 bad.jpeg good.pdf # much slower! or this: temp.pnm cjpeg -quality 50 temp.jpeg sam2p temp.jpeg good.pdf The real reason why Acrobat Reader rejects the JPEG is unknown to me. I also don't know of any baseline JPEG compliance testing software. (But if you re-encode with djpeg and cjpeg, it becomes compliant.) (thanks to Thomas Kraemer for reporting the problem) Q44. How do I create an 1x1 transparent GIF and PNG? A44. Do echo "P1 1 1 0" >one.pbm sam2p -transparent:ffffff one.pbm one.gif sam2p -transparent:ffffff one.pbm one.png Q45. Is it possible to specify a resolution other than 72 DPI, so that the dimensions of the resulting PDF are accurate for print-resolution images? A45. Yes, it is. Use `-m:dpi:144' to have the output EPS or PDF scaled to double size, or use `-m:dpi:' to have it scaled by a factor of /72, or 72/-, if is negative. If you know that your input image resolution is DPI, and you want to sam2p to create an EPS or PDF keeping the image resolution, you should use `-m:dpi:-'. Note that this works only for EPS and PDF output. For all other FileFormat{}s, `-m:dpi:' is ignored. The `-m:dpi:' option doesn't scale the values specified for the other `-m:...' options. Some image file formats such as PNG an JPEG can contain resolution information. sam2p ignores this and assumes that the input image resolution is 72 DPI). It would be possible to improve sam2p to use this information, but it would be too much work. To proper way of scaling an image, however, is using your DTP or word processor program to resize it properly. For example, after running `sam2p foo.png foo.pdf', in LaTeX, use % \usepackage{graphicx} \includegraphics[height=10cm]{foo} Q46. Is it legal to use LZW compression? A46. I think so. Also look at Q17. Q47. Help! I cannot compile it on SunOS/Solaris. I get /usr/include/sys/wait.h:90: type specifier omitted for parameter /usr/include/sys/wait.h:90: parse error before `*' A47. Until someone adds a test to ./configure, try adding the line #define siginfo_t void to the end of config2.h, just before running `make'. Q48. Should I run sam2p over all my EPS (or PDF) files, to see if they would become smaller? A48. No! This is a bad idea in general, because you lose information, since the EPS output of sam2p is always rasterized, so it is not scalable anymore. But you may run sam2p over all those EPS files which contain raster graphics. But please be aware that sam2p re-renders everything at 72 DPI (can be overridden by `-l:gs=-r', and the gs rendering sometimes adjusts RGB color values slightly (+-2 on in the 0..255 domain), so there might be quality loss during the _reading_ of the original EPS. There is absolutely no quality loss when sam2p _writes_ the EPS. Q49. Should I run sam2p over all my GIF, TIFF and XPM files, to see if they would become smaller? A49. Yes, run `sam2p --' if you have a backup copy of the original. Otherwise, choose a different filename for output. Q50. Should I run sam2p over all my PNG files, to see if they would become smaller? A50. You might try it, there will be no quality loss, but the general experience of the author is that the tools using libpng (e.g. pnmtopng) produce slightly smaller PNG than sam2p. If you are an image compression specialist, please help the author to find the reason of this, and enhance sam2p. Q51. Should I run sam2p over all my JPEG files, to see if they would become smaller? A51. sam2p doesn't change the file by default. Use the `-c:ijg' option (possibly with a JPEG quality parameter, e.g. `-c:ijg:50') to make sam2p re-encode the JPEG. This is a lossy operation, and the size of the output file depends on quality parameter specified, so it might actually become larger than the original. Please also note that JPEG meta-information (such as EXIF tags inserted by digital cameras) gets completely lost with `-c:ijg'. Q52. How do I use ZIP (Deflate) compression in LanguageLevel 2? A52. Run this: sam2p -c:zip PSL2: in.image out.eps This will make sam2p emit the image decoding procedure so the image will be viewable (veeeery slowly) on LanguageLevel 2 devices, too. It doesn't affect the rendering speed on LanguageLevel 3 devices. Q53. How do I create a GIF from an image with more than 256 colors? A53. You need the pnmquant utility too from NetPbm. Run this: sam2p in.image PPM:- | pnmquant 256 | sam2p - out.gif Or, if you have the convert utility from ImageMagick, run: sam2p in.image PPM:- | convert - out.gif Q54. What is the maximum image size sam2p supports? A54. As of version 0.45, the following limits apply for input images: -- Input image height times image width must be <= 2000000000 pixels. Individual dimensions can be as high as necessary. -- Input image memory must be <= 1000000000 bytes (1 GiB). The memory is computed by multiplying image width, image height and BPC. BPC is number of bytes per pixels. It is 3 for RGB images, 1 for grayscale and indexed (256-color palette) images. For some temporary calculations BPC might go up to 3 even if it is smaller than 3 in the input image, so to be safe, always assume that BPC is 3 in image memory calculations. -- For JPEG input or ouput, image width and height must be <= 65535 pixels. This is an inherent limitation in the JPEG file format. In earlier versions (0.44 or below) the following additional limits applied: -- Image width must be <= 65535 pixels. -- Image height must be <= 65535 pixels. sam2p is a fast image conversion tool: it isn't unnecessarily slow on large images. Its speed is predictable for uncompressed images: it slows down proportionally to the input image memory (see the calculation below). Q55. How do I get the smallest PNG output? A55. If your input image is truecolor, please consider a lossy compression file format (such as JPEG), because the ZIP compression used in PNG is not particularly well-suited for truecolor images. If your input image has only a few colors, specify `-c zip:25:9', which forces the ZIP compression whith a high effort (9) and predictor autodetection (25). This is considerably slower than not specifying any `-c' flag at all, and getting `-c zip:25', because the high effort (9) is slower than the default effort. Please note that `-c zip:25:9' disables the predictor unless the SampleFormat is Rgb8 or Gray8. (This is the same what libpng-1.2.15 does by default.) For large images (of Rgb{1,2,4,8} or Gray{1,2,4,8}), you may want to specify `-c zip:15:9' to forcibly enable the predictor, being autodetected for each image row. Please also note that the free software ``optipng'' and the free-to-use closed-source software PNGOUT (for Win32, Linux and Mac OS X) can produce PNGs about 10% smaller than what sam2p produces -- but they are a 100 times (or even more) slower than sam2p. The tool ``pnmtopng'' (tested with one linked to libpng 1.2.20) does not produce smaller PNGs than sam2p >= 0.46. For older versionf of sam2p, the output of ``pnmtopng'' was about 5--10% smaller. Please also note that the the PNG output of Ghostscript -sDEVICE=pngmono etc. is not optimal. Convert it with sam2p or the tools mentioned above to reduce the file size. Q56. How do I get the smallest PDF output? A56. If your input image is truecolor, specify `-c jpeg', possibly tuning it with a low quality parameter e.g. `-c jpeg:30'. If your input image has only a few colors, specify `-c zip:25:9' or `-c zip:15:9', see also Q55. Please also have a look at Q55. Unfortunately, sam2p doesn't yet support calling external PNG optimizers and converting their output to PDF. Q57. Does sam2p convert images to canonical form, i.e. if I have two source images with identical width, height and RGB8 pixel representation, and I convert both with sam2p with the same flags, will the two output image files be byte-by-byte identical? A57. Yes, since version 0.46-2. The only code code needed for that was sorting the indexed palette. For blackbox input images which sam2p doesn't decompress (e.g. JPEG with /Compression/JAI), the output is only guaranteed to be byte-byte-byte identical, if the input was byte-byte-byte identical. Q58. Can sam2p generate a PDF which is scaled proportionally (i.e. keeping the aspect ratio) to a specified page size, and centered on the page? A58. No, but the Perl script sam2p_pdf_scale.pl bundled with sam2p can post-process the file created by sam2p. For example, to scale and center a PDF on an A4 paper, do: $ sam2p input.img output.pdf $ sam2p_pdf_scale.pl 595 842 output.pdf Please also have a look at the LaTeX package pdfpages.sty for more options. It can also be used to concatenate multiple PDFs. Its documentation: http://www.ctan.org/get/macros/latex/contrib/pdfpages/pdfpages.pdf Example output.tex file: \documentclass{article} \pdfcompresslevel9 \paperwidth 21cm \pdfpagewidth\paperwidth \paperheight29.7cm \pdfpageheight\paperheight \usepackage{pdfpages} \begin{document} \includepdf{output_tmp.pdf} \end{document} How to compile the .tex file above: $ sam2p input.img output_tmp.pdf $ pdflatex output.tex Please note that a2ping.pl or pdftk won't work either. Q59. How does sam2p detect the bounding box of PostScript and EPS input? A59. For PostScript input, the paper size specified in the PostScript code is used, reverting to the system's default paper size if missing. PostScript input is detected by finding `%!PS-Adobe-' at the beginning of the file, but `EPSF-' missing from the first line. Paper size can be specified in the PostScript code using `<> setpagedevice', 'a4', `letter' etc. The comments `%%BoundingBox:' etc. are ignored. For EPS input, the `%%ExactBoundingBox:' is used, reverting to `%%HiResBoundingBox:', reverting to `%%BoundingBox:', reverting to the system's default paper size. The paper size specified in the PostScript code is ignored. EPS input is detected by finding `%!PS-Adobe-' at the beginning of the file and `EPSF-' in the first line. When converting to PostScript, EPS or PDF, the (in.llx, in.lly) coordinates of the input bounding box are not preserved: the output file will always have (0, 0) as its lower left corner and (in.urx-in.llx, in.ury-in.lly) as its upper right corner. Upsampling ~~~~~~~~~~ Here is a figure about upsampling samples bits 1 -> 2 -> 4 -> 8: 0 -> 00 0 1 -> 11 3 00 -> 0000 0 01 -> 0101 5 10 -> 1010 10 11 -> 1111 15 0000 -> 0000 0000 0 0001 -> 0001 0001 17 0010 -> 0010 0010 34 ... 1110 -> 1110 1110 238 1111 -> 1111 1111 255 A 1-bit image has a palette of 2 colors: #00 and #ff. A 2-bit image has a palette of 4 colors: #00, #55, #aa and #ff. A 4-bit image has a palette of 16 colors: #00, #11, #22, ... #ff. An 8-bit image has a palette of 256 colors: #00, #01, #02, ... #ff. Standards ~~~~~~~~~ -- PSL1 is PostScript LanguageLevel1, as defined by Adobe's PostScript Language Reference Manual. -- PSLC is PSL1 with the CMYK extension (including the `colorimage' operator). Supersedes PSL1. -- PSL2 is PostScript LanguageLevel2, as defined by Adobe's PostScript Language Reference Manual. Supersedes PSLC. -- PSL3 is PostScript LanguageLevel3, as defined by Adobe's PostScript Language Reference Manual (PLRM.pdf). Supersedes PSL2. -- PDF1.0 is PDF version 1.0, as defined by Adobe's PDF Reference. -- PDF1.1 is PDF version 1.1, as defined by Adobe's PDF Reference. Supersedes PDF1.0. -- PDF1.2 is PDF version 1.2, as defined by Adobe's PDF Reference. Supersedes PDF1.1. -- PDF1.3 is PDF version 1.3, as defined by Adobe's PDF Reference. Supersedes PDF1.2. -- PDF1.4 is PDF version 1.4, as defined by Adobe's PDF Reference (PDFRef.pdf). Supersedes PDF1.3. -- PDF1.5 is PDF version 1.4, as defined by Adobe's PDF Reference (PDFRef.pdf). Supersedes PDF1.4. -- PBM is Portable Bitmap file format, as defined in NetPBM's pbm(5) UNIX manual page. -- PGM is Portable Graymap file format, as defined in NetPBM's pgm(5) UNIX manual page. -- PPM is Portable Pixmap file format, as defined in NetPBM's ppm(5) UNIX manual page. -- PNM is Portable Anymap file format, as defined in NetPBM's pnm(5) UNIX manual page. It is the union of PGM, PPM and PPM. -- PAM is the new, Portable ...map file format, as defined in NetPBM's pam(5) UNIX manual page. We don't support it yet. -- TIFF is ... v6.0. -- JPEG is baseline JPEG JFIF file format as defined by the Joint Picture Expert Group. -- PNG is Portable Network Graphics file format v1.0, as defined by RFC 2083. Obsolete: Image metadata ~~~~~~~~~~~~~~~~~~~~~~~~ -- Width: uint -- Height: uint -- ColorSpace: enum (see later), determines PixBits -- PixBits: 1..24 -- Origin: coord -- Comment: string -- FileFormat: -- Predictor: enum (see later), same as PSLanguageLevel1 filter /Predictor 1 -- no predictor 2 -- TIFF predictor 2 (horizontal differencing) 10 -- PNG predictor, None function 11 -- PNG predictor, Sub function 12 -- PNG predictor, Up function 13 -- PNG predictor, Average function 14 -- PNG predictor, Paeth function 15 -- PNG predcitor, individually chosen for each line -- PredictorColumns: uint -- PredictorColors: 1..3 -- PredictorBitsPerComponent: 1, 2, 4, 8 -- CompressionEffort: -1..9 (ZIP) -- CompressionRecordSize: uint (RLE, Fax: K) -- Compression: enum 0 -- None 1 -- LZW (PSL2 PDF1.0 LZWEncode filter EarlyChange=true, UnitLength=8 LowBitFirst=false) 2 -- ZIP (PSL3 PDF1.2 FlateEncode filter without options) 3 -- RLE (PSL2 PDF1.0 RunLengthEncode filter, similar to TIFF PackBits) 4 -- Fax (PSL2 PDF1.0 CCITTFaxEncode filter, Uncompressed=true!, K=-1,0,1, EndOfLine=false, EncodedByteAlign=false, Columns=..., Rows=0, EndOfBlock=true, BlackIs1=false, DamagedRowsBeforeError=0) 5 -- DCT (PSL2 PDF1.0 DCTEncode, options in JPEG stream) 6 -- IJG (PSL2 PDF1.0 DCTEncode, options in JPEG stream; the IJG libjpeg library is used for compression, respecting the quality value 0..100) 7 -- JAI (PSL2 PDF1.0 DCTEncode, options in JPEG stream; JPEG-as-is: the input file must be a JPEG file -- its contents are transferred unmodified into the /DCTDecode JPEG stream) -- TransferEncoding: enum 0 -- Binary (RawBits, see pbm(5), pgm(5), ppm(5)) 1 -- ASCII (text, chars: 9,10,13,32..126) 2 -- Hex ((PSL1), PDF1.0, PSL2 ASCIIHexEncode filter) 3 -- 85 (PSL2 PDF1.0, ASCII85Encode filter) 4 -- base64, _not_ implemented 5 -- quoted-printable, _not_ implemented 6 -- URLencode, _not_ implemented Compatibility notes ~~~~~~~~~~~~~~~~~~~ by pts@fazekas.hu at Wed Nov 14 12:14:15 CET 2001 Fri Mar 22 11:48:36 CET 2002 Sat Apr 20 19:57:44 CEST 2002 Fri Feb 7 11:15:39 CET 2003 -- Ghostscript 6.50 has problems with /FileFormat/PDFB1.0 /SampleFormat/JAI|/IJG/DCT (Error: /syntaxerror in ID). The problem has been fixed in Ghostscript 7.04. With the buggy Ghostscript use /FileFormat/PDF1.0 instead. -- /FileFormat/PDF[B]1.0 /SampleFormat/Mask|/Indexed1 doesn't work on Acrobat Reader 5.0 on Linux: a fully opaque, one-color rectangle is painted. This works fine on gs 6.50 and xpdf 1.0, so Acrobat Reader is assumed to be buggy. -- The GIMP 1.0 cannot load PlanarConfig Separated TIFF images of type GrayA. (But can load PlanarConfig Contiguous GrayA.) -- xv cannot display gray TIFF images with transparency. xv: Sorry, can not handle 2-channel images. -- (lib)tiff FAX compression an PS /CCITTFaxEncode have black and white the opposite way. So `/CCITTFaxEncode <>' has to be applied when creating a TIFF file. -- libtiff 3.5.4 doesn't read or write an indexed image with transparency: Sorry, can not handle contiguous data with PhotometricInterpretation=1, and Samples/pixel=2. (Doesn't work with convert or GIMP.) -- libtiff 3.5.4 doesn't read or write a gray with transparency: Sorry, can not handle contiguous data with PhotometricInterpretation=2, and Samples/pixel=2. (Doesn't work with convert, works with GIMP.) -- libtiff doesn't read or write TIFFTAG_SUBFILETYPE/FILETYPE_MASK + TIFFTAG_PHOTOMETRIC/PHOTOMETRIC_MASK. One has to use TIFFTAG_EXTRASAMPLES instead. -- libtiff (and the TIFF file format) supports only /Predictor 1 and /Predictor 2, with /Compression/LZW and /Compression/ZIP. -- libtiff supports only bpc=8 and bpc=16 with /Predictor 2 -- libtiff and most TIFF-handling utils have buggy support for TIFF/JPEG. See FAQ answer Q4. -- libtiff supports only files with all components having the same BitsPerSample. -- acroread 4.0 can display all possible /Predictor values with /Indexed1. -- Ghostscript 5.50 renders (PDF?) images inaccurately: the last bit of the 8-bit palette sometimes gets wrong. -- Netscape Navigator 4.7 displays transparent PNG images with their bKGD (or an arbitrary color if bKGD not present) as a solid background. This is a bug. -- pdftops 0.92 has serious problems displaying images if /Predictor != 1. The image will be obscured without an error message. Ghostscript 5.50 and Acrobat Reader 4 do not have such problems. -- Ghostscript 5.50 cannot display a PDF with /ColorSpace[/Indexed/DeviceRGB ...]. Acrobat Reader 4, Ghostscript 7.04 and pdftops 0.92 can. -- /Decode is not required in PDF. -- GIMP 1.0 completely ignores the PNG tRNS chunk! (Thus it won't recognise such a transparency in PNG.) Use `pngtopnm -alpha' instead! -- pngtopnm honors the PNG bKGD chunk only if called as `pngtopnm -mix' (and does mixing) -- convert honors the PNG bKGD chunk (and does mixing) -- display doesn't honor the PNG bKGD chunk, but has `-bg' command line option -- xv honors the PNG bKGD chunk (and does mixing) -- PDF procsets (subsection 8.1 of PDFRef.pdf) /PDF /Text /ImageB Grayscale images or image masks /ImageC Color images /ImageI Indexed (color-table) images -- Ghostscript always requires the /Decode entry in image dicts -- /DCTEncode and /DCTDecode supports only BitsPerComponent==8. -- Actually PostScript supports 1,2,4,8,12 BitsPerComponent. PDF1.3 supports only 1,2,4,8. We support only 1, 2, 4 and 8. -- PostScript also supports the CMYK color space, not just gray and RGB. (And also the HSB, which can be transformed to RGB in an ugly way.) -- PostScript supports PNG predictors to enhance compression. -- The PLRM 4.10.6 describes a trick with patterns and imagemask to do transparent images. Unfortunately this doesn't work in Ghostscript 5.50 and xpdf 0.92 (but it works in acroread 4.0), so we don't use it. That's why we have only two *-transparent-* entries. -- ImageMagick EPSI is an EPS with preview (%%BeginPreview .. %%EndPreview) -- ImageMagick EPSF and EPS are equivalent -- ImageMagick EPS* is incredibly slooow because of the bad design, even for LanguageLevel 2. -- ImageMagick EPS* cannot display color images without the colorimage opertor. (We could do some trickery with multiple calls to imagemask.) -- tiff2ps cannot display color images without the colorimage opertor. (We could do some trickery with multiple calls to imagemask.) -- Timing: 1495 x 935 RGB, gs -sDEVICE=bmp16m -sOutputFile=/dev/null time gs -q -sDEVICE=ppmraw -sOutputFile=t.ppm $IN.eps setgray currentgray % PSL1, 0.0=black 1.0=white sethsbcolor % PSL1 setrgbcolor % PSL1 setcmykcolor % PSL2; not in PSL1 Algorithms, code comments ~~~~~~~~~~~~~~~~~~~~~~~~~ RGB -> Gray """"""""""" gray = 0.299*red + 0.587*green + 0.114*blue (NTSC video std) gray = (306.176*red + 601.088*green + 116.736*blue) >> 10 perl -e 'no integer;for(@ARGV){y/#//d;$N=hex($_);$R=0.299*($N>>16)+0.587*(($N>>8)&255)+0.114*($N&255);print $R/255," ",sprintf("#%02x",int($R+0.5)),"\n"}' '#0f0f0f' Rgb2 -> Gray """""""""""" perl -e 'no integer;for(@ARGV){print"$_ ";y/#//d;$N=hex($_);$R=0.299*($N>>16)+0.587*(($N>>8)&255)+0.114*($N&255); print "",$R/255," ",sprintf("#%02x",int($R+0.5)),"\n"}' 000000 000055 0000aa 0000ff 005500 005555 0055aa 0055ff 00aa00 00aa55 00aaaa 00aaff 00ff00 00ff55 00ffaa 00ffff 550000 550055 5500aa 5500ff 555500 555555 5555aa 5555ff 55aa00 55aa55 55aaaa 55aaff 55ff00 55ff55 55ffaa 55ffff aa0000 aa0055 aa00aa aa00ff aa5500 aa5555 aa55aa aa55ff aaaa00 aaaa55 aaaaaa aaaaff aaff00 aaff55 aaffaa aaffff ff0000 ff0055 ff00aa ff00ff ff5500 ff5555 ff55aa ff55ff ffaa00 ffaa55 ffaaaa ffaaff ffff00 ffff55 ffffaa ffffff 000000 0 #00 000055 0.038 #0a 0000aa 0.076 #13 0000ff 0.114 #1d 005500 0.195666666666667 #32 005555 0.233666666666667 #3c 0055aa 0.271666666666667 #45 0055ff 0.309666666666667 #4f 00aa00 0.391333333333333 #64 00aa55 0.429333333333333 #6d 00aaaa 0.467333333333333 #77 00aaff 0.505333333333333 #81 00ff00 0.587 #96 00ff55 0.625 #9f 00ffaa 0.663 #a9 00ffff 0.701 #b3 550000 0.0996666666666667 #19 550055 0.137666666666667 #23 5500aa 0.175666666666667 #2d 5500ff 0.213666666666667 #36 555500 0.295333333333333 #4b 555555 0.333333333333333 #55 5555aa 0.371333333333333 #5f 5555ff 0.409333333333333 #68 55aa00 0.491 #7d 55aa55 0.529 #87 55aaaa 0.567 #91 55aaff 0.605 #9a 55ff00 0.686666666666667 #af 55ff55 0.724666666666667 #b9 55ffaa 0.762666666666667 #c2 55ffff 0.800666666666667 #cc aa0000 0.199333333333333 #33 aa0055 0.237333333333333 #3d aa00aa 0.275333333333333 #46 aa00ff 0.313333333333333 #50 aa5500 0.395 #65 aa5555 0.433 #6e aa55aa 0.471 #78 aa55ff 0.509 #82 aaaa00 0.590666666666667 #97 aaaa55 0.628666666666667 #a0 aaaaaa 0.666666666666667 #aa aaaaff 0.704666666666667 #b4 aaff00 0.786333333333333 #c9 aaff55 0.824333333333333 #d2 aaffaa 0.862333333333333 #dc aaffff 0.900333333333333 #e6 ff0000 0.299 #4c ff0055 0.337 #56 ff00aa 0.375 #60 ff00ff 0.413 #69 ff5500 0.494666666666667 #7e ff5555 0.532666666666667 #88 ff55aa 0.570666666666667 #92 ff55ff 0.608666666666667 #9b ffaa00 0.690333333333333 #b0 ffaa55 0.728333333333333 #ba ffaaaa 0.766333333333333 #c3 ffaaff 0.804333333333333 #cd ffff00 0.886 #e2 ffff55 0.924 #ec ffffaa 0.962 #f5 ffffff 1 #ff Building the palette for Paletted image -> PSLC colorimage """""""""""""""""""""""""""""""""""""""""""""""""""""""""" { Buf3 0 0 currentfile Bufx readstring pop % /i 0 def % Stack: Buf3 0 0 Bufx { % Stack: Buf3 <0-1-2> exch { { % Stack: Buf3 dup -2 bitshift Pal exch get % Stack: Buf3 exch 4 bitshift /Carry exch def % Stack: Buf3 3 copy put pop 1 add 1 % Stack: Buf3 1 }{dup -4 bitshift Carry add Pal exch get exch 15 and 2 bitshift /Carry exch def 3 copy put pop 1 add 2 }{dup -6 bitshift Carry add Pal exch get % Stack: Buf3 exch 4 copy % Stack: Buf3 Buf3 pop put % Stack: Buf3 63 and Pal exch get pop % Stack: Buf3 exch 1 add exch 3 copy put pop 1 add 0 % Stack: Buf3 0 } } exch % Stack: Buf3 {code3} <0-1-2> get exec % Stack: Buf3 <1-2-0> } forall % Stack: Buf3 pop pop Bufr } Color space conversion: (unfinished) """""""""""""""""""""""""""""""""""" -- Ripped from jccolor.c from libjpeg: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) -- RGB -> YCbCr: Y = 0.29900 * R + 0.58700 * G + 0.11400 * B Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE -- CMYK -> YCCK: R=1-C, G=1-M, B=1-Y, K=K, RGB -> YCbCr -- YCbCr -> RGB: (Cb < CENTERJSAMPLE, Cr < CENTERJSAMPLE) R = Y + 1.40200 * Cr G = Y - 0.34414 * Cb - 0.71414 * Cr B = Y + 1.77200 * Cb -- YCCK -> CMYK: YCbCr -> RGB, C=1-R, M=1-G, Y=1-B, K=K. -- (YCbCrK == YCCK) -- Gray -> RGB: red = gray, green = gray, blue = gray -- RGB -> Gray: gray = 0.299*red + 0.587*green + 0.114*blue (NTSC video std) : gray = (306.176*red + 601.088*green + 116.736*blue) >> 10 : gray = (19595.264*red + 38469.632*green + 7471.104*blue) >> 16 -- Obsolete: RGB -> YCbCr: (YCbCr == YUV) y:luminance = 0.299*red + 0.587*green + 0.114*blue (0..1) cb:chrominance-b = blue - y = - 0.299*red - 0.587*green + 0.886*blue (-0.886 .. 0.886) cr:chrominance-r = red - y = 0.701*red - 0.587*green - 0.114*blue (-0.701 .. 0.701) Chrominance components can be represented less accurately since the human eye is around twice as sensitive to luminance as to chrominance. -- RGB <-> HSB: quite obfuscated. See gshsb.c in Aladdin Ghostscript's source. Word frequency counting in PostScript source """""""""""""""""""""""""""""""""""""""""""" perl -e '$C=0; $X=join"",; for (split" ",$X) { print "$_.\n"; $C+=length($_)-1 if /[0-9]/ }; print STDERR "C=$C\n"' ; $X=~s@([{}])@ $1 @g; $X=~s@/@ /@g; for (split" ",$X) { print "$_.\n" if length>=2; $C++ if length($_)>=2 }; print STDERR "C=$C\n"' | sort | uniq ; $X=~s@([{}])@ $1 @g; $X=~s@/@ /@g; $Y=""; for (split" ",$X) { $_=" $_ " if length($_)>=2; $Y.=$_ }; $Y=~s@ /@/@g; print $Y' >t How tiff2ps displays a gray version of a PSLC Rgb8 image on PSL1 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" gsave 100 dict begin 1495.000000 935.000000 scale /bwproc { rgbproc dup length 3 idiv string 0 3 0 5 -1 roll { add 2 1 roll 1 sub dup 0 eq { pop 3 idiv 3 -1 roll dup 4 -1 roll dup 3 1 roll 5 -1 roll put 1 add 3 0 } { 2 1 roll } ifelse } forall pop pop pop } def /colorimage where {pop} { /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def } ifelse %ImageData: 1495 935 8 3 0 1 2 "false 3 colorimage" /line 4485 string def 1495 935 8 [1495 0 0 -935 0 935] {currentfile line readhexstring pop} bind false 3 colorimage pts_defl.c which function calls which function """""""""""""""""""""""""""""""""""""""""""""" send_bits rengeteg flush_outbuf send_bits flush_block 2* build_tree flush_block 3* flush_block deflate2 5* ct_tally deflate2 sok* longest_match deflate2 2* fill_window deflate2 4* gen_codes 2, reentrant deflate2 1.. pts_deflate_init 1 Answers from Taco """"""""""""""""" Are the problems I'm concerned about already solved? -- Is there a pixel image converter that can create small and compatible EPS documents with all the RunLength, CCITTFax, LZW and Flate compression types? -- Is there a PDF version of psfrag.sty? Is there a utility for splitting and assebling PDF files? Is there a utility for changing text labels inside a PDF file? -- Is there a utility for creating (semi-)transparent EPS or PDF files from pixel images? Compilation problems """""""""""""""""""" -- Mrten Svantesson wrote: > Another problem was that the configure script didn't realise that it > couldn't use the forte CC-compiler. This lead to several errors. For > example it doesn't accept the option -ansi, so several tests fail for > this reason. I don't have access to the a forte CC-compiler. The configure script has been designed for use with GCC and G++. -- Peter Dyballa wrote (unquoted): > > leads to PTS_lstat being #define'd as lstat -- while stat would be correct. > > Why do you think that stat would be correct? Because /usr/include/sys/stat.h contains this: __BEGIN_DECLS int chmod __P((const char *, mode_t)); int fstat __P((int, struct stat *)); int mkdir __P((const char *, mode_t)); int mkfifo __P((const char *, mode_t)); int stat __P((const char *, struct stat *)); mode_t umask __P((mode_t)); #ifndef _POSIX_SOURCE int chflags __P((const char *, u_long)); int fchflags __P((int, u_long)); int fchmod __P((int, mode_t)); int lstat __P((const char *, struct stat *)); #endif __END_DECLS and gensio.cpp #define's _POSIX_SOURCE. > I think that that PTS_lstat is defined as it should, but configure should generate the poper condition for #if. Please submit a patch to configure. > This makes it compile in Mac OS X 10.3.9 (Panther): diff -Naur gensio.cpp~ gensio.cpp --- gensio.cpp~ Thu Mar 3 23:00:06 2005 +++ gensio.cpp Mon Oct 31 15:07:53 2005 @@ -16,7 +16,9 @@ #else #undef __STRICT_ANSI__ /* for __MINGW32__ */ #define _BSD_SOURCE 1 /* vsnprintf(); may be emulated with fixup_vsnprintf() */ +#ifndef __APPLE__ #define _POSIX_SOURCE 1 /* also popen() */ +#endif #define _POSIX_C_SOURCE 2 /* also popen() */ #define _XOPEN_SOURCE_EXTENDED 1 /* Digital UNIX lstat */ #ifndef _XPG4_2 --- I've integrated his #ifndef __APPLE__ patch. There should be a better way to handle this situation, though. -- How to compile with i386-uclibc-gcc on Debian Etch: by pts@fazekas.hu at Sun Apr 5 00:28:53 CEST 2009 $ i386-uclibc-gcc -v Invoked as i386-uclibc-gcc arg[ 0] = gcc arg[ 1] = -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) $ CXX='i386-uclibc-gcc -static' CC=i386-uclibc-gcc ./configure --enable-gif --enable-lzw # change LDXX=... to LDXX=$(CXX) in Makehelp $ make # (Unfortunately, the executable is large, 410KB) Revision history, changes ~~~~~~~~~~~~~~~~~~~~~~~~~ See in the file debian/changelog. Missing feature list ~~~~~~~~~~~~~~~~~~~~ !! make mkdist-noautoconf creates .tar.gz w/o leading directory part !! cannot read t.pnm "P4 1 1 1" doesn't end with \S !! ./sam2p ../pts.ppm t.gif -> sam2p: out_gif.cpp:260: void out_gif_write(GenBuffer::Writable&, Image::Indexed*): Assertion `bits_per_pixel<=8' failed. !! why so large PNG? sam2p examples/chessboard_ascii.pnm t.png !! easy seek back to 0 in in_*.cpp !! rxvt_bug.png -> useful Win98 .bmp ?? (expected) !! --invert option, for tif22pnm users complete turbo tutorial, MIFF input, _output_ full BMP output compressed, faster GIF input??, make install, .deb (debhelper?), .rpm, normal `image' instead of `colorimage' CUPS raster input and output, /Background option (-bg) to change transparent pixels -> bg color LZW and ZIP compressed for indexed etc. /* OK : PS and PDF input */ /* Imp: parse bts2.ttt just after generating (balance of [ << ... >> ]) /* Imp: command line option for /Transparent */ /* Imp: avoid 3 warnings in: ./sam2p examples/pts2.pbm t.ppm */ /* OK : margins for all PS, EPS and PDF (Sat Sep 7 16:17:58 CEST 2002 */ /* Imp: howto in pts_defl.h */ /* Imp: check for fixed bugs new zlib */ /* OK : built-in CCITTFaxEncode */ /* Imp: one-liner eliminate automatically invalid BMP SampleFormats with compression */ /* OK : more transferencodings for l1fa85g.tte */ /* Imp: eliminate long line (>120) from l1fa85g.tte */ /* Imp: one-liner -s gray|indexed|rgb|transparent */ /* OK : read bad.txt, and move it to section {Fixed bugs} */ /* OK : verify /Compression/Fax /K 1|2 with gs 5.50|7.04 */ /* Imp: in-memory dump when scanf_dict Error */ /* Imp: optimal, non-mem-hungry RLE compression filter (hardly possible...) */ /* Imp: possibility to write RGB (non-YCbCr) JPEG with /Compression/IJG etc. */ /* Imp: ability to load .gz and .zip compressed input files. Example: * .pbm.gz */ /* Imp: no return DONT_KNOW from *_work() */ /* Imp: Meta output */ /* Imp: PSL1 auto fallback to grayscale `image' in absence of `colorimage' */ /* Imp: full support for ZIP compression in PSL1 (similar to RLE) */ /* OK: TIFF output */ /* Imp: implement as a library (throw/catch exceptions, memory management, reentrance) */ /* Imp: check for proper inner dict usage in l1fa85g.tte */ /* Imp: add /Transparent2, /Transparent4, /Transparent8 for PDF */ /* Imp: add all #warning REQUIRES: */ /* OK : ccdep.pl, --enable-debug (Sat Jun 1 16:27:58 CEST 2002) */ /* Imp: show binary/ASCII in PDF and PS header comments */ /* Imp: `available loaders: (TIFF)' if tifftopnm not found (run-time) */ /* Imp: make LZW-unsupported not an Error, but a Warning */ /* Imp: create output profile */ /* OK: a real string hashing lib */ /* Imp: GIF reader is too slow (maybe LZW reading? ?). Change to xvgif.c?? */ /* OK : XPM reader (>=256 colors) is too slow */ /* OK : specify transparent color in the Job file */ /* Imp: run-time detect the absence of external progs */ /* Imp: make install */ /* Imp: make .deb, .rpm */ /* No : NDEBUG by default */ /* Imp: substitute char (1) for bool (8) on Digital UNIX */ /* OK : real replacement of vsnprintf() (Digital UNIX, Solaris) -- Tue Jun 11 15:20:22 CEST 2002 */ /* OK : close both filters in l23.tte, but _never_ close currentfile */ /* Imp: run-time choice from FlateEncode filter implemenetations etc. */ /* Imp: convert bilevel indexed image to grayscale more quickly */ /* OK : add quick and effective command line interface (one-liner mode) */ /* No : read external .tte files (runtime) instead of built-in .tth */ /* Imp: possibility to store several profiles in the same .jib file */ /* Imp: real, PDF-style dates into Created, Produced */ /* OK : real hashing in MiniPS::Dict */ /* Imp: enforce magic numbers for .job and .jib files */ /* OK : /TransferEncoding: * -> ascii if ... */ /* Imp: (early check, special handler) make everything work when wd==0 || ht==0; especially encoding filters */ /* Imp: better Job option for specifying and removing transparent color (better than /Transparent) */ /* Imp: log date(now) */ /* OK : DCT options in Output Rule */ /* OK : implement JAI */ /* Imp: support LargeBBox */ /* Imp: support Comment */ /* Imp: support PDF metadata: Title Subject Author Creator Producer */ /* Imp: support PDF dates: Created Produced */ /* Imp: support Comment */ /* Imp: add PAM file format support from NetPBM */ /* OK : verify ADSC EPSF-3.0 compatibility */ /* Imp: pre-transformation: making grayscale */ /* Imp: pre-transformation: down-bit-sampling */ /* Imp: pre-transformation: down-palette-sampling (``generate optimal palette'') */ /* Imp: tif22pnm warning - non-square pixels; to fix do a 'pnmscale -yscale nan'P6 2840 2138 255 */ ==6750== ==6750== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==6750== malloc/free: in use at exit: 3741 bytes in 102 blocks. ==6750== malloc/free: 2296 allocs, 2194 frees, 170451 bytes allocated. ==6750== For counts of detected errors, rerun with: -v ==6750== searching for pointers to 102 not-freed blocks. ==6750== checked 4227304 bytes. ==6750== ==6750== 12 bytes in 1 blocks are definitely lost in loss record 3 of 15 ==6750== at 0x400254FF: __builtin_new (vg_replace_malloc.c:172) ==6750== by 0x806ABC3: MiniPS::Parser::parse1(int, int) (minips.cpp:789) ==6750== by 0x806B378: MiniPS::Parser::parse1(int, int) (minips.cpp:856) ==6750== by 0x804DBD5: run_sam2p_engine(Files::FILEW &, Files::FILEW &, char const *const *, bool) (sam2p_main.cpp:923) ==6750== ==6750== ==6750== 808 bytes in 81 blocks are possibly lost in loss record 14 of 15 ==6750== at 0x400255E9: __builtin_vec_new (vg_replace_malloc.c:197) ==6750== by 0x8060C94: Mapping::DoubleHash::set(char const *, unsigned int, char const *) (mapping.cpp:43) ==6750== by 0x806A18B: MiniPS::Dict::put(char const *, unsigned int, int) (minips.cpp:461) ==6750== by 0x8069FF1: MiniPS::Dict::put(char const *, int) (minips.cpp:431) ==6750== ==6750== LEAK SUMMARY: ==6750== definitely lost: 12 bytes in 1 blocks. ==6750== possibly lost: 808 bytes in 81 blocks. ==6750== still reachable: 2921 bytes in 20 blocks. ==6750== suppressed: 0 bytes in 0 blocks. Known bugs ~~~~~~~~~~ (reported by Stefan Fritsch) > I got a bug report [1] about sam2p 0.44-10 not including a length > after the %%BeginData: line. As I understand it, the length is not > optional (see [2] p.44 (and gsview output?)). Sam2p 0.44-11 adds a > ";" after to this line. What does this ";" do? Is this supposed to be > conforming to the postscript standard? If not, are you planning to > write a real fix? > > [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=315046 > [2] http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf Fixing it would require a major rewrite. However, I don't have free time for that right now. If you really care about standards, remove the %%BeginData...%%EndData pair from the PostScript file or remove it altogether from the sam2p sources. The `;' is there so GSView won't complain. !! compiling on Debian SID with uclibc-toolchain i386-uclibc-linux-g++, the statically linked sam2p executable becomes quite biiiig: 668268 bytes. for configure: export CXX='i386-uclibc-linux-gcc -x c++ -static' Also, Makehelp has to be modified after running configure: LDXX=i386-uclibc-linux-g++ -static !! .eps import bad shift of BBX (LLX,LLY) with never Ghostscript Fixed bugs ~~~~~~~~~~ (this section was formerly bad.txt) ./sam2p -j examples/ptsbanner2.jpg test.pdf discover at Sun Sep 22 14:38:39 CEST 2002 BUGFIX at Sun Sep 22 15:03:33 CEST 2002 ./sam2p -1 -s:rgb1 -c:none examples/pts2.pbm test.eps discover at Sun Sep 22 14:29:59 CEST 2002 BUGFIX (add -s:...:stopq) at Sun Sep 22 16:20:41 CEST 2002 (behaviour correct, specifying -s:rgb1:stop gives more error messages) ./sam2p -c:fax:2 examples/shot.gif y.pdf BUGFIX /EndOfLine true is forced old gs: /ioerror in --%image_file_continue-- old acroread: `read less image data' (PDFB1.0: `expected EI') ./sam2p -c:fax:1 examples/shot.gif y.pdf BUGFIX /EndOfLine true is forced gs: OK old acroread: `read less image data' (PDFB1.0: `problem 115') ./sam2p -c:fax:0 examples/shot.gif y.pdf gs, acroread: OK ./sam2p -c:fax:-1 examples/shot.gif y.pdf gs, acroread: OK ./sam2p -c:fax examples/pts2.pbm y.tiff BUGFIX black-white inversion ./sam2p -c:fax examples/shot.gif y.tiff BUGFIX black-white inversion ./sam2p -j -c jpeg examples/pts2.pbm y.tiff seems to be OK now ./sam2p -j -c jpeg examples/pts2.pbm y.tiff seems to be OK now ./sam2p -j -c fax examples/ptsbanner.gif y.eps BUGFIX guard against applying /Compression/Fax to non-1-bit data ./sam2p -j -c fax -s:Indexed8 examples/ptsbanner.gif y.eps OK, no guard ./sam2p -j -c fax -c none examples/ptsbanner.gif y.eps OK, no guard ./sam2p -j -c fax examples/ptsbanner.gif y.tiff BUGFIX forbidden applying /Compression/Fax to non-1-bit data ./sam2p -c fax csanyi_torok_old.png csanyi_torok.eps ./sam2p -c fax examples/ptsbanner.gif csanyi_torok.eps error: Impossible combination OK, the user should specify `-s Indexed8' for unexpected use of `-c fax' __END__ sam2p-0.49.2/appliers.cpp0000644000175100017510000027142212212351433013357 0ustar ptspts/* * appliers.cpp -- specific OutputRule implementations * by pts@fazekas.hu at Sat Mar 16 14:45:02 CET 2002 * Blanca JAI additions at Tue May 21 13:18:26 CEST 2002 * TIFF output at Tue Jun 4 19:50:45 CEST 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "rule.hpp" #include "error.hpp" #include "encoder.hpp" #include "in_jai.hpp" #include "crc32.h" /* crc32() used by out_png_work() */ #include /** Appends 4 bytes in MSB first (network) byte order */ static inline void mf32(char *&p, slen_t u32) { p[0]=(u32>>24)&255; p[1]=(u32>>16)&255; p[2]=(u32>> 8)&255; p[3]=(u32 )&255; p+=4; } /** Appends 4 bytes in LSB first (PC) byte order */ static inline void lf32(char *&p, slen_t u32) { p[0]=(u32 )&255; p[1]=(u32>> 8)&255; p[2]=(u32>>16)&255; p[3]=(u32>>24)&255; p+=4; } /** Appends 2 bytes in LSB first (PC) byte order */ static inline void lf16(char *&p, unsigned u16) { p[0]=(u16 )&255; p[1]=(u16>> 8)&255; p+=2; } /* --- at Sat Mar 23 15:42:17 CET 2002, removed obsolete * PostScript Level2 FlateEncode or LZWEncode filter, predictors supported * written at Mar 16 14:48:27 CET 2002 */ /* --- Sun Mar 17 15:43:20 CET 2002 */ #if 0 /* l1fa85g.tte was a special .tte that is not built in to bts.ttt, but I've * integrated it into bts2.ttt at Sun Sep 22 00:48:21 CEST 2002. I've also * integrated _l1fa85g_ to _l1c_ that day. */ static char *l1fa85g_tte= #include "l1fa85g.tth" /** PostScript Level1 FlateEncode, A85, without Predictor */ Rule::Applier::cons_t out_l1fa85g_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (!cache->isPS() || cache->Compression!=Rule::Cache::CO_ZIP || cache->hasPredictor() || !cache->isGray() || cache->TransferEncoding!=cache->TE_A85 || (!cache->WarningOK && !cache->isPSL3()) ) return Rule::Applier::DONT_KNOW; return Rule::Applier::OK; } Rule::Applier::cons_t out_l1fa85g_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { /* by pts@fazekas.hu at Sun Mar 17 15:52:48 CET 2002 */ // Imp: two other TransferEncodings [no more, since #if 0] if (out_l1fa85g_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; if (!or_->cache.isPSL3()) Error::sev(Error::WARNING_DEFER) << "l1fa85g: /ZIP without /PSL3 will be slow" << (Error*)0; or_->doSampleFormat(sf); PSEncoder *bp=PSEncoder::newASCII85Encode(out, or_->cacheHints.TransferCPL); PSEncoder *cp=PSEncoder::newFlateEncode(*bp, or_->cacheHints.Effort); Rule::writeTTE(out, out, *cp, l1fa85g_tte, or_, sf, Rule::writeData); delete bp; delete cp; return Rule::Applier::OK; } Rule::Applier out_l1fa85g_applier = { "l1fa85g", out_l1fa85g_check_rule, out_l1fa85g_work, 0 }; #endif /* l2jbin --- Sun Mar 17 21:45:22 CET 2002 * p0jbin (integrated to p0jbin) --- Mon Apr 15 23:29:13 CEST 2002 */ //static char *l2jbin_tte= //#include "l2jbin.tth" /** PostScript Level2 DCTEncode (Baseline JPEG), Binary */ Rule::Applier::cons_t out_l2jbin_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if ((!cache->isPS() && !cache->isPDF()) || cache->Compression!=Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; /* Dat: not unrequired anymore: cache->TransferEncoding!=cache->TE_Binary */ bool badp=false; if (cache->isPS() && !cache->isPSL2()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/PSL* /Compression/JAI requires /PSL2+" << (Error*)0; badp=true; } if (cache->SampleFormat!=Image::SF_Asis) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/PSL*|PDF* /Compression/JAI requires /SampleFormat/Asis" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/PSL*|PDF* /Compression/JAI requires /Predictor 1" << (Error*)0; badp=true; } return (Rule::Applier::cons_t)(badp ? 0+Rule::Applier::BAD : 0+Rule::Applier::OK); /* ^^^ 0+: pacify g++-3.1 */ } Rule::Applier::cons_t out_l2jbin_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { char const*strings[]={ (char const*)NULLP/*LanguageLevel, PDF-1.`0'*/, ""/*colorSpace*/ }; //, " F closefile T closefile"/*closes*/ }; // Error::sev(Error::WARNING_DEFER) << "l2jbin: /ZIP without /PSL3 will be slow" << (Error*)0; if (out_l2jbin_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; assert(sf->getImg()->getBpc()==8); or_->doSampleFormat(sf); // PSEncoder *bp=PSEncoder::newASCII85Encode(out, or_->cacheHints.TransferCPL); Rule::Cache *cache=&or_->cache; Filter::VerbatimE outve(out); /* required since template /p0jbin is TTM */ GenBuffer::Writable *op=cache->isPDF() ? &outve : &out, *tp=op; strings[0]=const_cast(cache->isPDF() ? (char const*)"0" : (char const*)"2"); if (cache->TransferEncoding==cache->TE_A85) tp=PSEncoder::newASCII85Encode (*op, or_->cacheHints.TransferCPL); else if (cache->TransferEncoding==cache->TE_Hex) tp=PSEncoder::newASCIIHexEncode(*op, or_->cacheHints.TransferCPL); // else strings[2]=" F closefile"; Rule::writeTTT(*op, *tp, *tp, !cache->isPDF()?"l2jbin":cache->isPDFB()?"p0jbb":"p0jbin", or_, sf, Rule::writePalData, strings); if (tp!=op) delete tp; /* Dat: outve is deleted by C++ scope */ // if (tp!=op) delete tp; /* BUGFIX at Thu Jan 20 15:04:47 CET 2005 */ return Rule::Applier::OK; } Rule::Applier out_l2jbin_applier = { "PSL2+PDF-JAI", out_l2jbin_check_rule, out_l2jbin_work, 0 }; /* --- */ #if 0 /* integrated to _l2jbin_ at Sun Sep 22 14:29:13 CEST 2002 */ //static char *p0jbin_ttm= //#include "p0jbin.tth" /** PostScript Level2 DCTEncode (Baseline JPEG), Binary */ Rule::Applier::cons_t out_p0jbin_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (!cache->isPDF() || cache->Compression!=Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; /* Dat: not unrequired anymore: cache->TransferEncoding!=cache->TE_Binary */ bool badp=false; if (cache->SampleFormat!=Image::SF_Asis) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/PDF* /Compression/JAI requires /SampleFormat/Asis" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/PDF* /Compression/JAI requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; return Rule::Applier::OK; } Rule::Applier::cons_t out_p0jbin_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { char *strings[]={ "0"/*PDF-1.`0'*/, ""/*colorSpace*/ }; // " F closefile"/*closes*/ }; if (out_p0jbin_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; assert(sf->getImg()->getBpc()==8); or_->doSampleFormat(sf); Rule::Cache *cache=&or_->cache; Filter::VerbatimE outve(out); /* required since template /p0jbin is TTM */ GenBuffer::Writable *tp=&outve; if (cache->TransferEncoding==cache->TE_A85) tp=PSEncoder::newASCII85Encode (outve, or_->cacheHints.TransferCPL); else if (cache->TransferEncoding==cache->TE_Hex) tp=PSEncoder::newASCIIHexEncode(outve, or_->cacheHints.TransferCPL); else strings[2]=""; #if 0 /* old */ MiniPS::VALUE ttm; { Filter::FlatR flatD(p0jbin_ttm); MiniPS::Parser p(&flatD); ttm=p.parse1(); if (p.parse1(p.EOF_ALLOWED)!=MiniPS::Qundef || MiniPS::getType(ttm)!=MiniPS::T_ARRAY) Error::sev(Error::EERROR) << "TTM: the TTM file should contain a single array" << (Error*)0; /* ^^^ Dat: the result of the second p.parse1() doesn't get delete0(...)d */ } Filter::VerbatimE outve(out); Rule::writeTTM(outve, outve, outve, MiniPS::RARRAY(ttm), or_, sf, Rule::writePalData, strings); MiniPS::delete0(ttm); #else /* new */ Rule::writeTTT(outve, *tp, *tp, cache->isPDFB()?"p0jbb":"p0jbin", or_, sf, Rule::writePalData, strings); #endif if (tp!=&outve)delete tp; return Rule::Applier::OK; } Rule::Applier out_p0jbin_applier = { "PDF-JAI", out_p0jbin_check_rule, out_p0jbin_work, 0 }; #endif /* --- Fri Mar 22 11:52:53 CET 2002 */ /* PDF added at Sat Apr 20 20:07:34 CEST 2002 */ /* Integrated l23ind1 at Sat Apr 20 20:24:21 CEST 2002 */ //static char *l23_tte= //#include "l23.tth" /** PostScript Level2 and PDF generic non-transparent */ Rule::Applier::cons_t out_l23_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; unsigned char sf=cache->SampleFormat; if (cache->hasPredictor() && cache->Compression!=Rule::Cache::CO_ZIP && cache->Compression!=Rule::Cache::CO_LZW) { Error::sev(Error::WARNING_DEFER) << "check_rule: real /Predictor requires /ZIP or /LZW" << (Error*)0; return Rule::Applier::BAD; } // assert(cache->isPSL2() && (sf==Image::SF_Transparent2 || sf==Image::SF_Transparent4 || sf==Image::SF_Transparent8)); if ((!cache->isPSL2() && !cache->isPDF()) || (sf!=Image::SF_Gray1 && sf!=Image::SF_Gray2 && sf!=Image::SF_Gray4 && sf!=Image::SF_Gray8 && sf!=Image::SF_Indexed1 && sf!=Image::SF_Indexed2 && sf!=Image::SF_Indexed4 && sf!=Image::SF_Indexed8 && sf!=Image::SF_Rgb1 && sf!=Image::SF_Rgb2 && sf!=Image::SF_Rgb4 && sf!=Image::SF_Rgb8 && sf!=Image::SF_Transparent2 && sf!=Image::SF_Transparent4 && sf!=Image::SF_Transparent8 && sf!=Image::SF_Mask) || cache->TransferEncoding==cache->TE_ASCII || !cache->isZIPOK() ) return Rule::Applier::DONT_KNOW; #if !HAVE_LZW if (cache->Compression==Rule::Cache::CO_LZW) return Rule::Applier::DONT_KNOW; #endif // if (cache->isDCTE() && !cache->isRGB() && !cache->isGray()) { bool badp=false; if (cache->isDCTE() && cache->SampleFormat!=Image::SF_Rgb8 && cache->SampleFormat!=Image::SF_Gray8 && cache->SampleFormat!=Image::SF_Indexed8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /DCTEncode requires /Rgb8 or /Gray8 (or /Indexed8)" << (Error*)0; badp=true; } if (sf==Image::SF_Transparent2 || sf==Image::SF_Transparent4 || sf==Image::SF_Transparent8) { if (cache->isPDF()) { Error::sev(Error::WARNING_DEFER) << "check_rule: unsupported /Transparent+ for /PDF*" << (Error*)0; badp=true; } else assert(cache->isPSL2()); } return (Rule::Applier::cons_t)(badp ? 0+Rule::Applier::BAD : 0+Rule::Applier::OK); } Rule::Applier::cons_t out_l23_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { Rule::stream_writer_t writeXData=Rule::writePalData; char LanguageLevel[2]="2", closes[30]; SimBuffer::B colorSpace; char const*strings[]={ LanguageLevel, (char*)NULLP /*colorSpace*/, closes }; Rule::Cache *cache=&or_->cache; // assert(0); if (out_l23_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf, true); if (cache->Compression==Rule::Cache::CO_ZIP) { if (!cache->isPDF()) LanguageLevel[0]='3'; } else if (cache->isPDF()) LanguageLevel[0]='0'; if (cache->isIndexed() || cache->isTransparentM()) { unsigned ncols=PTS_dynamic_cast(Image::Indexed*,sf->getImg())->getNcols(); colorSpace << "[/Indexed/DeviceRGB " << ncols-1; if (ncols==0) { /* Avoid writing zero bytes to the filters */ /* Imp: verify this in Acrobat Reader */ colorSpace << "()]"; } else if (!cache->isPDF()) { /* Insert an in-line hexdump. No better way :-( */ /*sprintf(colorSpace, "[/Indexed/DeviceRGB %u T %u string readstring pop]", ncols-1, ncols*3); */ colorSpace << " T " << ncols*3 << " string readstring pop]"; } else { /* Insert an in-line hexdump. No shorter way for PDF */ #if 0 colorSpace="/DeviceGray "; #else /* SUXX: gs5.50 & PDF & /Indexed doesn't work */ colorSpace << "\n<"; GenBuffer::Writable *hp=PSEncoder::newASCIIHexEncode(colorSpace, or_->cacheHints.TransferCPL); hp->vi_write(sf->getImg()->getHeadp(), ncols*3); hp->vi_write(0,0); colorSpace << ']'; /* Dat: '>' is appended by ASCIIHexEncode */ #endif writeXData=Rule::writeData; /* The palette has already been written. */ } } else if (cache->isGray()) colorSpace="/DeviceGray "; else { assert(cache->isRGB()); colorSpace="/DeviceRGB "; } if (cache->SampleFormat==Image::SF_Mask || cache->SampleFormat==Image::SF_Indexed1) writeXData=Rule::writeData; GenBuffer::Writable *vp=&out; if (cache->isPDF()) vp=new Filter::VerbatimE(out); /* required since template /p02* is TTM */ GenBuffer::Writable *tp=vp; if (cache->TransferEncoding==cache->TE_A85) tp=PSEncoder::newASCII85Encode (*vp, or_->cacheHints.TransferCPL); else if (cache->TransferEncoding==cache->TE_Hex) tp=PSEncoder::newASCIIHexEncode(*vp, or_->cacheHints.TransferCPL); GenBuffer::Writable *cp=tp; switch (cache->Compression) { case Rule::Cache::CO_None: break; case Rule::Cache::CO_ZIP: cp=PSEncoder::newFlateEncode(*tp, or_->cacheHints.Effort); break; case Rule::Cache::CO_LZW: cp=PSEncoder::newLZWEncode(*tp); break; case Rule::Cache::CO_RLE: cp=PSEncoder::newRunLengthEncode(*tp, or_->cacheHints.RecordSize); break; case Rule::Cache::CO_Fax: cp=PSEncoder::newCCITTFaxEncode(*tp, or_->cacheHints.K, or_->cacheHints.EncoderBPL, /*EndOfLine:*/ or_->cacheHints.K>0); break; /* ^^^ getBpp() BUGFIX at Wed Jul 3 20:00:30 CEST 2002 */ /* ^^^ EndOfLine BUGFIX at Wed Jul 3 21:12:54 CEST 2002 * With EndOfLine==false, `sam2p -c:fax:1', acroread triggers the bug. * With EndOfLine==false, `sam2p -c:fax:2', acroread and gs trigger the bug. */ case Rule::Cache::CO_IJG: cp=PSEncoder::newDCTIJGEncode(*tp, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.Quality); break; case Rule::Cache::CO_DCT: { SimBuffer::B other_parameters; or_->cacheHints.DCT->dump(other_parameters, 0, false); cp=PSEncoder::newDCTEncode(*tp, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.ColorTransform, other_parameters); break; } default: assert(0); } GenBuffer::Writable *pp=cp; if (cache->hasPredictor()) pp=PSEncoder::newPredictor(*cp, cache->Predictor, or_->cacheHints.PredictorBPC, or_->cacheHints.PredictorColumns, or_->cacheHints.PredictorColors); #if 0 /* Sun Sep 22 20:40:51 CEST 2002 */ if (cp!=tp) strcpy(closes," F closefile"); else closes[0]='\0'; if (tp!=vp) strcpy(closes+strlen(closes)," T closefile"); #endif strings[1]=colorSpace.term0()(); Rule::writeTTT(*vp, *tp, *pp, !cache->isPDF() ? ( cache->SampleFormat==Image::SF_Indexed1 ? "l23ind1" : cache->SampleFormat==Image::SF_Mask ? "l23mask" : cache->isTransparentM() ? "l23tran2" : "l23" ) : cache->isPDFB() ? ( cache->SampleFormat==Image::SF_Indexed1 ? "p02ind1bb" : cache->SampleFormat==Image::SF_Mask ? "p02maskbb" : "p02bb" ) : ( cache->SampleFormat==Image::SF_Indexed1 ? "p02ind1" : cache->SampleFormat==Image::SF_Mask ? "p02mask" : "p02" ), or_, sf, writeXData, strings); if (pp!=cp) delete pp; if (cp!=tp) delete cp; if (tp!=vp) delete tp; if (vp!=&out)delete vp; return Rule::Applier::OK; } Rule::Applier out_l23_applier = { "PSL23+PDF", out_l23_check_rule, out_l23_work, 0 }; /* --- Fri Mar 22 17:22:40 CET 2002 -- Sat Jun 15 16:03:06 CEST 2002 */ /* integrated l1tr at Sat Jun 15 16:03:03 CEST 2002 */ /* added /Bbox at Sat Jun 15 16:03:31 CEST 2002 */ //static char *l1tr_tte= //#include "l1tr.tth" /** PostScript Level1 or PDF Fully transparent image */ Rule::Applier::cons_t out_l1tr_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (!(cache->isPS() || cache->isPDF()) || (cache->SampleFormat!=Image::SF_Transparent && cache->SampleFormat!=Image::SF_Bbox && cache->SampleFormat!=Image::SF_Opaque) ) return Rule::Applier::DONT_KNOW; return Rule::Applier::OK; } Rule::Applier::cons_t out_l1tr_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { char t[]="...."; if (out_l1tr_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); Rule::Cache *cache=&or_->cache; Filter::VerbatimE outve(out); /* required since template /p0* is TTM */ if (cache->isPS()) { t[0]='l'; t[1]='1'; } else { t[0]='p'; t[1]='0'; } switch (cache->SampleFormat) { case Image::SF_Transparent: t[2]='t'; t[3]='r'; break; case Image::SF_Opaque: t[2]='o'; t[3]='p'; break; case Image::SF_Bbox: t[2]='b'; t[3]='b'; break; default: assert(0); } Rule::writeTTT(outve, outve, outve, t, or_, sf, 0/*NULLP*/); return Rule::Applier::OK; } Rule::Applier out_l1tr_applier = { "P-TrOpBb", out_l1tr_check_rule, out_l1tr_work, 0 }; /* --- */ /* --- l23mask Fri Mar 22 18:11:12 CET 2002 * --- l23ind1 Fri Mar 22 18:11:12 CET 2002 * removed (integrated to l23) at Sat Apr 20 20:25:57 CEST 2002 */ /* --- l1mask Fri Mar 22 18:33:01 CET 2002 * --- l1mashex Sun Apr 14 15:25:25 CEST 2002 * --- l1in1 Fri Mar 22 18:33:37 CET 2002 * --- l1in1hex Fri Mar 22 18:33:37 CET 2002 * removed (integrated to l1c) at Sat Apr 20 20:25:57 CEST 2002 * --- lcr Sat Jun 1 17:09:57 CEST 2002 * removed (integrated to l1c) at Sun Jun 2 16:48:31 CEST 2002 * --- l1gbh * removed (integrated to l1c) at Sun Jun 2 16:48:31 CEST 2002 * --- l1fa85g.tte: PostScript Level1 FlateEncode, A85, without Predictor * removed (integrated to l1c) at Sun Sep 22 00:48:21 CEST 2002 */ /* --- Sun Jun 2 16:48:44 CEST 2002 */ //static char *l1mask_tte= //#include "l1mask.tth" static void gen_tkey(char *tkey, GenBuffer::Writable& out, GenBuffer::Writable*&tp, GenBuffer::Writable*& cp, Rule::OutputRule*or_) { Rule::Cache *cache=&or_->cache; tp=&out; if (cache->TransferEncoding==cache->TE_A85) { tkey[3]='8'; tp=PSEncoder::newASCII85Encode (out, or_->cacheHints.TransferCPL); } else if (cache->TransferEncoding==cache->TE_Hex) { tkey[3]='h'; tp=PSEncoder::newASCIIHexEncode(out, or_->cacheHints.TransferCPL); } else tkey[3]='b'; cp=tp; if (cache->Compression==Rule::Cache::CO_RLE) { tkey[4]='r'; cp=PSEncoder::newRunLengthEncode(*tp, or_->cacheHints.RecordSize); } else if (cache->Compression==Rule::Cache::CO_ZIP) { tkey[4]='z'; cp=PSEncoder::newFlateEncode(*tp, or_->cacheHints.Effort); } else if (cache->Compression==Rule::Cache::CO_LZW) { tkey[4]='l'; cp=PSEncoder::newLZWEncode(*tp); } else tkey[4]='n'; /* vvv removed 'm' and '1' at Sun Sep 22 17:53:08 CEST 2002 */ tkey[2]=// cache->SampleFormat==Image::SF_Mask ? 'm' : // cache->SampleFormat==Image::SF_Indexed1 ? '1' : cache->SampleFormat==Image::SF_Indexed2 ? '2' : cache->SampleFormat==Image::SF_Indexed4 ? '4' : cache->SampleFormat==Image::SF_Indexed8 ? '8' : cache->SampleFormat==Image::SF_Transparent2 ? 't' : cache->SampleFormat==Image::SF_Transparent4 ? 't' : cache->SampleFormat==Image::SF_Transparent8 ? 't' : 'g'; /* /Gray*, /Rgb*, /Mask, /Indexed1 */ } /** PostScript Level1 uncompressed binary or hex */ Rule::Applier::cons_t out_l1c_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if ((cache->FileFormat!=cache->FF_PSL1 && cache->FileFormat!=cache->FF_PSLC && cache->FileFormat!=cache->FF_PSL2) || (cache->FileFormat==cache->FF_PSL2 && cache->Compression!=Rule::Cache::CO_ZIP) || (cache->TransferEncoding!=cache->TE_Binary && cache->TransferEncoding!=cache->TE_Hex && cache->TransferEncoding!=cache->TE_A85) || (cache->Compression!=Rule::Cache::CO_None && cache->Compression!=Rule::Cache::CO_RLE && cache->Compression!=Rule::Cache::CO_ZIP && cache->Compression!=Rule::Cache::CO_LZW) || cache->hasPredictor() || !(cache->isTransparentM() || cache->isIndexed() || cache->isGray() || cache->isRGB()) ) return Rule::Applier::DONT_KNOW; bool badp=false; if (cache->FileFormat==cache->FF_PSL1 && cache->SampleFormat!=Image::SF_Indexed1 && cache->isIndexed()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /SampleFormat/Indexed+ doesn't work with /FileFormat/PSL1 (use /PSLC or /PSL2)" << (Error*)0; badp=true; } if (cache->FileFormat==cache->FF_PSL1 && cache->isRGB()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /SampleFormat/RGB* doesn't work with /FileFormat/PSL1 (use /PSLC or /PSL2)" << (Error*)0; badp=true; } char tkey[]="l1..."; /* /l1{2,4,8,t}{8,h}{r,z,l} */ GenBuffer::Writable *tp0,*cp0,*out=(GenBuffer::Writable*)NULLP; gen_tkey(tkey, *out, tp0, cp0, or_); /* fprintf(stderr,"tkey=%s\n", tkey); */ if (!badp && Rule::Templates->get(tkey, strlen(tkey))==MiniPS::Qundef) return Rule::Applier::DONT_KNOW; return (Rule::Applier::cons_t)(badp ? 0+Rule::Applier::BAD : 0+Rule::Applier::OK); /* ^^^ Dat: 0+: pacify gcc-3.1 */ } Rule::Applier::cons_t out_l1c_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { if (out_l1c_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; /* Dat: only these have been defined so far: grep '^/l1[248tg][8h][rzl]' bts2.ttt * /l1thr /l1g8r /l1ghr /l128r /l12hr /l148r /l14hr /l188r /l18hr /l1g8z /l1ghz /l1g8l /l1ghl */ or_->doSampleFormat(sf, true); /* Dat: `true': because of /Transparent+ */ char tkey[]="l1..."; /* /l1{2,4,8,t}{8,h}{r,z,l} */ GenBuffer::Writable *tp, *cp; gen_tkey(tkey, out, tp, cp, or_); // fprintf(stderr, "tkey=(%s)\n", tkey); Rule::writeTTT(out, *tp, *cp, tkey, or_, sf, tkey[2]=='2' || tkey[2]=='4' || tkey[2]=='8' || tkey[2]=='t' ? Rule::writePalData : Rule::writeData ); // Rule::writeTTT(out, *tp, *cp, tkey, or_, sf, Rule::writePalData); if (cp!=tp) delete cp; if (tp!=&out)delete tp; return Rule::Applier::OK; } Rule::Applier out_l1c_applier = { "PSL1C", out_l1c_check_rule, out_l1c_work, 0 }; /* lcrbin (lcrb) --- Sun Apr 14 16:50:14 CEST 2002 * lcrhex (lcr8, lcrh) --- Sun Apr 14 16:50:22 CEST 2002 * removed (integrated to _l1c_) at Sat Jun 1 17:09:52 CEST 2002 */ #if 0 /* --- Sat Jun 1 17:09:57 CEST 2002 */ //static char *lcrbin_tte= //#include "lcrbin.tth" /** PostScript Level1+C uncompressed RGB image */ Rule::Applier::cons_t out_lcr_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (!cache->isPS() || cache->FileFormat==cache->FF_PSL1 || (cache->TransferEncoding!=cache->TE_Binary && cache->TransferEncoding!=cache->TE_Hex && cache->TransferEncoding!=cache->TE_A85) || cache->Compression!=Rule::Cache::CO_None || cache->hasPredictor() || !cache->isRGB() ) return Rule::Applier::DONT_KNOW; return Rule::Applier::OK; } Rule::Applier::cons_t out_lcr_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { Rule::Cache *cache=&or_->cache; if (out_lcr_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); char tkey[]="lcr."; GenBuffer::Writable *tp=&out; if (cache->TransferEncoding==cache->TE_A85) { tkey[3]='8'; tp=PSEncoder::newASCII85Encode (out, or_->cacheHints.TransferCPL); } else if (cache->TransferEncoding==cache->TE_Hex) { tkey[3]='h'; tp=PSEncoder::newASCIIHexEncode(out, or_->cacheHints.TransferCPL); } else tkey[3]='b'; Rule::writeTTT(out, *tp, *tp, tkey, or_, sf, Rule::writeData); if (tp!=&out)delete tp; return Rule::Applier::OK; } Rule::Applier out_lcr_applier = { "PSLC-RGB", out_lcr_check_rule, out_lcr_work, 0 }; #endif /* --- Sat Mar 23 12:37:04 CET 2002; Tue Jul 2 10:23:44 CEST 2002 */ Rule::Applier::cons_t out_gif89a_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; bool badp=false; if (cache->FileFormat!=cache->FF_GIF89a ) return Rule::Applier::DONT_KNOW; if (!cache->isIndexed() && !cache->isTransparentM()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /GIF89a must be /Indexed*, /Mask or /Transparent+" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /GIF89a requires /Binary" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None && cache->Compression!=Rule::Cache::CO_LZW) { Error::sev(Error::WARNING_DEFER) << "check_rule: /GIF89a requires /LZW" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /GIF89a requires /Predictor 1" << (Error*)0; badp=true; } #if !USE_OUT_GIF Error::sev(Error::WARNING_DEFER) << "check_rule: please `configure --enable-gif' for /GIF89a" << (Error*)0; badp=true; #endif if (badp) return Rule::Applier::BAD; or_->cache.WarningOK=true; return Rule::Applier::OK; } #if USE_OUT_GIF #if OBJDEP # warning REQUIRES: out_gif.o #endif extern void out_gif_write(GenBuffer::Writable& out, Image::Indexed *img); /* out_gif.cpp */ Rule::Applier::cons_t out_gif89a_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { if (out_gif89a_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->cache.SampleFormat=(Image::sf_t)(or_->cache.isIndexed()? 0+Image::SF_Indexed8: 0+Image::SF_Transparent8); /* ^^^ Dat: 0+: pacify gcc-3.1; (Image::sf_t): pacify VC6.0 */ or_->doSampleFormat(sf); out_gif_write(out, PTS_dynamic_cast(Image::Indexed*,sf->getImg())); return Rule::Applier::OK; } #else /*# define out_gif89a_check_rule (Rule::Applier::check_rule_t)NULLP*/ # define out_gif89a_work (Rule::Applier::work_t)0 #endif Rule::Applier out_gif89a_applier = { #if HAVE_LZW "GIF89a+LZW" #else "GIF89a" #endif , out_gif89a_check_rule, out_gif89a_work, 0 }; /* --- Tue Jun 4 19:51:03 CEST 2002 */ Rule::Applier::cons_t out_xpm_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; bool badp=false; if (cache->FileFormat!=cache->FF_XPM ) return Rule::Applier::DONT_KNOW; if (!cache->isIndexed() && !cache->isTransparentM()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XPM must be /Indexed*, /Mask or /Transparent+" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_ASCII && cache->TransferEncoding!=cache->TE_Binary) { /* ^^^ && BUGFIX at Thu Jul 11 21:57:09 CEST 2002 */ Error::sev(Error::WARNING_DEFER) << "check_rule: /XPM requires /TransferEncoding/ASCII" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XPM requires /Compression/None" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XPM requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; or_->cache.WarningOK=true; return Rule::Applier::OK; } Rule::Applier::cons_t out_xpm_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { if (out_xpm_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->cache.SampleFormat=(Image::sf_t)(or_->cache.isIndexed()? 0+Image::SF_Indexed8: 0+Image::SF_Transparent8); /* ^^^ force 8-bit; may trigger warnings... */ /* ^^^ Dat: 0+: pacify gcc-3.1 */ or_->doSampleFormat(sf); Image::Indexed *iimg=PTS_dynamic_cast(Image::Indexed*,sf->getImg()); /* vvv 93 useful ASCII chars (+ '\0'), missing: " and \ ; plus a hextable */ static char const xpmc=93; static char const xpms[xpmc+1]="0123456789abcdef !#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`ghijklmnopqrstuvwxyz{|}~"; Image::Sampled::dimen_t wd=iimg->getWd(), htc=iimg->getHt(); bool pal2ch=iimg->getNcols()>xpmc; // pal2ch=true; out << "/* XPM */\nstatic char *sam2p_xpm[] = {\n" "/* columns rows colors chars-per-pixel */\n\"" << wd << ' ' << htc << ' ' << iimg->getNcols() << ' ' << (pal2ch?2:1) << "\",\n"; char const *p=iimg->getHeadp(), *pend=iimg->getRowbeg(), *phend; char coline3[]="\".. c #ABCDEF\",\n"; char cotran3[]="\".. c None s None \",\n"; assert((pend-p)%3==0); unsigned i=0; bool transp=false; if (iimg->getTransp()>=0) { pend-=3; assert((iimg->getTransp())*3+p==pend); transp=true; } if (pal2ch) { while (p!=pend) { coline3[ 1]=xpms[i>>2]; coline3[ 2]=xpms[i++&3]; coline3[ 7]=xpms[*(unsigned char const*)p>>4]; coline3[ 8]=xpms[*(unsigned char const*)p++&15]; coline3[ 9]=xpms[*(unsigned char const*)p>>4]; coline3[10]=xpms[*(unsigned char const*)p++&15]; coline3[11]=xpms[*(unsigned char const*)p>>4]; coline3[12]=xpms[*(unsigned char const*)p++&15]; out << coline3; } if (transp) { cotran3[ 1]=xpms[i>>2]; cotran3[ 2]=xpms[i++&3]; out << cotran3; p+=3; } pend=iimg->getRowbeg()+wd*htc; out << "/* Pixels */\n"; char *obuf=new char[4+2*wd], *op; obuf[0]='"'; obuf[2*wd+1]='"'; obuf[2*wd+2]=','; /* Dat: it's OK to have a comma in the last line */ obuf[2*wd+3]='\n'; while (htc--!=0) { phend=p+wd; op=obuf; while (p!=phend) { *++op=xpms[*p>>2]; *++op=xpms[*p++&3]; } out.vi_write(obuf, 2*wd+4); } } else { coline3[1]='"'; while (p!=pend) { coline3[ 2]=xpms[i++]; coline3[ 7]=xpms[*(unsigned char const*)p>>4]; coline3[ 8]=xpms[*(unsigned char const*)p++&15]; coline3[ 9]=xpms[*(unsigned char const*)p>>4]; coline3[10]=xpms[*(unsigned char const*)p++&15]; coline3[11]=xpms[*(unsigned char const*)p>>4]; coline3[12]=xpms[*(unsigned char const*)p++&15]; out << (coline3+1); } if (transp) { cotran3[1]='"'; cotran3[ 2]=xpms[i]; out << (cotran3+1); p+=3; } pend=iimg->getRowbeg()+wd*htc; out << "/* Pixels */\n"; char *obuf=new char[4+wd], *op; obuf[0]='"'; obuf[wd+1]='"'; obuf[wd+2]=','; /* Dat: it's OK to have a comma in the last line */ obuf[wd+3]='\n'; while (htc--!=0) { phend=p+wd; op=obuf; while (p!=phend) *++op=xpms[0U+*p++]; out.vi_write(obuf, wd+4); } } assert(p==pend); out << "};\n"; return Rule::Applier::OK; } Rule::Applier out_xpm_applier = { "XPM", out_xpm_check_rule, out_xpm_work, 0 }; /* --- Sat Mar 23 13:18:07 CET 2002 */ Rule::Applier::cons_t out_pnm_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_PNM ) return Rule::Applier::DONT_KNOW; bool badp=false; // if (cache->SampleFormat!=Image::SF_Rgb8 && cache->SampleFormat!=Image::SF_Gray8 && cache->SampleFormat!=Image::SF_Gray1) { if (!cache->isGray() && !cache->isRGB() && !cache->isIndexed() && !cache->isTransparentM()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNM must be /Rgb8, /Gray8 or /Gray1" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary && cache->TransferEncoding!=cache->TE_ASCII) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNM requires /Binary or /ASCII" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNM requires /Compression/None" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNM requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; or_->cache.WarningOK=true; return Rule::Applier::OK; } Rule::Applier::cons_t out_pnm_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { /*static*/ char head[]={ 'P', 0, '\n', '#', ' ', 'b', 'y', ' ' }; /*static*/ char tmp[72]; Image::sf_t sfo=or_->cache.SampleFormat; Image::Indexed *alphaChannel=(Image::Indexed*)NULLP; if (out_pnm_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; if (or_->cache.SampleFormat==Image::SF_Gray1 || or_->cache.SampleFormat==Image::SF_Gray8) { if (or_->cache.TransferEncoding==or_->cache.TE_ASCII) or_->cache.SampleFormat=Image::SF_Gray8; } else if (or_->cache.SampleFormat==Image::SF_Gray2 || or_->cache.SampleFormat==Image::SF_Gray4) { or_->cache.SampleFormat=Image::SF_Gray8; } else if (or_->cache.isRGB()) { or_->cache.SampleFormat=Image::SF_Rgb8; } else { assert(or_->cache.isIndexed() || or_->cache.isTransparentM()); if (or_->cache.isTransparentM()) { alphaChannel=PTS_dynamic_cast(Image::Indexed*,sf->getImg())->calcAlpha(); sf->clearTransp(); /* BUGFIX at Tue Sep 17 10:05:47 CEST 2002 */ } or_->cache.SampleFormat=(Image::sf_t)( !sf->canGrayy() ? 0+Image::SF_Rgb8 : sf->minRGBBpcc()==1 ? 0+Image::SF_Gray1 : 0+Image::SF_Gray8); /* ^^^ Dat: 0+: pacify gcc-3.1 */ } if (or_->cache.SampleFormat==Image::SF_Gray1 && or_->cache.TransferEncoding==or_->cache.TE_ASCII) or_->cache.SampleFormat=Image::SF_Gray8; or_->doSampleFormat(sf); sfo=or_->cache.SampleFormat; head[1]=(sfo==Image::SF_Rgb8 ? '3' : sfo==Image::SF_Gray8 ? '2' : '1') +(or_->cache.TransferEncoding==or_->cache.TE_Binary)*3; out.vi_write(head, sizeof(head)); out << Error::banner0; Image::Sampled *img=sf->getImg(); out << '\n' << img->getWd() << ' ' << img->getHt(); out << " 255\n"+(sfo==Image::SF_Gray1?4:0); /* ^^^ SF_Gray1 BUGFIX at Tue Jun 4 21:44:17 CEST 2002 */ register char *p=img->getRowbeg(), *t=(char*)NULLP; slen_t len=img->getRlen()*img->getHt(); // fprintf(stderr, "len=%u\n", len); register unsigned smallen, i; switch (head[1]) { case '1': /* PBM ASCII */ while (len>=70) { smallen=70; t=tmp; while (smallen--!=0) *t++=(*p++==0)?'1':'0'; /* ^^^ note the swapping of '0' and '1' above */ *t++='\n'; out.vi_write(tmp, 71); len-=70; } while (len--!=0) *t++=(*p++==0)?'0':'1'; /* Dat: xv requires a whitespace just before EOF */ *t++='\n'; out.vi_write(tmp, t-tmp); break; case '2': case '3': /* PGM ASCII, PPM ASCII */ while (len!=0) { if (len>17) { smallen=17; len-=17; } else { smallen=len; len=0; } t=tmp; while (smallen--!=0) { if ((i=*(unsigned char*)p++)<10) *t++=i+'0'; else if (i<100) { *t++=i/10+'0'; *t++=i%10+'0'; } else if (i<200) { *t++='1'; *t++=(i-100)/10+'0'; *t++=i%10+'0'; } else { *t++='2'; *t++=(i-200)/10+'0'; *t++=i%10+'0'; } *t++=' '; } /* Dat: xv requires a whitespace just before EOF */ t[-1]='\n'; out.vi_write(tmp, t-tmp/*-(len==0)*/); } break; case '4': /* PBM RAWBITS */ /* Invert the image */ while (len--!=0) *p++^=-1; p=img->getRowbeg(); len=img->getRlen()*img->getHt(); /* fall through */ default: /* PBM RAWBITS, PGM RAWBITS, PPM RAWBITS */ /* fwrite(p, 1, len, stdout); */ out.vi_write(p, len); } if (alphaChannel!=NULLP) { /* OK: don't always output rawbits PBM file */ assert(alphaChannel->getBpc()==1); assert(alphaChannel->getWd()==img->getWd()); assert(alphaChannel->getHt()==img->getHt()); /* write PBM RAWBITS subfile (alpha channel) */ if (or_->cache.TransferEncoding==or_->cache.TE_Binary) { out << "P4 " << img->getWd() << ' ' << img->getHt() << '\n'; out.vi_write(alphaChannel->getRowbeg(), alphaChannel->getRlen()*alphaChannel->getHt()); /* ^^^ BUGFIX at Tue Sep 17 10:18:28 CEST 2002 */ } else { out << "P1 " << img->getWd() << ' ' << img->getHt() << '\n'; alphaChannel->to8(); p=alphaChannel->getRowbeg(); len=alphaChannel->getRlen()*alphaChannel->getHt(); while (len>=70) { smallen=70; t=tmp; while (smallen--!=0) *t++=(*p++!=0)?'1':'0'; /* ^^^ note the non-swapping of '0' and '1' above */ *t++='\n'; out.vi_write(tmp, 71); len-=70; } while (len--!=0) *t++=(*p++!=0)?'0':'1'; /* Dat: xv requires a whitespace just before EOF */ *t++='\n'; out.vi_write(tmp, t-tmp); } delete alphaChannel; } return Rule::Applier::OK; } Rule::Applier out_pnm_applier = { "PNM", out_pnm_check_rule, out_pnm_work, 0 }; /* --- Sat Aug 10 22:18:33 CEST 2002 */ Rule::Applier::cons_t out_xwd_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_XWD ) return Rule::Applier::DONT_KNOW; bool badp=false; if (cache->SampleFormat!=Image::SF_Rgb8 && cache->SampleFormat!=Image::SF_Gray8 && cache->SampleFormat!=Image::SF_Indexed8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XWD must be /Rgb8, /Gray8 or /Indexed8" << (Error*)0; return Rule::Applier::BAD; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XWD requires /Binary" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XWD requires /Compression/None" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /XWD requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; return Rule::Applier::OK; } Rule::Applier::cons_t out_xwd_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { static const unsigned XWD_FILE_VERSION=7, ZPixmap=2, MSBFirst=1, DirectColor=5, PseudoColor=3, //GrayScale=1, StaticGray=0; Image::sf_t sfo=or_->cache.SampleFormat; if (out_xwd_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); sfo=or_->cache.SampleFormat; char head[101], *p=head; Image::Sampled *img=sf->getImg(); slen_t bits_per_pixel, bitmap_pad, bytes_per_line; unsigned ncolors; memset(head, '\0', 101); /*header_size*/ mf32(p,101); /*file_version*/ (p+=4)[-1]=XWD_FILE_VERSION; /*pixmap_format*/ (p+=4)[-1]=ZPixmap; /*pixmap_depth*/ (p+=4)[-1]=sfo==Image::SF_Rgb8 ? 24 : 8; /*pixmap_width */ mf32(p, img->getWd()); /*pixmap_height*/ mf32(p, img->getHt()); /*xoffset*/ p+=4; /*byte_order*/ (p+=4)[-1]=MSBFirst; /*bitmap_unit*/ (p+=4)[-1]=8; // sfo==Image::SF_Rgb8 ? 32 : 8; /*bitmap_bit_order*/ (p+=4)[-1]=MSBFirst; /*bitmap_pad*/ bitmap_pad=(p+=4)[-1]=8; // sfo==Image::SF_Rgb8 ? 32 : 8; /* ^^^ force no padding at all */ /*bits_per_pixel*/ bits_per_pixel=(p+=4)[-1]=sfo==Image::SF_Rgb8 ? 24 : 8; /*bytes_per_line*/ mf32(p, bytes_per_line=((bits_per_pixel*img->getWd()+bitmap_pad-1)&~(bitmap_pad-1))>>3); /*visual_class*/ (p+=4)[-1]=sfo==Image::SF_Rgb8 ? DirectColor : sfo==Image::SF_Indexed8 ? PseudoColor : StaticGray; /*red_mask */ (p+=4)[-3]=(char)(sfo==Image::SF_Rgb8 ? 255 : 0); /*green_mask*/ (p+=4)[-2]=(char)(sfo==Image::SF_Rgb8 ? 255 : 0); /*blue_mask */ (p+=4)[-1]=(char)(sfo==Image::SF_Rgb8 ? 255 : 0); /*bits_per_rgb*/ (p+=4)[-1]=sfo==Image::SF_Rgb8 ? 24 : 8; /*colormap_entries*/ (p+=4)[-2]=1; /*256*/ /*ncolors*/ mf32(p, ncolors=sfo==Image::SF_Rgb8 ? 0 : sfo==Image::SF_Indexed8 ? ((Image::Indexed*)img)->getNcols() : 256); /*window_width */ mf32(p, img->getWd()); /*window_height*/ mf32(p, img->getHt()); assert(p+13==head+101); /*window_x*/ /*0*/ /*window_y*/ /*0*/ /*window_bdrwidth*/ /*0*/ /*filename*/ /*""*/ out.vi_write(head, 101); if (sfo!=Image::SF_Rgb8) { char *pal=new char[ncolors*12], *pp=pal; unsigned pixel; if (sfo==Image::SF_Indexed8) { char const* q=img->getHeadp(); for (pixel=0;pixelgetRlen(); Image::Sampled::dimen_t htc=img->getHt(); char const* rp=img->getRowbeg(); unsigned scanline_pad=bytes_per_line-rlen; // assert(*rp=='\xff'); if (scanline_pad!=0) { assert(1<=scanline_pad && scanline_pad<=3); while (htc--!=0) { out.vi_write(rp, rlen); rp+=rlen; if (scanline_pad!=0) out.vi_write("\0\0", scanline_pad); } } else out.vi_write(rp, rlen*htc); return Rule::Applier::OK; } Rule::Applier out_xwd_applier = { "XWD", out_xwd_check_rule, out_xwd_work, 0 }; Rule::Applier out_x11_applier = { "X11", 0/*out_x11_check_rule*/, 0/*out_x11_work*/, 0 }; /* --- Sat Apr 20 11:49:56 CEST 2002 */ /** Baseline (lossy) JPEG */ Rule::Applier::cons_t out_jpeg_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_JPEG || cache->Compression==Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; bool badp=false; if (cache->SampleFormat!=Image::SF_Rgb8 && cache->SampleFormat!=Image::SF_Gray8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /DCTEncode requires /Rgb8 or /Gray8" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /JPEG requires /Binary" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None && cache->Compression!=Rule::Cache::CO_DCT && cache->Compression!=Rule::Cache::CO_IJG) { Error::sev(Error::WARNING_DEFER) << "check_rule: /JPEG requires /DCT or /IJG" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /JPEG requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; or_->cache.WarningOK=true; /* ?? */ return Rule::Applier::OK; } Rule::Applier::cons_t out_jpeg_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { Rule::Cache *cache=&or_->cache; // assert(0); if (out_jpeg_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); // GenBuffer::Writable *tp=&out; /* always binary */ GenBuffer::Writable *cp=&out; /* SUXX: cjpeg(1) won't create a color JPEG for a grayscale image */ if (cache->Compression==Rule::Cache::CO_DCT) { SimBuffer::B other_parameters; or_->cacheHints.DCT->dump(other_parameters, 0, false); cp=PSEncoder::newDCTEncode(out, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.ColorTransform, other_parameters); } else { assert(cache->Compression==Rule::Cache::CO_None || cache->Compression==Rule::Cache::CO_IJG); cp=PSEncoder::newDCTIJGEncode(out, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.Quality); } Rule::writePalData(out, *cp, sf); delete cp; return Rule::Applier::OK; } Rule::Applier out_jpeg_applier = { "JPEG", out_jpeg_check_rule, out_jpeg_work, 0 }; /* --- Wed Apr 17 13:32:46 CEST 2002 */ Rule::Applier::cons_t out_jpegjai_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_JPEG || cache->Compression!=Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; bool badp=false; if (cache->SampleFormat!=Image::SF_Asis) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/JPEG /Compression/JAI requires /SampleFormat/Asis" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/JPEG /Compression/JAI requires /TransferEncoding/Binary" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/JPEG /Compression/JAI requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; return Rule::Applier::OK; } Rule::Applier::cons_t out_jpegjai_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { /* This is the second simplest Applier I've ever written. */ if (out_jpegjai_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; Image::Sampled *img=sf->getImg(); // out.vi_write(img->getHeadp(), img->end_()-img->getHeadp()); /* ^^^ end_() BUGFIX by pts@fazekas.hu at Sun Jun 2 22:24:32 CEST 2002 */ /* ^^^ end_() contains 8 extra bytes */ out.vi_write(img->getHeadp(), img->getRowbeg()-img->getHeadp()); return Rule::Applier::OK; } Rule::Applier out_jpegjai_applier = { "JPEG-JAI", out_jpegjai_check_rule, out_jpegjai_work, 0 }; /* --- Sun Jun 2 22:25:16 CEST 2002 */ class TIFFPrinter { GenBuffer::Writable& out; /** true iff little endian == LSB first */ bool le; SimBuffer::B s, dir; public: TIFFPrinter(GenBuffer::Writable &out_, bool le_); inline SimBuffer::B& getS() { return s; } inline SimBuffer::B const& getDir() const { return dir; } void aSHORT(SimBuffer::B &s, unsigned count, unsigned short const*val); void aLONG (SimBuffer::B &s, unsigned count, slen_t const*val); void dirSHORT(unsigned short tag, slen_t count, unsigned short const*val); void dirLONG(unsigned short tag, slen_t count, slen_t const*val); void dirSL(unsigned short tag, slen_t val); void dirLONG(unsigned short tag, slen_t val); void dirRATIONAL(unsigned short tag, slen_t count, slen_t const*val); void dirUNDEFINED(unsigned short tag, slen_t count, char const*val); void dirUNDEFINED(unsigned short tag, slen_t count, char const*val, slen_t count2, char const*val2); void dirClose(); BEGIN_STATIC_ENUM1(unsigned short) EXTRASAMPLE_ASSOCALPHA=1, /* !associated alpha data */ EXTRASAMPLE_UNASSALPHA=2 /* !unassociated alpha data */ END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned short) COMPRESSION_NONE =1, /* dump mode */ COMPRESSION_CCITTRLE =2, /* CCITT modified Huffman RLE; unused in sam2p */ COMPRESSION_CCITTFAX3=3, /* CCITT Group 3 fax encoding */ COMPRESSION_CCITTFAX4=4, /* CCITT Group 4 fax encoding */ COMPRESSION_LZW =5, /* Lempel-Ziv & Welch */ COMPRESSION_OJPEG =6, /* !6.0 JPEG; obsolete, unused in sam2p */ COMPRESSION_JPEG =7, /* %JPEG DCT compression */ COMPRESSION_CCITTRLEW=32771,/* #1 w/ word alignment; unused in sam2p */ COMPRESSION_PACKBITS =32773,/* Macintosh RLE */ COMPRESSION_DEFLATE =32946 /* Deflate compression */ END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned short) PHOTOMETRIC_MINISBLACK=1, PHOTOMETRIC_RGB=2, PHOTOMETRIC_PALETTE=3, PHOTOMETRIC_MASK=4, PHOTOMETRIC_SEPARATED=5, /* possibly CMYK */ PHOTOMETRIC_YCBCR=6 END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned short) GROUP3OPT_2DENCODING=0x1, GROUP3OPT_UNCOMPRESSED=0x2, GROUP3OPT_FILLBITS=0x4, GROUP4OPT_UNCOMPRESSED=0x2 END_STATIC_ENUM() BEGIN_STATIC_ENUM1(unsigned short) ImageWidth=256, ImageLength=257, BitsPerSample=258, Compression=259, Photometric=262, FillOrder=266, StripOffsets=273, SamplesPerPixel=277, RowsPerStrip=278, StripByteCounts=279, XResolution=282, YResolution=283, PlanarConfig=284, Group3Options=292, Group4Options=293, ResolutionUnit=296, Predictor=317, ColorMap=320, InkSet=332, ExtraSamples=338, JPEGTables=347, YCbCrSubsampling=530, ReferenceBlackWhite=532 END_STATIC_ENUM() }; TIFFPrinter::TIFFPrinter(GenBuffer::Writable &out_, bool le_) :out(out_), le(le_) { /* Directory now at unknown offset (will be set by .dirClose()) */ s.vi_write(le_ ? "II*\0\0\0\0\0" : "MM\0*\0\0\0\0", 8); dir.vi_write("\0",2); /* initial number of directory entries */ } void TIFFPrinter::aSHORT(SimBuffer::B &s, unsigned count, unsigned short const*val) { if (le) while (count--!=0) { s << (char)(*val) << (char)(*val>>8); val++; } else while (count--!=0) { s << (char)(*val>>8) << (char)(*val); val++; } } void TIFFPrinter::aLONG (SimBuffer::B &s, unsigned count, slen_t const*val) { /* Imp: is vi_write(..., 4); faster ? */ if (le) while (count--!=0) { s << (char)(*val) << (char)(*val>>8) << (char)(*val>>16) << (char)(*val>>24); val++; } else while (count--!=0) { s << (char)(*val>>24) << (char)(*val>>16) << (char)(*val>>8) << (char)(*val); val++; } } void TIFFPrinter::dirSHORT(unsigned short const tag, slen_t const count, unsigned short const*val) { slen_t offs; aSHORT(dir, 1U, &tag); dir.vi_write("\0\3"+(le?1:0), 2); aLONG(dir, 1U, &count); switch (count) { case 0: dir.vi_write("\0\0\0", 4); break; case 1: aSHORT(dir, 1, val); dir.vi_write("\0", 2); break; case 2: aSHORT(dir, 2, val); break; default:offs=s.getLength(); aSHORT(s, count, val); aLONG(dir, 1, &offs); } } void TIFFPrinter::dirLONG(unsigned short const tag, slen_t const count, slen_t const*val) { slen_t offs; aSHORT(dir, 1U, &tag); dir.vi_write("\0\4"+(le?1:0), 2); aLONG(dir, 1U, &count); switch (count) { case 0: dir.vi_write("\0\0\0", 4); break; case 1: aLONG(dir, 1, val); break; default:offs=s.getLength(); aLONG(s, count, val); aLONG(dir, 1, &offs); } } void TIFFPrinter::dirRATIONAL(unsigned short tag, slen_t count, slen_t const*val) { slen_t offs; aSHORT(dir, 1U, &tag); dir.vi_write("\0\5"+(le?1:0), 2); aLONG(dir, 1U, &count); switch (count) { case 0: dir.vi_write("\0\0\0", 4); break; default:offs=s.getLength(); aLONG(s, count*2, val); aLONG(dir, 1, &offs); } } void TIFFPrinter::dirUNDEFINED(unsigned short tag, slen_t count, char const*val) { slen_t offs; aSHORT(dir, 1U, &tag); dir.vi_write("\0\7"+(le?1:0), 2); aLONG(dir, 1U, &count); if (count<=4) { dir.vi_write(val, count); if (count!=4) dir.vi_write("\0\0\0", 4-count); } else { offs=s.getLength(); s.vi_write(val, count); aLONG(dir, 1, &offs); } } void TIFFPrinter::dirUNDEFINED(unsigned short tag, slen_t count, char const*val, slen_t count2, char const*val2) { slen_t offs, countx=count+count2; aSHORT(dir, 1U, &tag); dir.vi_write("\0\7"+(le?1:0), 2); aLONG(dir, 1U, &countx); if (countx<=4) { dir.vi_write(val, count); dir.vi_write(val2, count2); if (countx!=4) dir.vi_write("\0\0\0", 4-countx); } else { offs=s.getLength(); s.vi_write(val, count); s.vi_write(val2, count2); aLONG(dir, 1, &offs); } } void TIFFPrinter::dirSL(unsigned short tag, slen_t val) { unsigned short sh; if (val<1<<16U) { sh=val; dirSHORT(tag, 1, &sh); } else dirLONG(tag, 1, &val); } void TIFFPrinter::dirLONG(unsigned short tag, slen_t val) { dirLONG(tag, 1, &val); } void TIFFPrinter::dirClose() { char *ss=s.begin_(); slen_t len=s.getLength(); if (le) { ss[4]=len; ss[5]=len>>8; ss[6]=len>>16; ss[7]=len>>24; } else { ss[4]=len>>24; ss[5]=len>>16; ss[6]=len>>8; ss[7]=len; } /* ^^^ dir offset: end of file */ out.vi_write(ss, len); assert(dir.getLength()%12==2); unsigned dirc=(dir.getLength()-2)/12; ss=dir.begin_(); if (le) { ss[0]=dirc; ss[1]=dirc>>8; } else { ss[0]=dirc>>8; ss[1]=dirc; } out.vi_write(dir(), dir.getLength()); out.vi_write("", 0); } /* tiffjai --- Sun Jun 2 22:25:16 CEST 2002 */ Rule::Applier::cons_t out_tiffjai_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_TIFF || cache->Compression!=Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; bool badp=false; if (cache->SampleFormat!=Image::SF_Asis) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF /Compression/JAI requires /SampleFormat/Asis" << (Error*)0; badp=true; } if (!cache->isBinSB()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF /TransferEncoding/Binary|/?SBFirst" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF /Compression/JAI requires /Prediror 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; return Rule::Applier::OK; } Rule::Applier::cons_t out_tiffjai_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { if (out_tiffjai_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; Image::Sampled *img=sf->getImg(); unsigned char cs=img->getCs(); /* color space */ if (cs!=Image::Sampled::CS_GRAYSCALE && cs!=Image::Sampled::CS_RGB && cs!=Image::Sampled::CS_YCbCr && cs!=Image::Sampled::CS_CMYK) { /* Dat: CS_YCCK is supported by JPEG, but unsupported by TIFF-JPEG */ Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF /Compression/JAI doesn't support this color space" << (Error*)0; return Rule::Applier::BAD; } /* Imp: test all CMYK TIFF tags */ /* Imp: test with RGB and CMYK images */ TIFFPrinter tp(out, or_->cache.TransferEncoding==or_->cache.TE_LSBfirst); /* ^^^ Dat: Binary defaults to MSBfirst, beacuse QuarkXPress 3 can read only * MSBfirst TIFF files. */ char const *databeg=img->getHeadp()+img->getXoffs(); assert(databeg[-2]=='\xFF' && databeg[-1]=='\xC0'); slen_t datalen=img->getRowbeg()-databeg; // printf("LEN=%u gl=%u datalen=%u\n", img->end_()-img->begin_(), img->getLength(), datalen); tp.getS().vi_write("\xFF\xD8\xFF\xC0", 4); /* fake-SOI SOF0 */ tp.getS().vi_write(databeg, datalen); /* DataPart */ // tp.getS().vi_write("\xFF\xD9", 2); /* fake-EOI */ /* ^^^ there must be an EOI already */ unsigned phot=0; bool inks=false, refe=false; switch (cs) { case Image::Sampled::CS_GRAYSCALE: phot=tp.PHOTOMETRIC_MINISBLACK; break; case Image::Sampled::CS_RGB: phot=tp.PHOTOMETRIC_RGB; break; case Image::Sampled::CS_YCbCr: phot=tp.PHOTOMETRIC_YCBCR; refe=true; break; /* preferred to RGB */ case Image::Sampled::CS_CMYK: phot=tp.PHOTOMETRIC_SEPARATED; inks=true; break; /* preferred to RGB */ default: Error::sev(Error::EERROR) << "TIFF6-JAI: color space " << (unsigned)cs << " not supported in TIFF-JPEG" << (Error*)0; } /* Dat: TIFF tags must appear in increasing numerical order */ tp.dirSL(tp.ImageWidth, img->getWd()); tp.dirSL(tp.ImageLength, img->getHt()); unsigned short eights[]={8,8,8,8}; tp.dirSHORT(tp.BitsPerSample, img->cs2cpp[cs], eights); tp.dirSL(tp.Compression, tp.COMPRESSION_JPEG); /* SHORT */ tp.dirSL(tp.Photometric, phot); /* SHORT */ tp.dirLONG(tp.StripOffsets, 8); tp.dirSL(tp.SamplesPerPixel, img->cs2cpp[cs]); /* SHORT */ tp.dirSL(tp.RowsPerStrip, img->getHt()); tp.dirLONG(tp.StripByteCounts, datalen+6); slen_t rats[]={1,1, 0,1, 255,1, 128,1, 255,1, 128,1, 255,1}; tp.dirRATIONAL(tp.XResolution, 1, rats); tp.dirRATIONAL(tp.YResolution, 1, rats); tp.dirSL(tp.PlanarConfig, 1); /* SHORT, PLANARCONFIG_CONTIG */ tp.dirSL(tp.ResolutionUnit, 1); /* SHORT */ if (inks) tp.dirSL(tp.InkSet, 1); /* SHORT */ tp.dirUNDEFINED(tp.JPEGTables, databeg-img->getHeadp()-2, img->getHeadp(), 2, "\xFF\xD9"); const unsigned char hvs=img->end_()[-1]; if (hvs!=0x22 && cs==Image::Sampled::CS_YCbCr) { // printf("hvs=0x%02X\n", hvs); const unsigned short horiz_vert[2]={ (unsigned short)((hvs+0U)>>4), (unsigned short)(hvs&15U) }; tp.dirSHORT(tp.YCbCrSubsampling, 2, horiz_vert); } if (refe) tp.dirRATIONAL(tp.ReferenceBlackWhite, 6, rats+2); tp.dirClose(); #if 0 { Files::FILEW f(fopen("t.hea","wb")); f.vi_write(img->getHeadp(), databeg-img->getHeadp()-2); /* HeadPart */ f.vi_write("\xFF\xD9", 2); f.close(); } { Files::FILEW f(fopen("t.dat","wb")); f.vi_write("\xFF\xD8\xFF\xC0", 4); /* fake-SOI SOF0 */ f.vi_write(databeg, datalen); /* DataPart */ f.close(); } #endif // out.vi_write(img->getHeadp(), img->getRowbeg()-img->getHeadp()); /* HeadPart */ // out.vi_write(img->getRowbeg(), img->end_()-img->getRowbeg()); /* DataPart */ return Rule::Applier::OK; /* SUXX: see compatibility notes in FAQ (README) */ } Rule::Applier out_tiffjai_applier = { "TIFF6-JAI", out_tiffjai_check_rule, out_tiffjai_work, 0 }; /* tiff --- Tue Jun 4 16:23:48 CEST 2002 */ /** by pts@fazekas.hu at Tue Jun 11 16:56:53 CEST 2002 * Reads a JPEG Baseline (SOF0) stream on input, and drops everything before * the first SOF0 marker. Then writes an SOI marker, the SOF0 marker, and * everything after the SOI marker. The last two bytes read must be an * EOI marker (/\xFF\xD9/). The first thing to be read must be a SOI marker * (/\xFF+\xD8/). The getJPEGTables() method can be used to retrieve the * data read before the SOF0 marker. An SOS marker must be read after SOF0. * Also retains some information (hvsamples[0]) from the SOF0 marker. * Suitable for reading the output of cjpeg and Ghostscript /FlateEncode. * This encoder would be much harder if we were not allowed to read the * JPEG stream into memory. */ class JPEGSOF0Encode: public PSEncoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ JPEGSOF0Encode(GenBuffer::Writable &out_); virtual void vi_write(char const*buf, slen_t len); SimBuffer::Flat const& getJPEGTables() const { return buf; } unsigned char getColorSpace() const { return gi.colorspace; } unsigned char getHVS() const { return gi.hvs; } protected: GenBuffer::Writable &out; SimBuffer::B buf; struct jai_gfxinfo gi; }; JPEGSOF0Encode::JPEGSOF0Encode(GenBuffer::Writable &out_): out(out_) {} void JPEGSOF0Encode::vi_write(char const*bufr, slen_t len) { if (len==0) { { Filter::FlatD flatd(buf(), buf.getLength()); jai_parse_jpeg(&gi, &flatd); } slen_t len=buf.getLength(); if (gi.bad==0 && (len<4 || buf[len-2]!='\xFF' || buf[len-1]!='\xD9')) gi.bad=10; if (gi.bad!=0) Error::sev(Error::EERROR) << "JPEGS0F0: invalid JPEG stream: " << jai_errors[gi.bad] << (Error*)0; out.vi_write("\xFF\xD8", 2); /* extra SOI */ out.vi_write(buf()+gi.SOF_offs-2, len-gi.SOF_offs+2); /* SOF0 and followers */ out.vi_write(0,0); assert(buf[gi.SOF_offs-2]=='\xFF'); /* BUGFIX at 2002.12.02 */ buf[gi.SOF_offs-1]='\xD9'; /* extra EOI */ buf.keepLeft(gi.SOF_offs); /* keep only headers */ } else buf.vi_write(bufr, len); } Rule::Applier::cons_t out_tiff_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_TIFF || cache->Compression==Rule::Cache::CO_JAI ) return Rule::Applier::DONT_KNOW; bool badp=false; /* Dat: acroread TIFF predictor2 OK. (examples/fishg_lzw2_pdf.job) */ /* Dat: /ZIP with /Predictor OK */ if (cache->Predictor!=cache->PR_None) { if (cache->Predictor!=cache->PR_TIFF2) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF requires /Predictor 1|2" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_ZIP && cache->Compression!=Rule::Cache::CO_LZW) { Error::sev(Error::WARNING_DEFER) << "check_rule: real /Predictor requires /ZIP or /LZW" << (Error*)0; badp=true; } } #if !HAVE_LZW if (cache->Compression==Rule::Cache::CO_LZW) { Error::sev(Error::WARNING_DEFER) << "check_rule: `configure --enable-lzw' for /Compression/LZW with /FileFormat/TIFF" << (Error*)0; badp=true; } #endif if (cache->Compression==Rule::Cache::CO_Fax && !cache->isOneBit()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF /Compression/Fax requires a 1-bit /SampleFormat" << (Error*)0; badp=true; } if (!cache->isGray() && !cache->isTransparentM() && !cache->isIndexed() && !cache->isRGB()) { /* Dat: unsupported SampleFormats: /Opaque, /Transparent and /Asis. */ Error::sev(Error::WARNING_DEFER) << "check_rule: unsupported /SampleFormat for /FileFormat/TIFF" << (Error*)0; badp=true; } if (!cache->isBinSB()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /FileFormat/TIFF requires /TransferEncoding/Binary|/?SBFirst" << (Error*)0; badp=true; } if (cache->isDCTE() && cache->SampleFormat!=Image::SF_Rgb8 && cache->SampleFormat!=Image::SF_Gray8 && cache->SampleFormat!=Image::SF_Indexed8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /DCTEncode requires /Rgb8 or /Gray8 (or /Indexed8)" << (Error*)0; badp=true; } if (!badp && cache->isTransparentM()) { cache->origSampleFormat=cache->SampleFormat; cache->SampleFormat=Image::SF_Transparent8; } return (Rule::Applier::cons_t)(badp ? 0+Rule::Applier::BAD : 0+Rule::Applier::OK); /* ^^^ Dat: 0+: pacify g++-3.1 */ } Rule::Applier::cons_t out_tiff_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { Rule::Cache *cache=&or_->cache; Image::sf_t origSampleFormat=cache->origSampleFormat; if (out_tiff_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; assert(!sf->hasTranspp() || cache->isTransparentM()); /** Alpha channel or null. */ Image::Indexed *alpha=(Image::Indexed*)NULLP; if (cache->isTransparentM()) { // fprintf(stderr,"sf=%u osf=%u\n", cache->SampleFormat, origSampleFormat); alpha=PTS_dynamic_cast(Image::Indexed*,sf->getImg())->calcAlpha(); PTS_dynamic_cast(Image::Indexed*,sf->getImg())->getClearTransp(); assert((alpha!=NULLP) == (sf->hasTranspp()==true)); sf->clearTransp(); static Image::sf_t const graytab[9]={Image::SF_None,Image::SF_Gray1,Image::SF_Gray2,Image::SF_None,Image::SF_Gray4,Image::SF_None,Image::SF_None,Image::SF_None,Image::SF_Gray8}; static Image::sf_t const rgbtab[9]={Image::SF_None,Image::SF_Rgb1,Image::SF_Rgb2,Image::SF_None,Image::SF_Rgb4,Image::SF_None,Image::SF_None,Image::SF_None,Image::SF_Rgb8}; static Image::sf_t const indexedtab[9]={Image::SF_None,Image::SF_Indexed1,Image::SF_Indexed2,Image::SF_None,Image::SF_Indexed4,Image::SF_None,Image::SF_None,Image::SF_None,Image::SF_Indexed8}; unsigned char minbpc=sf->minRGBBpcc(); // fprintf(stderr,"minbpc=%u\n",minbpc); if (minbpc<8 && origSampleFormat==Image::SF_Transparent8) minbpc=8; else if (minbpc<4 && origSampleFormat==Image::SF_Transparent4) minbpc=4; else if (minbpc<2 && origSampleFormat==Image::SF_Transparent2) minbpc=2; // fprintf(stderr,"minbpc=%u\n",minbpc); // cacheHints.EncoderBPL=(slen_t)img->getWd()*img->getCpp()*img->getBpc(); /* ^^^ Dat: doSampleFormat will do it correctly */ // assert(saf!=Image::SF_max); cache->SampleFormat=(alpha==NULLP ? indexedtab : sf->minGrayBpcc()==0 ? rgbtab : graytab)[minbpc]; } or_->doSampleFormat(sf); /* No separations */ Image::Sampled *img=sf->getImg(); /* call this _after_ doSampleFormat()! */ TIFFPrinter tp(out, or_->cache.TransferEncoding==or_->cache.TE_LSBfirst); /* ^^^ Dat: Binary defaults to MSBfirst, beacuse QuarkXPress 3 can read only * MSBfirst TIFF files. */ unsigned phot= cache->isRGB() ? 0+tp.PHOTOMETRIC_RGB // : cache->SampleFormat==Image::SF_Mask ? tp.PHOTOMETRIC_MASK : cache->isGray() ? 0+tp.PHOTOMETRIC_MINISBLACK // : cache->isIndexed() ? tp.PHOTOMETRIC_PALETTE : 0+tp.PHOTOMETRIC_PALETTE /* /Indexed*, /Mask, /Transparent+ */; unsigned compr=tp.COMPRESSION_NONE; Filter::VerbatimCountE vc(tp.getS()); GenBuffer::Writable *cp=&vc; JPEGSOF0Encode *jp=(JPEGSOF0Encode*)NULLP; // Dat: g++-3.4: Rule::Cache::CO_None: `cache cannot appear in a constant expression' switch (cache->Compression) { case Rule::Cache::CO_None: break; case Rule::Cache::CO_ZIP: compr=tp.COMPRESSION_DEFLATE; cp=PSEncoder::newFlateEncode(*cp, or_->cacheHints.Effort); break; case Rule::Cache::CO_LZW: compr=tp.COMPRESSION_LZW; cp=PSEncoder::newLZWEncode(*cp); break; /* vvv Dat: RunLengthEncode EOD (char 128) is OK and ignored in TIFF PackBits streams */ case Rule::Cache::CO_RLE: compr=tp.COMPRESSION_PACKBITS; cp=PSEncoder::newRunLengthEncode(*cp, or_->cacheHints.RecordSize); break; case Rule::Cache::CO_Fax: if (or_->cacheHints.K<0) compr=tp.COMPRESSION_CCITTFAX4; else if (or_->cacheHints.K==0) compr=tp.COMPRESSION_CCITTFAX3; else { compr=tp.COMPRESSION_CCITTFAX3; or_->cacheHints.K=img->getHt(); } cp=PSEncoder::newCCITTFaxEncode(*cp, or_->cacheHints.K, or_->cacheHints.EncoderBPL, /*EndOfLine:*/ compr==tp.COMPRESSION_CCITTFAX3, /*BlackIs1: !*/ true); /* Dat: libtiff enforces EndOfLine==(compr==tp.COMPRESSION_CCITTFAX3) */ break; case Rule::Cache::CO_IJG: compr=tp.COMPRESSION_JPEG; jp=new JPEGSOF0Encode(vc); cp=PSEncoder::newDCTIJGEncode(*jp, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.Quality); break; case Rule::Cache::CO_DCT: compr=tp.COMPRESSION_JPEG; { SimBuffer::B other_parameters; or_->cacheHints.DCT->dump(other_parameters, 0, false); jp=new JPEGSOF0Encode(vc); cp=PSEncoder::newDCTEncode(*jp, or_->cacheHints.EncoderColumns, or_->cacheHints.EncoderRows, or_->cacheHints.EncoderColors, or_->cacheHints.ColorTransform, other_parameters); break; } default: assert(0); } GenBuffer::Writable *pp=cp; if (cache->hasPredictor()) pp=PSEncoder::newPredictor(*cp, cache->Predictor, or_->cacheHints.PredictorBPC, or_->cacheHints.PredictorColumns, or_->cacheHints.PredictorColors); slen_t rlenht=img->getRlen()*img->getHt(); Image::Sampled::dimen_t wd=img->getWd(); if (rlenht!=0) { /* Dat: TIFF inserts extra sample bits... */ /* TIFF images with transparency are really inefficient. That's because * libtiff doesn't read or write an indexed image with transparency: * Sorry, can not handle contiguous data with PhotometricInterpretation=3, * and Samples/pixel=2. * So Indexed images are converted to RGB* or Gray* first, and then the * alpha channel is added. The result is a big and inefficiently * compressible TIFF file. */ if (alpha!=NULLP) { unsigned char bpc=img->getBpc(); slen_t rlen=img->getRlen(); slen_t writelen; char *buf=(char*)NULLP; char const*psave=img->getRowbeg(), *p, *ppend=psave+rlenht; char const*r=alpha->getRowbeg(), *rend; char *t; register unsigned u; Image::Sampled::dimen_t rlena=(wd+7)>>3; assert(rlena==alpha->getRlen()); // printf("SF=%u\n", cache->SampleFormat); if (cache->isGray()) { /* works at Mon Dec 9 01:25:59 CET 2002 */ static unsigned char const szor1[16]={2*0,2*1,2*4,2*5,2*16,2*17,2*20,2*21,2*64,2*65,2*68,2*69,2*80,2*81,2*84,2*85}; static unsigned char const szor2[16]={85,84,81,80,69,68,65,64,21,20,17,16,5,4,1,0}; // static unsigned char const szor2[8]={0,1,16,17,64,65,80,81}; buf=new char[(writelen=((slen_t)wd*bpc+3)>>2)+24]; assert(rlena*8>=rlen); while (psave!=ppend) { t=buf; rend=r+rlena; p=psave; psave+=rlen; assert(psave<=ppend); u=(1<<16); switch (bpc) { case 8: while (p!=psave) { /* Dat: works at Tue Sep 10 22:45:52 CEST 2002 */ if (0!=(u&(1<<16))) u=*(unsigned char const*)r++|(1<<8); *t++=*p++; *t++=-(0==(u&128)); u<<=1; } break; case 4: while (p!=psave) { if (0!=(u&(1<<16))) u=*(unsigned char const*)r++|(1<<8); *t++=(p[0]&0xF0)|(0==(u&128)?15:0); *t++=((p[0]&0xF)<<4)|(0==(u&64)?15:0); p++; u<<=2; } break; case 2: while (p!=psave) { if (0!=(u&(1<<16))) u=*(unsigned char const*)r++|(1<<8); *t++=(p[0]&0xC0 )|((u&128)!=0?0:48)|((p[0]&0x30)>>2)|((u&64)!=0?0:3); *t++=((p[0]&0xC)<<4)|((u& 32)!=0?0:48)|((p[0]&0x3 )<<2)|((u&16)!=0?0:3); p++; u<<=4; } break; case 1: while (p!=psave) { u=*(unsigned char const*)r++; *t++=szor1[*(unsigned char const*)p>>4]|szor2[u>>4]; *t++=szor1[*(unsigned char const*)p&15]|szor2[u&15]; p++; } break; } /* SWITCH Gray bpc */ // assert(p-psave+0U==rlena*8U); assert(p>=psave); pp->vi_write(buf, writelen); } } else { /* works at Sun Dec 8 23:30:17 CET 2002 */ assert(cache->isRGB()); buf=new char[(writelen=((slen_t)wd*bpc+1)>>1)+24]; while (psave!=ppend) { t=buf; p=psave; psave+=rlen; assert(psave<=ppend); u=(1<<16); rend=r+rlena; /* superfluous */ switch (bpc) { case 8: while (p>4)&15); /* R1 and G1 */ *t++=(p[2]<<4)|((u&64)!=0?0:15); /* B1 and A1 */ p+=3; u<<=2; } break; case 2: while (p>2)&0x3C)|((u&64)!=0?0:3); /* R1 G1B1 A1 */ *t++=(p[1]<<4)|((p[2]>>4)&0x0C)|((u&32)!=0?0:3); /* R2G1 B1 A2 */ *t++=(p[2]<<2)|((u&16)!=0?0:3); /* R3G3B3 and A3 */ p+=3; u<<=4; } break; default: // case 1: while (p>1)&0xE)|((u&64)!=0?0:1); *t++=(p[0]<<6)|((p[1]>>2)&0x80)|((u&32)!=0?0:16) |((p[1]>>3)&0xE)|((u&16)!=0?0:1); *t++=((p[1]<<4)&0xE0)|((u&8)!=0?0:16) |((p[1]<<3)&0x7)|((p[2]>>5)&0x06)|((u&4)!=0?0:1); *t++=((p[2]<<2)&0xE0)|((u&2)!=0?0:16) |((p[2]<<1)&0x0E)|((u&1)!=0?0:1); p+=3; } break; } /* SWITCH RGB bpc */ assert(r==rend); // r=rend; pp->vi_write(buf, writelen); } } delete [] buf; } else pp->vi_write(img->getRowbeg(), rlenht); } pp->vi_write(0,0); /* flush all */ if (pp!=cp) delete pp; if (cp!=&vc) delete cp; bool refe=false; if (compr==tp.COMPRESSION_JPEG) switch (jp->getColorSpace()) { case Image::Sampled::CS_GRAYSCALE: assert(phot==tp.PHOTOMETRIC_MINISBLACK || phot==tp.PHOTOMETRIC_PALETTE); /* Dat: we don't change `phot' here, so JPEG compression can be applied * to the palette indexes of indexed images :-) */ break; case Image::Sampled::CS_RGB: phot=tp.PHOTOMETRIC_RGB; break; case Image::Sampled::CS_YCbCr: phot=tp.PHOTOMETRIC_YCBCR; refe=true; break; /* preferred to RGB */ // case Image::Sampled::CS_CMYK: phot=tp.PHOTOMETRIC_SEPARATED; inks=true; break; /* preferred to RGB */ default: Error::sev(Error::EERROR) << "TIFF6: color space " << (unsigned)jp->getColorSpace() << " not supported in TIFF-JPEG" << (Error*)0; } /* Dat: TIFF tags must appear in increasing numerical order */ tp.dirSL(tp.ImageWidth, wd); // tp.dirSL(tp.ImageWidth, img->getWd()/2); tp.dirSL(tp.ImageLength, img->getHt()); unsigned short s4[]={img->getBpc(),img->getBpc(),img->getBpc(),img->getBpc()}; /* ^^^ these values may be different according to the TIFF6 spec, but * libtiff can read TIFF files only with same BitsPerSamples. */ unsigned sppa=img->getCpp()+(alpha!=NULLP ? 1:0); tp.dirSHORT(tp.BitsPerSample, sppa, s4); tp.dirSL(tp.Compression, compr); /* SHORT */ tp.dirSL(tp.Photometric, phot); /* SHORT */ if (cache->Compression==Rule::Cache::CO_Fax) tp.dirSL(tp.FillOrder, 1); /* byte abcdefgh is (a<<7)+...+h */ tp.dirLONG(tp.StripOffsets, 8); if (!cache->isIndexed()) tp.dirSL(tp.SamplesPerPixel, sppa); /* SHORT */ // tp.dirSL(tp.SamplesPerPixel, 2); /* SHORT */ tp.dirSL(tp.RowsPerStrip, img->getHt()); tp.dirLONG(tp.StripByteCounts, vc.getCount()); slen_t rats[]={1,1, 0,1, 255,1, 128,1, 255,1, 128,1, 255,1}; tp.dirRATIONAL(tp.XResolution, 1, rats); tp.dirRATIONAL(tp.YResolution, 1, rats); tp.dirSL(tp.PlanarConfig, 1); /* SHORT, PLANARCONFIG_CONTIG */ if (compr==tp.COMPRESSION_CCITTFAX3) tp.dirLONG(tp.Group3Options, (tp.GROUP3OPT_UNCOMPRESSED)|(or_->cacheHints.K!=0?tp.GROUP3OPT_2DENCODING:0)); if (compr==tp.COMPRESSION_CCITTFAX4) tp.dirLONG(tp.Group4Options, tp.GROUP4OPT_UNCOMPRESSED); tp.dirSL(tp.ResolutionUnit, 1); /* SHORT */ if (cache->Predictor!=cache->PR_None) { tp.dirSL(tp.Predictor, cache->Predictor); /* 1|2 */ if (img->getBpc()!=8) Error::sev(Error::WARNING) << "TIFF6: libtiff supports /Predictor only with bpc=8 and bpc=16" << (Error*)0; } if (cache->isIndexed() || cache->isTransparentM()) { unsigned colorlen=(1<getBpc()), i=0; unsigned short *r=new unsigned short[3*colorlen], *g=r+colorlen, *b=g+colorlen; memset(r, '\0', 3*colorlen); /** Image palette data */ char const *p=img->getHeadp(), *pend=img->getRowbeg(); assert((pend-p)%3==0); assert(3*colorlen>=(unsigned)(pend-p)); while (pgetJPEGTables().getLength(), jp->getJPEGTables()() /* , 2, "\xFF\xD9" */); const unsigned char hvs=jp->getHVS(); if (hvs!=0x22 && phot==tp.PHOTOMETRIC_YCBCR) { const unsigned short horiz_vert[2]={ (unsigned short)((hvs+0U)>>4), (unsigned short)(hvs&15U) }; tp.dirSHORT(tp.YCbCrSubsampling, 2, horiz_vert); } if (refe) tp.dirRATIONAL(tp.ReferenceBlackWhite, 6, rats+2); delete jp; } tp.dirClose(); return Rule::Applier::OK; } Rule::Applier out_tiff_applier = { "TIFF6", out_tiff_check_rule, out_tiff_work, 0 }; /* --- Sat Apr 20 11:32:42 CEST 2002 -- Sat Apr 20 16:48:25 CEST 2002 */ #if OBJDEP # warning REQUIRES: crc32.o # warning REQUIRES: crc32.o #endif /** Encodes 32-bit (data.length-minus), data, crc32. */ class LenCRC32Encode: public PSEncoder { public: /** @param maxcpl_: maximum # hex digits per line, should be even */ LenCRC32Encode(GenBuffer::Writable &out_, unsigned minus_); virtual void vi_write(char const*buf, slen_t len); protected: GenBuffer::Writable &out; unsigned minus; /** The length is not known in advance, so we have to buffer the whole output * in memory. */ SimBuffer::B sofar; }; LenCRC32Encode::LenCRC32Encode(GenBuffer::Writable &out_, unsigned minus_): out(out_), minus(minus_), sofar("1234") {} void LenCRC32Encode::vi_write(char const*buf, slen_t len) { if (len==0) { char *s=const_cast(sofar()); slen_t slen=sofar.getLength(); unsigned PTS_INT32_T crc=crc32(CRC32_INITIAL, s+4, slen-4); slen-=minus+4; s[0]=slen>>24; s[1]=slen>>16; s[2]=slen>>8; s[3]=slen; s=sofar.vi_mkend(4); s[0]=crc >>24; s[1]=crc>>16; s[2]=crc>>8; s[3]=crc; out.vi_write(sofar(), sofar.getLength()); out.vi_write(0,0); } else sofar.vi_write(buf, len); } /** PNG output (RFC 2083) */ Rule::Applier::cons_t out_png_check_rule(Rule::OutputRule* or_) { /* Supported PNG types: /Gray1, /Gray2, /Gray4, /Gray8, /Rgb8, * /Indexed1, /Indexed2, /Indexed4, /Indexed8. * Unsupported PNG types: /Gray16, /Rgb16, /GrayA8, /GrayA16, /RgbA8, * /RgbA16. * /Indexed* supports transparency (via PNG chunk tRNS). */ Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_PNG ) return Rule::Applier::DONT_KNOW; bool badp=false; /* Dat: (by policy) we don't support /Transparent or /Opaque here; the * user should not specify such SampleFormat in the .job file. */ if (!cache->isGray() && !cache->isTransparentM() && !cache->isIndexed() && cache->SampleFormat!=Image::SF_Rgb8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNG requires /Gray*, /Indexed*, /Mask, /Transparent+ or /Rgb8" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNG requires /Binary" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None && cache->Compression!=Rule::Cache::CO_ZIP) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNG requires /Compression/None or /ZIP" << (Error*)0; badp=true; } if (cache->Predictor==cache->PR_TIFF2) { Error::sev(Error::WARNING_DEFER) << "check_rule: /PNG requires /Predictor >=10" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; /* Now we are sure about Rule::Applier::OK. */ or_->cache.WarningOK=true; /* ?? */ return Rule::Applier::OK; } Rule::Applier::cons_t out_png_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { Rule::Cache *cache=&or_->cache; char tmp[64], colortype; register char*p; unsigned PTS_INT32_T crc; // assert(0); if (out_png_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); Image::Sampled *img=sf->getImg(); unsigned char bpc=img->getBpc(); /* set _after_ doSampleFormat */ Image::Sampled::dimen_t wd=img->getWd(), ht=img->getHt(); GenBuffer::Writable *rp=new LenCRC32Encode(out,4); GenBuffer::Writable *cp=PSEncoder::newFlateEncode(*rp, (cache->Compression==Rule::Cache::CO_None) ? 0: or_->cacheHints.Effort); /* Dat: PredictorColumns, PredictorBPC and PredictorColors are forced to * match the image, because PNG requires it. */ GenBuffer::Writable *pp=PSEncoder::newPredictor( *cp, cache->Predictor==cache->PR_None ? cache->PR_PNGNone : cache->Predictor, bpc, /*or_->cacheHints.PredictorBPC*/ wd, /*or_->cacheHints.PredictorColumns*/ img->getCpp() /*or_->cacheHints.PredictorColors*/ ); /* Critical PNG chunks (capital 1st letter) and ancillary PNG chunks: * * -: zero, 1: exactly one, ?: 0 or 1, *: 0 or more, +: 1 or more * Name Nr sam2p Ordering constraints * IHDR 1 1 Must be first * cHRM ? - Before PLTE and IDAT * gAMA ? - Before PLTE and IDAT * sBIT ? - Before PLTE and IDAT * PLTE ? ? Before IDAT * hIST ? - After PLTE; before IDAT * tRNS ? ? After PLTE; before IDAT * bKGD ? ? After PLTE; before IDAT * pHYs ? - Before IDAT * tIME ? - None * tEXt * - None * zTXt * - None * IDAT + 1 After IHDR and PLTE, multiple IDATs must be consecutive * IEND 1 1 Must be last */ /* 0..3: PNG header */ /* 8..11: IHDR chunk length */ /* 12..15: IHDR chunk name */ memcpy(tmp,"\211PNG\r\n\032\n\0\0\0\015IHDR",16); /* ASCII charset is assumed. */ p=tmp+16; *p++=wd>>24; *p++=wd>>16; *p++=wd>>8; *p++=wd; /* 16: Width */ *p++=ht>>24; *p++=ht>>16; *p++=ht>>8; *p++=ht; /* 20: Height */ *p++=bpc; /* 24: Bit depth */ colortype=*p++=cache->isGray()?0:cache->isRGB()?2:3; /* 25: Color type */ *p++=0; /* 26: Compression method: deflate/32K (forced by PNG spec), overcoming with Effort==0 */ *p++=0; /* 27: Filter type: adaptive filtering with 5 basic PNG filter types */ *p++=0; /* 28: Non-interlaced */ crc=crc32(CRC32_INITIAL, tmp+12, 17); *p++=crc>>24;*p++=crc>>16;*p++=crc>>8;*p++=crc; /* 29: IHDR CRC */ out.vi_write(tmp, 33); if (colortype==3) { bool transp=cache->isTransparentM() && PTS_dynamic_cast(Image::Indexed*,img)->getTransp()>=0; /* unsigned ncols=PTS_dynamic_cast(Image::Indexed*,img)->getNcols(); */ unsigned ncols3=img->getRowbeg()-img->getHeadp(); p=tmp; *p++=0; *p++=0; *p++=ncols3>>8; *p++=ncols3; /* 0: PLTE chunk length */ *p++='P'; *p++='L'; *p++='T'; *p++='E'; /* 4: PLTE chunk name */ out.vi_write(tmp, 8); if (transp) { PTS_dynamic_cast(Image::Indexed*,img)->makeTranspZero(); p=img->getHeadp(); p[0]=p[1]=p[2]=(char)0; /* force black backround (for consistency) */ } out.vi_write(img->getHeadp(), ncols3); crc=crc32(crc32(CRC32_INITIAL,tmp+4,4), img->getHeadp(), ncols3); p=tmp; *p++=crc>>24;*p++=crc>>16;*p++=crc>>8;*p++=crc; /* 0: PLTE CRC */ out.vi_write(tmp, 4); if (transp) { out.vi_write("\0\0\0\1tRNS\0@\346\330f", 13); /* color 0 is transparent */ //fprintf(stderr, "tRNS: 0x%08lx", (unsigned long)crc32(CRC32_INITIAL,"tRNS\0",5)); /* 0x40e6d866 */ out.vi_write("\0\0\0\1bKGD\0\210\5\35H", 13); /* color 0 is background color */ //out.vi_write("\0\0\0\1bKGD\2\x66\x0b\x7c\x64", 13); /* color 2 is background color */ //fprintf(stderr, "bKGD: 0x%08lx", (unsigned long)crc32(CRC32_INITIAL,"bKGD\2",5)); /* 0x88051d48 */ } } slen_t rlenht=img->getRlen()*img->getHt(); #if 0 /* Calculates _bad_ CRC (before compression etc.) */ p=tmp; *p++=rlenht>>24; *p++=rlenht>>16; *p++=rlenht>>8; *p++=rlenht; /* 0: IDAT chunk length */ *p++='I'; *p++='D'; *p++='A'; *p++='T'; /* 4: IDAT chunk name */ out.vi_write(tmp, 8); if (rlenht!=0) pp->vi_write(img->getRowbeg(), rlenht); pp->vi_write(0,0); /* flush all, write CRC */ crc=crc32(crc32(CRC32_INITIAL,tmp+4,4), img->getRowbeg(), rlenht); p=tmp; *p++=crc>>24;*p++=crc>>16;*p++=crc>>8;*p++=crc; /* 0: IDAT CRC */ out.vi_write(tmp, 4); #else rp->vi_write("IDAT",4); if (rlenht!=0) pp->vi_write(img->getRowbeg(), rlenht); pp->vi_write(0,0); /* flush all, write CRC */ #endif out.vi_write("\0\0\0\0IEND\256B`\202",12); /* IEND chunk */ delete pp; delete cp; delete rp; return Rule::Applier::OK; } Rule::Applier out_png_applier = { "PNG", out_png_check_rule, out_png_work, 0 }; /* --- Sat Jun 15 19:30:41 CEST 2002 */ /** BMP RLE compression, type 1. Seems to be optimal. * @param dst buffer with enough place for compressed data. The caller must * pre-allocate >=(send-sbeg)+(send-sbeg+128)*2/255. * @param sbeg first raw data char to compress * @param send char to finish compression just before * @return dst+(number of characters occupied by compressed data) * * in-memory implementation Sun Jun 23 20:02:41 CEST 2002 */ static char *bmp_compress1_row(char *dst, char const *sbeg, char const *send) { #if 0 # define BMP_ASSERT(x) assert(x) #else # define BMP_ASSERT(x) #endif #undef BUF #define BUF(x) (*(x)) #undef PUTCH__ #define PUTCH__(c) (*dst++=(c)) char c, c2; char const *beg, *end, *rend, *q, *r, *best; signed bestca, rca; /* both must fit into -255..255 */ slen_t frl, efrl; int ci; // bool oddp; beg=sbeg; end=(send-sbeg>255) ? beg+255 : send; while (beg!=end) { /* there is still unprocessed data in the buffer */ c=BUF(beg++); if (beg==end) { PUTCH__(1); PUTCH__(c); break; } /* last char */ if (c==BUF(beg)) { /* sure r chunk */ ci=2; beg++; rep: while (beg!=end && c==BUF(beg)) { beg++; ci++; } PUTCH__(ci); PUTCH__(c); /* r chunk */ } else { /* possible c chunk */ rend=end; BMP_ASSERT(end-beg<=254); if (end!=send) { /* read an extra char as the terminator of the last run-length of c, buf:0..254 */ end++; BMP_ASSERT(end-beg==255); /* buffer is full (255 chars) */ } best=r=beg; bestca=rca=-1; /* best and current advantage of c over r */ while (r!=rend) { /* c chunk should stop only at run-length boundaries */ BMP_ASSERT(-255<=rca && rca<=255); BMP_ASSERT(-255<=bestca && bestca<=255); q=r; r=q+1; ci=1; while (r!=end && BUF(r)==BUF(q)) { r++; ci++; } if (r==end && end!=rend) break; if (((r-beg)&1)==0) { /* odd (!) copy length */ rca+=3-ci; if (rca<=bestca-1) { r--; break; } /* fix-5 (instead of rule-4): `xyz|bbbbb|xyz|', `abcdef|gggggggg|abababababab|', `abcdef|ggg|hhh|ggg|hhh|ggg|hhh|ggg|hhh|abababababab|' */ if (bestca -1) */ BMP_ASSERT(q==end); while ((ci=(q==send)?-1:(unsigned char)*q++)!=-1 && (char)ci==c2) efrl++; } /* printf("clen=%u\n", clen); */ if (1+(r>beg ? r-beg : 256+beg-r)<255 && efrl>=256 && efrl%255==1) { r++; efrl--; } /* make the c chunk one char longer if appropriate */ // oddp=(1+(r-beg)&1)==1; PUTCH__(0); PUTCH__(1+(r-beg)); PUTCH__(c); while (beg!=r) { PUTCH__(BUF(beg)); beg++; } /* emit c chunk */ // if (oddp) PUTCH__(0); /* Imp: padding breaks optimality */ beg=q; /* remove beginning of the r chunk from the buffer */ if (ci>=0) { beg--; BMP_ASSERT((unsigned char)BUF(beg)==ci); } while (efrl>=255) { PUTCH__('\377'); PUTCH__(c2); efrl-=255; } /* emit full r chunks */ if (efrl>=2) { /* emit last r chunk */ PUTCH__(efrl); PUTCH__(c2); } else if (efrl!=0) { BMP_ASSERT(efrl==1); beg--; /* leave a single instance of c2 in beginning of the buffer */ BMP_ASSERT(BUF(beg)==c2); } } /* IF c chunk has followers */ } /* IF r or c chunk */ end=(send-beg>255) ? beg+255 : send; } /* WHILE main loop */ return dst; #undef BUF #undef PUTCH__ } /** Windows Bitmap BMP output */ Rule::Applier::cons_t out_bmp_check_rule(Rule::OutputRule* or_) { /* Supported BMP types: /Rgb8, * /Indexed1, /Indexed4, /Indexed8. */ Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_BMP ) return Rule::Applier::DONT_KNOW; bool badp=false; /* Dat: (by policy) we don't support /Transparent or /Opaque here; the * user should not specify such SampleFormat in the .job file. */ if (cache->SampleFormat!=Image::SF_Indexed1 /* Dat: /Indexed2 is not supported by /BMP */ && cache->SampleFormat!=Image::SF_Indexed4 && cache->SampleFormat!=Image::SF_Indexed8 && cache->SampleFormat!=Image::SF_Rgb8) { Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires /Indexed1, /Indexed4, /Indexed8 or /Rgb8" << (Error*)0; badp=true; } if (cache->TransferEncoding!=cache->TE_Binary) { Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires /Binary" << (Error*)0; badp=true; } if (cache->Compression!=Rule::Cache::CO_None && cache->Compression!=Rule::Cache::CO_RLE) { Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires /Compression/None or /RLE" << (Error*)0; badp=true; } if (cache->Compression==Rule::Cache::CO_RLE && cache->SampleFormat!=Image::SF_Indexed8) { /* !! Imp: Implement compr==2 for /Indexed4 */ Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP/RLE requires /Indexed8" << (Error*)0; badp=true; } if (cache->hasPredictor()) { Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires /Predictor 1" << (Error*)0; badp=true; } if (badp) return Rule::Applier::BAD; /* Now we are sure about Rule::Applier::OK. */ return Rule::Applier::OK; } Rule::Applier::cons_t out_bmp_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { if (out_bmp_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; or_->doSampleFormat(sf); Image::Sampled *img=sf->getImg(); Image::Sampled::dimen_t wd=img->getWd(), ht=img->getHt(), htc=ht; slen_t rlen=img->getRlen(); char const*pend=img->getRowbeg()+rlen*ht; char const*palbeg=img->getHeadp(), *palend=img->getRowbeg(); slen_t ncols4=(palend-palbeg)/3*4; unsigned biCompr=or_->cache.Compression!=or_->cache.CO_RLE ? 0 : or_->cache.SampleFormat==Image::SF_Indexed4 ? 2 : 1; SimBuffer::B data; slen_t crowsize=2+ rlen+(rlen+128)*2/255; /* !! Imp: real upper bound? */ char *crow=new char[crowsize]; /* !! GIMP compatibility */ if (or_->cache.Compression==or_->cache.CO_RLE) { /* Imp: bmp_compress2_row */ char *crow2; while (htc--!=0) { /* BMP stores rows from down */ crow2=bmp_compress1_row(crow, pend-rlen, pend); #if 0 crow2=crow; *crow2++=10; *crow2++=1; *crow2++=10; *crow2++=2; *crow2++=10; *crow2++=3; *crow2++=10; *crow2++=4; *crow2++=10; *crow2++=5; *crow2++=10; *crow2++=6; #endif assert((slen_t)(crow2-crow)<=crowsize-2); pend-=rlen; *crow2++='\0'; *crow2++='\0'; /* signal end of compressed data row */ /* fprintf(stderr, "htc=%u cl=%u\n", htc, crow2-crow); */ data.vi_write(crow, crow2-crow); } data.vi_write("\0\1", 2); /* signal end of bitmap */ } else { unsigned pad=(4-(rlen&3))&3; /* Dat: pad rows to 32 bits */ if (or_->cache.SampleFormat==Image::SF_Rgb8) { /* SWAP RGB values */ /* BUGFIX at Thu Dec 12 21:36:57 CET 2002 */ char *buf=new char[rlen]; while (htc--!=0) { /* BMP stores rows from down */ char const*pxend=pend, *px=pend-=rlen; char *q=buf; while (px!=pxend) { *q++=px[2]; *q++=px[1]; *q++=px[3]; px+=3; } data.vi_write(buf, rlen); if (pad!=0) data.vi_write("\0\0\0", pad); } delete [] buf; } else { while (htc--!=0) { /* BMP stores rows from down */ data.vi_write(pend-=rlen, rlen); if (pad!=0) data.vi_write("\0\0\0", pad); } } } assert(pend==img->getRowbeg()); delete [] crow; /* Now data is ready. */ char *bmphead=new char[54+ncols4+data.getLength()], *p=bmphead; *p++='B'; *p++='M'; /* magic number header */ lf32(p, 54+ncols4+data.getLength()); /* bfSize */ lf32(p, 0); /* zzHotX, zzHotY */ lf32(p, 54+ncols4); /* bfOffs */ lf32(p, 40); /* biSize==40 => Windows 3.x style BMP file */ lf32(p, wd); /* biWidth */ lf32(p, ht); /* biHeight */ lf16(p, 1); /* biPlanes, must be 1 */ lf16(p, img->getBpc()*img->getCpp()); /* biBitCnt: bits per pixel (1, 4, 8: /Indexed*; 24: /Rgb8) */ lf32(p, biCompr); /* biCompr */ lf32(p, 0); /* biSizeIm */ lf32(p, 0); /* biXPels */ lf32(p, 0); /* biYPels */ lf32(p, (palend-palbeg)/3); /* biClrUsed */ lf32(p, (palend-palbeg)/3); /* biClrImp */ /* vvv Now comes the palette (zero length for /Rgb) */ while (palbeg!=palend) { *p++=palbeg[2]; *p++=palbeg[1]; *p++=palbeg[0]; *p++='\0'; palbeg+=3; } assert((slen_t)(p-bmphead)==54+ncols4); out.vi_write(bmphead, p-bmphead); delete [] bmphead; #if 0 out.vi_write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 100); out.vi_write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 100); out.vi_write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 100); out.vi_write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 100); out.vi_write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 100); #endif out << data; out.vi_write(0,0); /* signal EOF */ return Rule::Applier::OK; } Rule::Applier out_bmp_applier = { "BMP", out_bmp_check_rule, out_bmp_work, 0 }; /* --- Sun Mar 24 13:48:57 CET 2002 */ /** The Empty applier produces an empty output file. */ Rule::Applier::cons_t out_empty_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_Empty ) return Rule::Applier::DONT_KNOW; return Rule::Applier::OK; } Rule::Applier::cons_t out_empty_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { (void)out; (void)sf; if (out_empty_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; return Rule::Applier::OK; } Rule::Applier out_empty_applier = { "Empty", out_empty_check_rule, out_empty_work, 0 }; /* --- Sun Mar 24 13:48:57 CET 2002 */ /** The Meta applier writes some meta-information into the output file */ Rule::Applier::cons_t out_meta_check_rule(Rule::OutputRule* or_) { Rule::Cache *cache=&or_->cache; if (cache->FileFormat!=cache->FF_Meta ) return Rule::Applier::DONT_KNOW; // return Rule::Applier::OK; /* Imp: implement the applier */ return Rule::Applier::BAD; } Rule::Applier::cons_t out_meta_work(GenBuffer::Writable& out, Rule::OutputRule*or_, Image::SampledInfo *sf) { (void)out; (void)sf; if (out_meta_check_rule(or_)!=Rule::Applier::OK) return Rule::Applier::DONT_KNOW; /* Imp: real content here */ return Rule::Applier::OK; } Rule::Applier out_meta_applier = { "Meta", out_meta_check_rule, out_meta_work, 0 }; /* __END__ */ sam2p-0.49.2/in_jai.cpp0000644000175100017510000003214312211371426012767 0ustar ptspts/* * in_jai.cpp -- read a JPEG file as-is * by pts@math.bme.hu at Sun Mar 17 20:15:25 CET 2002 */ /* Imp: test this code with various JPEG files! */ #ifdef __GNUC__ #pragma implementation #endif #include "image.hpp" #include "error.hpp" #if USE_IN_JAI #include "in_jai.hpp" #include /* memchr() */ #include /* --- */ class JAI: public Image::Sampled { public: /** (Horiz<<4+Vert) sampling factor for the first color component. Usually * 0x11, but TIFF defaults to 0x22. */ JAI(dimen_t wd_, dimen_t ht_, unsigned char bpc_, unsigned char cs_, slen_t flen_, slen_t SOF_offs_, unsigned char hvs_); virtual void copyRGBRow(char *to, dimen_t whichrow) const; virtual void to8(); virtual Image::Indexed* toIndexed(); virtual bool canGray() const; // virtual void setBpc(unsigned char bpc_); virtual Image::RGB * toRGB(unsigned char bpc_); virtual Image::Gray * toGray(unsigned char bpc_); virtual unsigned char minRGBBpc() const; virtual Image::Sampled* addAlpha(Image::Gray *al); void fixEOI(); }; JAI::JAI(dimen_t wd_, dimen_t ht_, unsigned char bpc_, unsigned char cs_, slen_t flen_, slen_t SOF_offs_, unsigned char hvs_) { param_assert(cs_<=5); // init(0,0,wd_,ht_,bpc_,TY_BLACKBOX,cs2cpp[cs_]); cs=cs_; bpc=8; (void)bpc_; // bpc=bpc_; /* /DCTDecode supports only BitsPerComponent==8 */ ty=TY_BLACKBOX; wd=wd_; ht=ht_; cpp=cs2cpp[cs_]; // pred=1; transpc=0x1000000UL; /* Dat: this means: no transparent color */ rlen=0; beg=new char[len=0+flen_+0+bpc]; rowbeg=(headp=const_cast(beg))+flen_; xoffs=SOF_offs_; trail=const_cast(beg)+len-bpc; const_cast(beg)[len-1]=hvs_; /* dirty place */ } void JAI::fixEOI() { /* by pts@fazekas.hu at Tue Jun 4 15:36:12 CEST 2002 */ if (rowbeg[-2]!='\xFF' || rowbeg[-1]!='\xD9') { *rowbeg++='\xFF'; *rowbeg++='\xD9'; } } Image::Sampled* JAI::addAlpha(Image::Gray *) { Error::sev(Error::WARNING) << "JAI: alpha channel ignored" << (Error*)0; return this; } unsigned char JAI:: minRGBBpc() const { return bpc; } void JAI::copyRGBRow(char*, dimen_t) const { assert(0); } void JAI::to8() { assert(0); } Image::Indexed* JAI::toIndexed() { return (Image::Indexed*)NULLP; } bool JAI::canGray() const { return cs==CS_GRAYSCALE; } Image::RGB * JAI::toRGB(unsigned char) { assert(0); return 0; } Image::Gray * JAI::toGray(unsigned char) { assert(0); return 0; } /* --- The following code is based on standard/image.c from PHP4 */ /* some defines for the different JPEG block types */ #define M_SOF0 0xC0 /* Start Of Frame0: Baseline JPEG */ #define M_SOF1 0xC1 /* N indicates which compression process */ #define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ #define M_SOF3 0xC3 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ #define M_SOF6 0xC6 #define M_SOF7 0xC7 #define M_SOF9 0xC9 #define M_SOF10 0xCA #define M_SOF11 0xCB #define M_SOF13 0xCD #define M_SOF14 0xCE #define M_SOF15 0xCF #define M_SOI 0xD8 #define M_EOI 0xD9 /* End Of Image (end of datastream) */ #define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ #define M_APP0 0xe0 #define M_APP1 0xe1 #define M_APP2 0xe2 #define M_APP3 0xe3 #define M_APP4 0xe4 #define M_APP5 0xe5 #define M_APP6 0xe6 #define M_APP7 0xe7 #define M_APP8 0xe8 #define M_APP9 0xe9 #define M_APP10 0xea #define M_APP11 0xeb #define M_APP12 0xec #define M_APP13 0xed #define M_APP14 0xee #define M_APP15 0xef #if 0 static unsigned int jai_next_marker(FILE *fp) /* get next marker byte from file */ { int c; #if 0 /**** pts ****/ /* skip unimportant stuff */ c = MACRO_GETC(fp); while (c != 0xff) { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } #else if (0xff!=(c=MACRO_GETC(fp))) return M_EOI; #endif /* get marker byte, swallowing possible padding */ do { if ((c = MACRO_GETC(fp)) == EOF) return M_EOI; /* we hit EOF */ } while (c == 0xff); return (unsigned int) c; } #endif #if 0 static inline int getc_(FILE *f) { return MACRO_GETC(f); } static inline long ftell_(FILE *f) { return ftell(f); } template static unsigned short jai_read2(T *fp); template static void jai_handle_jpeg(struct jai_gfxinfo *result, T *fp) { #endif /* Dat: removed templates at Tue Mar 11 19:59:16 CET 2003, because decoding * JPEG headers isn't time-critical */ static inline unsigned short jai_read2(GenBuffer::Readable *fp) { #if 0 unsigned char a[ 2 ]; /* just return 0 if we hit the end-of-file */ if (fread(a,sizeof(a),1,fp) != 1) return 0; return (((unsigned short) a[ 0 ]) << 8) + ((unsigned short) a[ 1 ]); #else int a=fp->vi_getcc(), b=fp->vi_getcc(); /* just return 0 if we hit the end-of-file */ return a>=0 && b>=0 ? (a<<8)+b : 0; #endif } /** main loop to parse JPEG structure */ void jai_parse_jpeg(struct jai_gfxinfo *result, DecoderTeller *fp, bool must_be_baseline) { int c; unsigned int length; unsigned char had_adobe; result->bad=9; /* signal invalid return value */ result->id_rgb=0; result->had_jfif=0; result->colortransform=127; /* no Adobe marker yet */ // fseek(fp, 0L, SEEK_SET); /* position file pointer on SOF */ /* Verify JPEG header */ /* Dat: maybe 0xFF != '\xFF' */ if ((c=fp->vi_getcc())!=0xFF) return; while ((c=fp->vi_getcc())==0xFF) ; if (c!=M_SOI) return; result->bad=1; // fprintf(stderr, "welcome ofs=%ld\n", fp->vi_tell()); while (1) { if ((c=fp->vi_getcc())!=0xFF) { result->bad=8; return; } while ((c=fp->vi_getcc())==0xFF) ; if (c==-1) { result->bad=2; return; } switch (c) { case M_SOF0: do_SOF: if (result->bad!=1) { result->bad=4; return; } /* only one M_SOF allowed */ result->SOF_type=c-M_SOF0; result->SOF_offs=fp->vi_tell(); // fprintf(stderr, "SOF_offs=%d\n", result->SOF_offs); /* handle SOFn block */ length=jai_read2(fp); result->bpc = fp->vi_getcc(); result->height = jai_read2(fp); result->width = jai_read2(fp); result->cpp = fp->vi_getcc(); if ((length-=8)!=3U*result->cpp) return; if (result->bpc!=8) { result->bad=6; return; } if (result->cpp!=1 && result->cpp!=3 && result->cpp!=4) { result->bad=5; return; } assert(length>=3); if (result->cpp==3) { result->id_rgb =fp->vi_getcc()=='R'; result->hvs=fp->vi_getcc(); fp->vi_getcc(); result->id_rgb&=fp->vi_getcc()=='G'; fp->vi_getcc(); fp->vi_getcc(); result->id_rgb&=fp->vi_getcc()=='B'; fp->vi_getcc(); fp->vi_getcc(); } else { length-=2; fp->vi_getcc(); result->hvs=fp->vi_getcc(); while (length--!=0) fp->vi_getcc(); } result->bad=2; break; case M_SOF1: case M_SOF2: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: if (!must_be_baseline) goto do_SOF; // fprintf(stderr, "SOF%u\n", marker-M_SOF0); assert(0); result->bad=3; return; case M_SOS: /* we are about to hit image data. We're done. Success. */ if (result->bad==2 /* && !feof(fp)*/) { /* Dat: !feof() already guaranteed */ if (result->cpp==1) { result->colorspace=Image::Sampled::CS_GRAYSCALE; } else if (result->cpp==3) { result->colorspace=Image::Sampled::CS_YCbCr; if (result->had_jfif!=0) ; else if (result->colortransform==0) result->colorspace=Image::Sampled::CS_RGB; else if (result->colortransform==1) ; else if (result->colortransform!=127) Error::sev(Error::EERROR) << "JAI: unknown ColorTransform: " << (unsigned)result->colortransform << (Error*)0; else if (result->id_rgb!=0) result->colorspace=Image::Sampled::CS_RGB; /* Imp: check for id_ycbcr */ else Error::sev(Error::WARNING) << "JAI: assuming YCbCr color space" << (Error*)0; } else if (result->cpp==4) { result->colorspace=Image::Sampled::CS_CMYK; if (result->colortransform==0) ; else if (result->colortransform==2) result->colorspace=Image::Sampled::CS_YCCK; else if (result->colortransform!=127) Error::sev(Error::EERROR) << "JAI: unknown ColorTransform: " << (unsigned)result->colortransform << (Error*)0; } else assert(0); result->bad=0; } /* fall through */ case M_EOI: /* premature EOF */ return; case M_APP0: /* JFIF application-specific marker */ length=jai_read2(fp); if (length==2+4+1+2+1+2+2+1+1) { result->had_jfif=fp->vi_getcc()=='J' && fp->vi_getcc()=='F' && fp->vi_getcc()=='I' && fp->vi_getcc()=='F' && fp->vi_getcc()==0; length-=7; } else length-=2; while (length--!=0) fp->vi_getcc(); break; case M_APP14: /* Adobe application-specific marker */ length=jai_read2(fp); if ((length-=2)==5+2+2+2+1) { had_adobe=fp->vi_getcc()=='A' && fp->vi_getcc()=='d' && fp->vi_getcc()=='o' && fp->vi_getcc()=='b' && fp->vi_getcc()=='e' && ((unsigned char)fp->vi_getcc())>=1; fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); fp->vi_getcc(); if (had_adobe) result->colortransform=fp->vi_getcc(); else fp->vi_getcc(); } else while (length--!=0) fp->vi_getcc(); break; case M_APP1: case M_APP2: case M_APP3: case M_APP4: case M_APP5: case M_APP6: case M_APP7: case M_APP8: case M_APP9: case M_APP10: case M_APP11: case M_APP12: case M_APP13: case M_APP15: /* fall through */ default: { /* anything else isn't interesting */ /* skip over a variable-length block; assumes proper length marker */ unsigned short length; length = jai_read2(fp); length -= 2; /* length includes itself */ #if 0 /**** pts: fseek would disturb later ftell()s and feof()s */ fseek(fp, (long) length, SEEK_CUR); /* skip the header */ #else while (length--!=0) fp->vi_getcc(); /* make feof(fp) correct */ #endif } } } } char const*jai_errors[]={ (char const*)NULLP, /*1*/ "missing SOF0 marker", /*2*/ "premature EOF", /*3*/ "not a Baseline JPEG (SOF must be SOF0)", /*4*/ "more SOF0 markers", /*5*/ "bad # components", /*6*/ "bad bpc", /*7*/ "?", /*8*/ "0xFF expected", /*9*/ "invalid JPEG header", // /*10*/ "not ending with EOI", /* not output by jai_handle_jpeg! */ }; static Image::Sampled *in_jai_reader(Image::Loader::UFD* ufd, SimBuffer::Flat const&) { // assert(0); struct jai_gfxinfo gi; Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; FILE *file_=ufdd->getFILE(/*seekable:*/true); jai_parse_jpeg(&gi, ufdd); // jai_parse_jpeg(&gi, (FILE*)file_); // long ftel=ftell((FILE*)file_); if (gi.bad!=0) Error::sev(Error::EERROR) << "JAI: " << jai_errors[gi.bad] << (Error*)0; // printf("ftell=%lu\n", ftell((FILE*)file_)); fseek((FILE*)file_, 0L, 2); /* EOF */ long flen=ftell((FILE*)file_); /* skip extra bytes after EOI. Imp: no need to do this */ // fprintf(stderr, "flen=%lu\n", flen); assert(flen>2); rewind((FILE*)file_); JAI *ret=new JAI(gi.width,gi.height,gi.bpc,gi.colorspace,flen,gi.SOF_offs,gi.hvs); if (fread(ret->getHeadp(), flen, 1, (FILE*)file_)!=1 || ferror((FILE*)file_)) { ret->fixEOI(); /* fclose((FILE*)file_); */ Error::sev(Error::EERROR) << "JAI: IO error" << (Error*)0; } /* fclose((FILE*)file_); */ return ret; } static Image::Loader::reader_t in_jai_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const& loadHints, Image::Loader::UFD* ufd) { if (0!=memcmp(buf, "\xff\xd8\xff", 3) || !(loadHints.findFirst((char const*)",jpeg-asis,",6)!=loadHints.getLength() || loadHints.findFirst((char const*)",asis,",6)!=loadHints.getLength()) ) return 0; Filter::UngetFILED* ufdd=(Filter::UngetFILED*)ufd; ufdd->seek(0); Image::Loader::reader_t ret=jai_is_baseline_jpeg(ufdd) ? in_jai_reader : 0; ufdd->seek(0); return ret; } #if 0 /* Filter::FlatR* used by JPEGSOF0Encode::vi_write() in appliers.cpp */ static inline int getc_(Filter::FlatR *f) { return f->getcc(); } static inline long ftell_(Filter::FlatR *f) { return f->tell(); } void jai_parse_jpeg(struct jai_gfxinfo *result, Filter::FlatR *f) { jai_handle_jpeg(result, f); } void jai_parse_jpeg(struct jai_gfxinfo *result, FILE *f) { jai_handle_jpeg(result, f); } #endif #if 0 /* unused */ int jai_is_baseline_jpeg(char const* filename) { /* by pts@fazekas.hu at Tue Mar 11 20:27:56 CET 2003 */ FILE *f=fopen(filename, "rb"); if (!f) return -1; Filter::FILED filed(f, /*closep:*/true); return jai_is_baseline_jpeg(&filed); } #endif int jai_is_baseline_jpeg(/*DecoderTeller*/Filter::UngetFILED *fp) { char buf[3]; struct jai_gfxinfo gi; bool qfalse=(3!=fp->vi_read(buf, 3) || 0!=memcmp(buf, "\xff\xd8\xff", 3)); fp->unread(buf, 3); if (qfalse) return false; fp->getFILE(/*seekable*/true); /* make it seekable, so the caller can seek back */ jai_parse_jpeg(&gi, fp, /*must_be_baseline:*/false); fp->seek(0); return gi.bad!=0 ? -1 : gi.SOF_type==0; } #else #define in_jai_checker (Image::Loader::checker_t)NULLP #endif /* USE_IN_JAI */ Image::Loader in_jai_loader = { "JAI", in_jai_checker, 0 }; sam2p-0.49.2/out_gif.cpp0000644000175100017510000002211712211371426013172 0ustar ptspts/* out_gif.cpp * by pts@fazekas.hu at Sat Mar 23 11:02:36 CET 2002 */ #include "image.hpp" #if USE_OUT_GIF #include #include /**** pts ****/ #ifdef __cplusplus # define AALLOC(var,len,itemtype) var=new itemtype[len] # define AFREE(expr) delete [] (expr) #else # include /* malloc(), free() */ # define AALLOC(var,len,itemtype) var=(itemtype*)malloc(len*sizeof(itemtype)); # define AFREE(expr) free((expr)) #endif #define HasLZW HAVE_LZW /* Imp: or USE_BUILTIN_LZW? */ #define True true #define False false /* The code of GIFEncodeImage is based on an early version of ImageMagick. */ static unsigned int GIFEncodeImage(GenBuffer::Writable& out, char const*ppbeg, register char const*ppend, const unsigned int data_size) { #define MaxCode(number_bits) ((1 << (number_bits))-1) #define MaxHashTable 5003 #define MaxGIFBits 12 #if defined(HasLZW) #define MaxGIFTable (1 << MaxGIFBits) #else #define MaxGIFTable max_code #endif #define GIFOutputCode(code) \ { \ /* \ Emit a code. \ */ \ if (bits > 0) \ datum|=((long) code << bits); \ else \ datum=(long) code; \ bits+=number_bits; \ while (bits >= 8) \ { \ /* \ Add a character to current packet. \ */ \ packet[byte_count++]=(unsigned char) (datum & 0xff); \ if (byte_count >= 254) \ { \ packet[-1]=byte_count; \ out.vi_write((char*)packet-1, byte_count+1); \ byte_count=0; \ } \ datum>>=8; \ bits-=8; \ } \ if (free_code > max_code) \ { \ number_bits++; \ if (number_bits == MaxGIFBits) \ max_code=MaxGIFTable; \ else \ max_code=MaxCode(number_bits); \ } \ } int bits, byte_count, i, next_pixel, number_bits; long datum; register int displacement, k; register char const*pp; short clear_code, end_of_information_code, free_code, *hash_code, *hash_prefix, index, max_code, waiting_code; unsigned char *packet, *hash_suffix; /* Allocate encoder tables. */ AALLOC(packet,257,unsigned char); AALLOC(hash_code,MaxHashTable,short); AALLOC(hash_prefix,MaxHashTable,short); AALLOC(hash_suffix,MaxHashTable,unsigned char); if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) || (hash_prefix == (short *) NULL) || (hash_suffix == (unsigned char *) NULL)) return(False); packet++; /* Now: packet-1 == place for byte_count */ /* Initialize GIF encoder. */ number_bits=data_size; max_code=MaxCode(number_bits); clear_code=((short) 1 << (data_size-1)); end_of_information_code=clear_code+1; free_code=clear_code+2; byte_count=0; datum=0; bits=0; for (i=0; i < MaxHashTable; i++) hash_code[i]=0; GIFOutputCode(clear_code); /* Encode pixels. */ /**** pts ****/ pp=ppbeg; waiting_code=*(unsigned char const*)pp++; /* unsigned char BUGFIX at Sun Dec 8 13:17:00 CET 2002 */ while (pp!=ppend) { /* Probe hash table. */ index=*(unsigned char const*)pp++; k=(int) ((int) index << (MaxGIFBits-8))+waiting_code; if (k >= MaxHashTable) k-=MaxHashTable; #if defined(HasLZW) if (hash_code[k] > 0) { if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index)) { waiting_code=hash_code[k]; continue; } if (k == 0) displacement=1; else displacement=MaxHashTable-k; next_pixel=False; for ( ; ; ) { k-=displacement; if (k < 0) k+=MaxHashTable; if (hash_code[k] == 0) break; if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index)) { waiting_code=hash_code[k]; next_pixel=True; break; } } if (next_pixel != False) /* pacify VC6.0 */ continue; } #endif GIFOutputCode(waiting_code); // printf("wc=%u\n", waiting_code); if (free_code < MaxGIFTable) { hash_code[k]=free_code++; hash_prefix[k]=waiting_code; hash_suffix[k]=index; } else { /* Fill the hash table with empty entries. */ for (k=0; k < MaxHashTable; k++) hash_code[k]=0; /* Reset compressor and issue a clear code. */ free_code=clear_code+2; GIFOutputCode(clear_code); number_bits=data_size; max_code=MaxCode(number_bits); } waiting_code=index; #if 0 /**** pts ****/ if (QuantumTick(i,image) && (image->previous == (Image2 *) NULL)) ProgressMonitor(SaveImageText,i,image->packets); #endif } /* Flush out the buffered code. */ GIFOutputCode(waiting_code); GIFOutputCode(end_of_information_code); if (bits > 0) { /* Add a character to current packet. */ packet[byte_count++]=(unsigned char) (datum & 0xff); if (byte_count >= 254) { packet[-1]=byte_count; out.vi_write((char*)packet-1, byte_count+1); byte_count=0; } } /* Flush accumulated data. */ if (byte_count > 0) { packet[-1]=byte_count; out.vi_write((char*)packet-1, byte_count+1); } /* Free encoder memory. */ AFREE(hash_suffix); AFREE(hash_prefix); AFREE(hash_code); AFREE(packet-1); return pp==ppend; } /** This isn't a complete GIF writer. For example, it doesn't support * animation or multiple sub-images. But it supports transparency and * compression. Only works when . The user should call * packPal() first to ensure img->getBpc()==8, and to get a minimal palette. */ void out_gif_write(GenBuffer::Writable& out, Image::Indexed *img) { /* Tested and proven to work at Sat Mar 23 13:11:41 CET 2002 */ unsigned i, c, bits_per_pixel; signed transp; char hd[19]; assert(img->getBpc()==8); /* 1 palette entry == 8 bits */ transp=img->getTransp(); memcpy(hd, transp!=-1 ? "GIF89a" : "GIF87a", 6); i=img->getWd(); hd[6]=i; hd[7]=i>>8; i=img->getHt(); hd[8]=i; hd[9]=i>>8; // transp=-1; /* With this, transparency will be ignored */ c=img->getNcols(); bits_per_pixel=1; while (((c-1)>>bits_per_pixel)!=0) bits_per_pixel++; /* ^^^ (c-1) BUGFIX at Mon Oct 20 15:18:24 CEST 2003 */ /* 63 -> 6, 64 -> 6, 65 -> 7 */ // if (bits_per_pixel>1) bits_per_pixel--; /* BUGFIX at Wed Apr 30 15:55:27 CEST 2003 */ /* BUGFIX at Mon Oct 20 15:18:14 CEST 2003 */ // fprintf(stderr, "GIF89 write transp=%d ncols=%d bpp=%d\n", transp, c, bits_per_pixel); assert(1<=bits_per_pixel && bits_per_pixel<=8); c=3*((1<getHeadp(), img->getRowbeg()-img->getHeadp()); /* write colormap */ if (c!=0) { char *padding=new char[(unsigned char)c]; /* BUGFIX at Fri Oct 17 18:05:09 CEST 2003 */ memset(padding, '\0', (unsigned char)c); /* Not automatic! */ out.vi_write(padding, (unsigned char)c); delete [] padding; } if (transp!=-1) { /* Write Graphics Control extension. Only GIF89a */ hd[0]=0x21; hd[1]=(char)0xf9; hd[2]=0x04; hd[3]=transp!=-1; /* dispose==0 */ hd[4]=hd[5]=0; /* delay==0 */ hd[6]=transp; /* transparent color index -- or 255 */ hd[7]=0; out.vi_write(hd, 8); } /* Write image header */ hd[8]=','; hd[ 9]=hd[10]=0; /* left */ hd[11]=hd[12]=0; /* top */ i=img->getWd(); hd[13]=i; hd[14]=i>>8; i=img->getHt(); hd[15]=i; hd[16]=i>>8; hd[17]=0; /* no interlace, no local colormap, no bits in local colormap */ if ((c=bits_per_pixel)<2) c=4; hd[18]=c; /* compression bits_per_pixel */ out.vi_write(hd+8, 11); #if 0 printf("GIFEncodeImage out r r+%u %u; off=%u\n", img->getRlen()*img->getHt(), c+1, img->getRowbeg()-img->getHeadp()); FILE *f=fopen("tjo.dat","wb"); fprintf(f, "P6 %u %u 255\n", img->getWd(), img->getHt()); // fwrite(img->getRowbeg(), 1, img->getRlen()*img->getHt(), f); for (unsigned u=0; ugetRlen()*img->getHt(); u++) { char *p=img->getHeadp()+3* *(unsigned char*)(img->getRowbeg()+u); putc(p[0],f); putc(p[1],f); putc(p[2],f); } #endif i=GIFEncodeImage(out, img->getRowbeg(), img->getRowbeg()+img->getRlen()*img->getHt(), c+1); #if 0 { char buf[500000]; FILE *f=fopen("tjo.dat","rb"); int got=fread(buf, 1, sizeof(buf), f); assert(got==486109); assert(got==img->getRlen()*img->getHt()); i=GIFEncodeImage(out, buf, buf+img->getRlen()*img->getHt(), c+1); } #endif assert(i!=0); /* Write trailer */ hd[0]=0; hd[1]=';'; out.vi_write(hd, 2); } #else #include void out_gif_write(GenBuffer::Writable&, Image::Indexed *) { assert(0); abort(); } #endif sam2p-0.49.2/mapping.hpp0000644000175100017510000001402712212351433013174 0ustar ptspts/* mapping.hpp -- an associative array that maps strings into arbitrary fixed-length values * by pts@fazekas.hu at Sat Mar 23 16:01:55 CET 2002 */ #ifdef __GNUC__ #pragma interface #endif #ifndef MAPPING_HPP #define MAPPING_HPP 1 #include "config2.h" #include "gensi.hpp" class Mapping { /** A mapping is an assicative array whose keys are arbitrary binary strings * and its values are arbirary fixed-length data. The Mapping class is * abstract. The longest key which can be stored in a Mapping::Gen has * length `(slen_t)-3'. The caller must verify that she doesn't try to * call us with a longer string. */ class Gen { public: inline virtual ~Gen() {} /** Returns the length of one data value (same for all values, determined * at construction of Gen). */ inline slen_t getDataLen() const { return datalen; } /** Returns the number of keys currently in this Mapping. */ inline slen_t getLength() const { return len; } /** Returns the number of key positions allocated for this Mapping. This * number may or may not have meaning, depending on the implementation. */ inline slen_t getAlloced() const { return len; } /** * Updates or extends the mapping with the specified key/value pair. * @param data must point to an area of length getDataLen(). That * area will be copied (memcpy()) by set(). * @return true if key previously hasn't existed */ virtual bool set(char const*key, slen_t keylen, char const*data) =0; /** @return the address of the data that corresponds to param * `key', or NULLP if `key' was not found. The returned value is valid * until the next modification (.set(), deletee() methods). */ virtual char* get(char const*key, slen_t keylen) =0; /** * Updates mapping with the specified key/value pair. Leaves it unchanged * if the specified key doesn't exist. Calls get() and memcpy() to do the * job. * @param data must point to an area of length getDataLen(). That * area will be copied by set(). * @return true if key previously hasn't existed */ bool update(char const*key, slen_t keylen, char const*data); /** Calls get to do the job. */ inline bool exists(char const*key, slen_t keylen) { return NULLP!=get(key, keylen); } /** * Deletes the specified `key' from the mapping. * @param data must point to an area of length getDataLen(). That * area will be copied by set(). * @return true if key previously hasn't existed */ virtual bool deletee(char const*key, slen_t keylen) =0; /** The user must ensure that she isn't updating the mapping while walking. * @param key (out) is set to NULLP on empty mapping. */ virtual void getFirst(char const*const*& key, slen_t &keylen, char *& data) =0; /** The user must ensure that she isn't updating the mapping while walking. * @param key (out) is set to NULLP if there are no more elements */ virtual void getNext (char const*const*& key, slen_t &keylen, char *& data) =0; protected: slen_t datalen, len, alloced; }; /** Double hashing. Still abstract. */ class DoubleHash: public Gen { public: inline virtual ~DoubleHash() {} /** If it modifies `scale', then it must modify alloced, may modify minlen * and maxused, and must not modify anything else. If it does not modify * `scale', it must not modify anything else. After it returns, * obj_assert() must hold. Must not copy or (re)allocate memory, * rehashing is not done by vi_scale(). rehash() calls vi_scale(), and * rehash() does the real reallocation. */ virtual void vi_scale() =0; /** First hash function. Must return a value in 0..alloced-1 */ virtual slen_t vi_h1(char const*key, slen_t keylen) =0; /** Second hash function. Must return a value in 1..alloced-1, which is * realatively prime to the value returned by vi_h2(). */ virtual slen_t vi_h2(char const*key, slen_t keylen) =0; /** Destruct and free resources used by data. Called by deletee(). */ virtual void vi_dtor(char *data) =0; /** Called by set() and deletee() ?? */ virtual bool set (char const* key, slen_t keylen, char const*data); virtual char*get (char const* key, slen_t keylen); virtual bool deletee (char const* key, slen_t keylen); virtual void getFirst(char const*const*&key, slen_t &keylen, char *& data); virtual void getNext (char const*const*&key, slen_t &keylen, char *& data); /** Delete everything. */ void clear(); protected: void rehash(); /** @return true */ bool obj_assert(); /** `keylen==(slen_t)-1' indicates a place never used, * `keylen==(slen_t)-2' indicates a deleted place * Before changing the value of NEVER_USED, please update the memset(...) * in rehash(). */ BEGIN_STATIC_ENUM1(slen_t) NEVER_USED=(slen_t)-1, DELETED=(slen_t)-2 END_STATIC_ENUM() // static const slen_t NEVER_USED=(slen_t)-1, DELETED=(slen_t)-2; struct Ary { slen_t keylen; /** data is located at keydata, key is located keydata-datalen */ char *keydata; } *ary; /* The minimum number of keys before rehashing. */ slen_t minlen; /* The maximum number of keys before rehashing. */ slen_t maxused; /* The number of used places. A place is used unless it is NEVER_USED */ slen_t used; /** Used by the implementor of vi_scale. */ unsigned scale; }; /** Simple prime modulus double hashing with a factor of around 1.5 * between `alloced' scales. This class is not abstract anymore. */ class DoubleHash15: public DoubleHash { public: DoubleHash15(slen_t datalen_); virtual ~DoubleHash15(); virtual void vi_scale(); /** @return key % Prime */ virtual slen_t vi_h1(char const*key, slen_t keylen); /** @return (key % (Prime-1))+1 */ virtual slen_t vi_h2(char const*key, slen_t keylen); /** No-op. */ virtual void vi_dtor(char *data); }; public: typedef DoubleHash15 H; }; #endif sam2p-0.49.2/mapping.cpp0000644000175100017510000002645212212351433013174 0ustar ptspts/* * mapping.cpp -- associative array implementations * by pts@fazekas.hu at Fri Mar 15 21:13:47 CET 2002 */ #ifdef __GNUC__ #pragma implementation #endif #include "mapping.hpp" #include "error.hpp" #include #include /* abort() */ /* --- */ bool Mapping::Gen::update(char const*key, slen_t keylen, char const*data) { char *found_data=get(key, keylen); if (found_data==NULLP) return true; memcpy(found_data, data, datalen); return false; } /* --- */ bool Mapping::DoubleHash::obj_assert() { assert(len <= used); assert(minlen <= len); assert(used <= maxused); assert(maxused < alloced); assert(alloced < (slen_t)-2); /* Imp: re-count used and len */ return true; } bool Mapping::DoubleHash::set (char const* key, slen_t keylen, char const*data) { assert(obj_assert()); slen_t h1=vi_h1(key,keylen); assert(h1keylen==NEVER_USED) { added: /* Dat: we shouldn't stop on p->keylen==DELETED */ memcpy(p->keydata=new char[keylen+datalen], data, datalen); memcpy(p->keydata+=datalen, key, p->keylen=keylen); len++; //if (p->keylen==NEVER_USED && used++==maxused) { p->keylen=keylen; rehash(); } // else { p->keylen=keylen; } if (used++==maxused) rehash(); assert(obj_assert()); return true; /* new value added */ } if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) { updated: memcpy(p->keydata-datalen, data, datalen); return false; /* value updated */ } /* Not found for the 1st try. We have to walk. */ slen_t h2=vi_h2(key,keylen); assert(1<=h2 && h1=h2) { h1-=h2; p-=h2; } else { h1+=alloced-h2; p+=alloced-h2; } if (p->keylen==NEVER_USED) goto added; if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) goto updated; } } char*Mapping::DoubleHash::get (char const* key, slen_t keylen) { assert(obj_assert()); slen_t h1=vi_h1(key,keylen); assert(h1keylen==NEVER_USED) return (char*)NULLP; if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) return p->keydata-datalen; /* Not found for the 1st try. We have to walk. */ slen_t h2=vi_h2(key,keylen); assert(1<=h2 && h1=h2) { h1-=h2; p-=h2; } else { h1+=alloced-h2; p+=alloced-h2; } if (p->keylen==NEVER_USED) return (char*)NULLP; if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) return p->keydata-datalen; } } bool Mapping::DoubleHash::deletee (char const* key, slen_t keylen) { /* We must not set `p->keylen=NEVER_USED' in this method because this would * ruin searches jumping on `p', but not coming from `p+h2'. So we just set * `p->keylen=DELETED'. */ assert(obj_assert()); slen_t h1=vi_h1(key,keylen); assert(h1keylen==NEVER_USED) return true; /* key to be deleted does not exist */ if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) { found: vi_dtor(p->keydata-datalen); delete [] (p->keydata-datalen); p->keylen=(slen_t)DELETED; // p->keydata=(char*)NULLP; if (len--==minlen) rehash(); assert(obj_assert()); return false; /* key-value pair deleted */ } /* Not found for the 1st try. We have to walk. */ slen_t h2=vi_h2(key,keylen); assert(1<=h2 && h1=h2) { h1-=h2; p-=h2; } else { h1+=alloced-h2; p+=alloced-h2; } if (p->keylen==(slen_t)NEVER_USED) return true; /* key to be deleted does not exist */ if (p->keylen==keylen && 0==memcmp(p->keydata, key, keylen)) goto found; } } void Mapping::DoubleHash::getFirst(char const*const*& key, slen_t &keylen, char *& data) { assert(obj_assert()); Ary *p=ary, *pend=p+alloced; while (p!=pend && p->keylen>=(slen_t)-2) p++; if (p==pend) { key=(char const*const*)NULLP; } else { key=&p->keydata; data=p->keydata-datalen; keylen=p->keylen; } } void Mapping::DoubleHash::getNext (char const*const*& key, slen_t &keylen, char *& data) { assert(obj_assert()); /* vvv Dat: this operation is safe despite of the fact that it increases * signedness off pointer target type ((char*) -> (Ary*)). */ Ary *p=PTS_align_cast(Ary*, ( (char*)const_cast(key) - ((char*)&((Ary*)0)->keydata-(char*)0) )), *pend=ary+alloced; p++; while (p!=pend && p->keylen>=(slen_t)-2) p++; if (p==pend) { key=(char const*const*)NULLP; } else { key=&p->keydata; data=p->keydata-datalen; keylen=p->keylen; } } void Mapping::DoubleHash::rehash() { unsigned old_scale=scale; slen_t old_alloced=alloced; #ifndef NDEBUG slen_t old_len=len; slen_t old_used=used; #endif Ary *old_ary=ary; // printf("rehash minlen=%u len=%u used=%u maxused=%u alloced=%u\n", minlen, len, used, maxused, alloced); vi_scale(); // printf("scaled minlen=%u len=%u used=%u maxused=%u alloced=%u\n", minlen, len, used, maxused, alloced); // assert( minlen <= len); if (scale==old_scale && used<=maxused) { assert(obj_assert()); return; } Ary *pp=old_ary, *ppend=pp+old_alloced; slen_t calclen=0, calcused=0; ary=new Ary[alloced]; // printf("alloced=%u\n", alloced); memset(ary, '\377', sizeof(Ary)*alloced); /* fill with NEVER_USED */ /* insert the old values to the new hash */ for (; pp!=ppend; pp++) { if (pp->keylen!=NEVER_USED) calcused++; if (pp->keylen<(slen_t)-2) { // printf("%u %u\n", (unsigned char)pp->keydata[0], (unsigned char)pp->keydata[1]); calclen++; slen_t h1=vi_h1(pp->keydata,pp->keylen); assert(h1keylen!=DELETED); if (p->keylen==NEVER_USED) { found: p->keylen=pp->keylen; p->keydata=pp->keydata; continue; } assert(!(p->keylen==pp->keylen && 0==memcmp(p->keydata, pp->keydata, pp->keylen)) && "dupicate key"); /* Not found for the 1st try. We have to walk. */ slen_t h2=vi_h2(pp->keydata,pp->keylen); assert(1<=h2 && h1=h2) { h1-=h2; p-=h2; } else { h1+=alloced-h2; p+=alloced-h2; } assert(p->keylen!=DELETED); if (p->keylen==NEVER_USED) goto found; assert(!(p->keylen==pp->keylen && 0==memcmp(p->keydata, pp->keydata, pp->keylen)) && "dupicate key"); } /* WHILE */ } } /* NEXT */ used=len=calclen; assert(calclen==old_len); assert(calcused==old_used); assert(old_len==len); assert(old_len==used); assert(obj_assert()); delete [] old_ary; } void Mapping::DoubleHash::clear() { assert(obj_assert()); Ary *pp=ary, *ppend=pp+alloced; for (; pp!=ppend; pp++) if (pp->keylen<(slen_t)-2) { vi_dtor(pp->keydata-datalen); /* this is quite fast */ delete [] (pp->keydata-datalen); /* this is really slow for millions of values */ pp->keylen=(slen_t)DELETED; len--; } assert(len==0); if (minlen!=0) rehash(); } /* --- */ static slen_t const d15_primes[]= { 0, 10, 13, 23, 37, 59, 89, 137, 211, 317, 479, 719, 1087, 1637, 2459, 3691, 5557, 8353, 12539, 18839, 28277, 42433, 63659, 95507UL, 143261UL, 214913UL, 322397UL, 483611UL, 725423UL, 1088159UL, 1632259UL, 2448389UL, 3672593UL, 5508913UL, 8263373UL, 12395069UL, 18592631UL, 27888947UL, 41833427UL, 62750147UL, 94125247UL, 141187901UL, 211781873UL, 317672813UL, 476509223UL, 714763843UL, 1072145771UL, 1608218669UL, 2412328031UL, 3618492049UL, #if SIZEOF_SLEN_T>=8 5427738097UL, 8141607167UL, 12212410753UL, 18318616157UL, 27477924239UL, 41216886467UL, 61825329719UL, 92737994593UL, 139106991917UL, 208660487887UL, 312990731839UL, 469486097807UL, 704229146717UL, 1056343720093UL, 1584515580187UL, 2376773370313UL, 3565160055487UL, 5347740083243UL, 8021610124867UL, 12032415187319UL, 18048622780987UL, 27072934171487UL, 40609401257291UL, 60914101885951UL, 91371152828947UL, 137056729243439UL, 205585093865189UL, 308377640797829UL, 462566461196803UL, 693849691795229UL, 1040774537692907UL, 1561161806539393UL, 2341742709809177UL, 3512614064713777UL, 5268921097070759UL, 7903381645606193UL, 11855072468409349UL, 17782608702614033UL, 26673913053921061UL, 40010869580881603UL, 60016304371322423UL, 90024456556983643UL, 135036684835475519UL, 202555027253213279UL, 303832540879819943UL, 455748811319729951UL, 683623216979594929UL, 1025434825469392417UL, 1538152238204088631UL, 2307228357306132983UL, 3460842535959199481UL, 5191263803938799269UL, #endif 0 }; void Mapping::DoubleHash15::vi_scale() { #if 0 // =1); alloced=(d15_primes+2)[--scale]; if (scale>1) minlen=(d15_primes+2)[scale-2]; else if (scale==1) minlen=10; else minlen=0; if (lenmaxused) { assert(used==maxused+1); if ((alloced=(d15_primes+2)[++scale])==0) abort(); /* Imp: better overflow reporting */ if (scale>1) minlen=(d15_primes+2)[scale-2]; else if (scale==1) minlen=10; else minlen=0; // if (len>4; else maxused=(alloced>>4)*15; if (used>maxused) printf("alloced=%u used=%u maxused=%u\n", alloced, used, maxused); #endif /* Dat: we respect only `len', not used. */ /* Imp: make calculation of scale relative to previous one */ scale=0; while (1) { // printf("xscale=%u\n", scale); if (0==(alloced=(d15_primes+2)[scale])) { assert(0); abort(); } /* Imp: better overflow reporting */ if (alloced<=4000U) maxused=(alloced*15)>>4; else maxused=(alloced>>4)*15; /* avoid overflows */ if (len<=maxused) break; /* _not_ used<=maxused, because of rehash() */ scale++; } minlen=(d15_primes)[scale]; // printf("ret alloced=%u used=%u maxused=%u\n", alloced, used, maxused); } slen_t Mapping::DoubleHash15::vi_h1(register char const*key, register slen_t keylen) { register slen_t hval=0, m=alloced; while (keylen--!=0) hval=((hval<<8)+*key++)%m; /* Imp: make this accurate and faster (the `%' operation is rather slow) */ return hval; } slen_t Mapping::DoubleHash15::vi_h2(char const*key, slen_t keylen) { register slen_t hval=0, m=alloced-1; while (keylen--!=0) hval=((hval<<8)+*key++)%m; /* Imp: make this accurate and faster (the `%' operation is rather slow) */ return hval+1; } void Mapping::DoubleHash15::vi_dtor(char *) {} Mapping::DoubleHash15::DoubleHash15(slen_t datalen_) { ary=new Ary[alloced=(d15_primes+2)[scale=0]]; memset(ary, '\377', sizeof(Ary)*alloced); /* fill with NEVER_USED */ datalen=datalen_; len=used=minlen=0; maxused=(alloced>>4)*15; } Mapping::DoubleHash15::~DoubleHash15() { minlen=0; clear(); delete [] ary; } /* __END__ */ sam2p-0.49.2/contrib/aprea.ps0000644000175100017510000000166212211371426014130 0ustar ptspts% anti-setpagedevice preamble by pts@inf.bme.hu in 2002.03.15 userdict begin 1 dict dup /ImagingBBox null put /setpagedevice where{ pop setpagedevice /setpagedevice{% -dict:pagedevice- sp - dup length dict copy dup /PageSize undef dup /ImagingBBox undef dup /HWResolution undef 0}% changed to //setpagedevice in next line dup dup length 1 sub 3 index load put bind 1 index where{dup wcheck{3 1 roll put}{pop def}ifelse}{def}ifelse % ^^^ instead of ef' -- redef at the appropriate place }if [/11x17/a3/a4/a4small/b5/ledger/legal/letter/lettersmall/note /a0/a1/a2/a5/a6/a7/a8/a9/a10/b0/b1/b2/b3/b4/b5/c0/c1/c2/c3/c4 /c5/c6/archE/archD/archC/archB/archA/flsa/flse/halfletter /tabloid/csheet/dsheet/esheet/executivepage/com10envelope /monarchenvelope/c5envelope/dlenvelope/folio/quarto]{ dup where{dup wcheck{exch{}put}{pop{}def}ifelse}{pop}ifelse % ^^^ make these ops a no-op ({}) if they exist }forall end% userdictsam2p-0.49.2/contrib/sam2p.tk0000644000175100017510000014454012211371426014061 0ustar ptspts#!/usr/bin/wish -f # # sam2p.tk # by pts@fazekas.hu at Sat Apr 6 13:14:37 CEST 2002 # # OK: confirm quit # Imp: don't update widgets when error in job file # Imp: newline mangling when loading/saving files # Imp: /DCT, ability to type literal MiniPS code to an `entry' # Imp: Perl parser should signal error on etc. # Imp: B2Press + Move + B2Release; inserts twice # Imp: initial `focus' # Imp: default values # Imp: tk-start with sh # Imp: to center of the resized window # Imp: tooltips (mouse button 2, 3) # Imp: less vertical padding # Imp: really detect what kind of -*-fixed fonts we have # Dat: TCL 8.0 doesn't have `string equal' # Dat: never do `.text mark set sel.first 1.5', beacuse this will override tag `sel' # Dat: `entry' widgets don't accept "insert + 1 chars" as a character index # Dat: tag-parser treats comments as legal tokens # Dat: matches , does not. # Dat: is mouse motion event over the sub-window # Dat: and is an event sent when # SUXX: Tcl: 8.0 doesn't have [string map ...] # SUXX: Tk: radio and checkbuttons cannot be made smaller or larger # SUXX: Tk: color for -relief cannot be specified # SUXX: Tk: on UNIX, Tk converts "Times New Roman" to "times" unless specified as "-*-times new roman-*-*-*-*-*-*-*-*-*-*-iso8859-1" # SUXX: Tk: .text cursor width cannot be extended to the right only (not to the left) # SUXX: Tk: .text cannot show the last line on the top unless first==last # SUXX: Tk bug: echo `bind . {put got}' | wish # Test: 1. press button2 2. move mouse 3. release button 4. move mouse # `got' is printed twice. Strange: works fine with button 1 and 3. # Even the following doesn't help: # echo `bind . {put got}' | wish # Even event parameters are useless to distinguish normal and duplicate # events. This is a bug even on all other X11 clients. May be a GPM bug # or an xlib bug?? # puts [file type alma] proc pts_PATH_sep {} { global tcl_platform if {0==[string compare windows $tcl_platform(platform)]} {return ;} return : # Imp: `macintosh' } proc pts_read_ok {filename} { if {0==[string length $filename]} {return 0} if {[catch {set t [file type $filename]}]} { if {[catch {set t [file type [file dirname $filename]]}]} {return !d} return !e } if {0!=[string compare $t file]} {return !f} if {![file readable $filename]} {return !r} return OK } proc pts_write_ok {filename} { if {0==[string length $filename]} {return 0} if {[catch {set t [file type $filename]}]} { if {[catch {set t [file type [set dir [file dirname $filename]]]}]} {return !d} if {0==[string compare $t directory] && [file writable $dir]} {return ++} return !dw } if {0!=[string compare $t file]} {return !f} if {![file writable $filename]} {return !w} return OK } proc pts_direct_bindtags {w} { #** Moves all binds associated with widget $w to directly widget itself. ## Half idea: bindtags $w "$w [bindtags $w]" # Dat: this assumes [lindex [bindtags $w] 0] == $w foreach tag [bindtags $w] { if {0!=[string compare $tag $w]} { foreach evtseq [bind $tag] { bind $w $evtseq [bind $w $evtseq]\n[bind $tag $evtseq] } } } bindtags $w $w } proc pts_readonly {w} { #** @param $w text or entry #** Makes the specified widget read-only. [$w configure -state disabled] #** is not OK, because it makes the insertion cursor invisible. pts_direct_bindtags $w # SUXX: cannot be avoided. Example: we must disable (typing letters), # but allow bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w break bind $w <> break bind $w <> break bind $w <> break bind $w <> break } proc pts_readonly_color {w} { #** Calls [pts_readonly $w], and sets widget colors etc. to make the user #** see that it's a read-only widget. pts_readonly $w $w configure -background [[winfo toplevel $w] cget -background] -relief sunken } proc pts_listrev {list} { # by pts@fazekas.hu at Sun Apr 21 21:08:20 CEST 2002 set i [llength $list] set ret {} while {$i>0} {incr i -1; lappend ret [lindex $list $i]} return $ret } proc pts_listrev1 {list} { #** Chops the 1st element of list, and returns the reverse of the rest. # by pts@fazekas.hu at Sun Apr 21 21:08:20 CEST 2002 set i [llength $list] set ret {} while {$i>1} {incr i -1; lappend ret [lindex $list $i]} return $ret } ## puts [pts_listrev {1 2 {3 4}}]; exit set pts_unknown_font [font actual ..unknown..] proc pts_has_font {f} { # by pts@fazekas.hu at Sat Apr 6 16:26:24 CEST 2002 # This is rather dirty, because there is no clean way to test whether a font # exists in Tk. #** return 1 or 0 global pts_unknown_font if {0==[string compare fixed $f]} {return 1} if {[string match -*-fixed-* $f]} {return 1} ;# Imp: first `*' shouldn't contain `-' # Dat: pts_unknown_font is `fixed' on UNIX systems... if {0==[string compare $pts_unknown_font [font actual $f]]} {return 0} return 1 } proc pts_last_font {first args} { #** @param first,args list of font names (suitable arg for `-font' of widgets) #** @return the last font name that is available for {set i [llength $args]} {$i>0} {} { incr i -1 if {[pts_has_font [set f [lindex $args $i]]]} {return $f} } return $first } proc pts_fix_shift_tab {} { # by pts@fazekas.hu at Sat Apr 6 15:22:58 CEST 2002 set tmp [bind all ] ## puts $tmp if {[string length $tmp]==0} {set tmp {tkTabToWindow [tk_focusPrev %]}} bind all $tmp catch {bind all $tmp} # ^^^ Dat: catch is here because some systems don't have ISO_Left_Tab } proc pts_fix_one_tab {wPath} { # by pts@fazekas.hu at Sat Apr 6 15:38:43 CEST 2002 # pts_fix_shift_tab() should be called. bind $wPath "[bind all ]; break" bind $wPath "[bind all ]; break" bind $wPath "[bind all ]; break" } proc pts_tag_set_first {w tagName index} { if {[$w tag nextrange $tagName 1.0 end] != ""} { if {[$w compare $index < $tagName.last]} { if {[$w compare $index < $tagName.first]} \ {$w tag add $tagName $index $tagName.first} \ {$w tag remove $tagName $tagName.first $index} } { set tmp [$w index $tagName.last] $w tag remove $tagName 1.0 end $w tag add $tagName $tmp $index } } } proc pts_tag_set_last {w tagName index} { if {[$w tag nextrange $tagName 1.0 end] != ""} { if {[$w compare $index > $tagName.first]} { if {[$w compare $index > $tagName.last]} \ {$w tag add $tagName $tagName.last $index} \ {$w tag remove $tagName $index $tagName.last} } { set tmp [$w index $tagName.first] $w tag remove $tagName 1.0 end $w tag add $tagName $index $tmp } } } proc pts_paste {w} {catch { set tmp [$w index insert] $w insert insert [selection get -displayof $w -selection CLIPBOARD] $w tag remove sel 0.1 end $w tag add sel $tmp insert }} proc pts_text_insert_newline {w autoindent} { #** Doesn't respect overstrike mode (neither does Turbo Pascal). #** Does auto-indenting of spaces and tabs. if {[$w cget -state] == "disabled"} {return} if $autoindent { if {![string length [set tmp [$w search -regexp "\[^ \t]" {insert linestart} {insert lineend}]]]} {set tmp "insert lineend"} $w insert insert \n[$w get {insert linestart} $tmp] } {$w insert insert \n} $w see insert } proc pts_text_autoindent {w bool} { if $bool {} ;# early error message if bool is malformed bind $w "pts_text_insert_newline %W $bool; break" } # vvv Overriding text.tcl, so we won't clobber the visible selection. proc tkTextInsert {w s} { if {($s == "") || ([$w cget -state] == "disabled")} {return} if {[string match "* 1" [bind $w ]]} { # vvv in overstrike mode, overstrike only in the middle of the line if {[$w compare insert != "insert lineend"]} {$w delete insert} } $w insert insert $s; $w see insert } #proc pts_text_insert {w s overstrike} { # if {($s == "") || ([$w cget -state] == "disabled")} {return} # set tmp [$w index insert] # # vvv in overstrike mode, overstrike only in the middle of the line # if {$overstrike && [$w compare insert != "insert lineend"]} {$w delete insert} # $w insert insert $s; $w see insert #} proc pts_text_overstrike {w bool} { #puts [$w configure -insertontime] #puts [$w configure -insertofftime] if {$bool} {$w configure -insertofftime 0} \ {$w configure -insertofftime [lindex [$w configure -insertofftime] 3]} # Dat: we cannot override the widget's method here, because then # we won't be able to receive cursor movement etc. events, see docs in # bindtags(n) and bind(n). So support must be built into tkTextInsert, # since `bind Text {tkTextInsert %W %A}' is the default. # bind Text "pts_text_insert %W %A $bool; break ;#alma" focus .; focus $w ;# trick to avoid non-reblinking bug in Tk8.0 Linux. } proc pts_text_toggle_overstrike {w bool} { if {$bool} {set bool 0} {set bool 1} pts_text_overstrike $w $bool bind $w "pts_text_toggle_overstrike %W $bool" } proc pts_text_auto_overstrike {w bool} { #** Sets overstrike mode, and binds Insert to do the switching. A #** non-blinking cursor indicates overstrike mode. (Tk is too stupid to draw #** a block cursor.) #** @param w a text widget pts_text_overstrike $w $bool bind $w "pts_text_toggle_overstrike %W $bool" } # redefine tkScrollButtonDown, so it won't `sunken' the slider # (se tcl8.2/scrlbar.tcl) proc tkScrollButtonDown {w x y} { global tkPriv set tkPriv(relief) [$w cget -activerelief] if {0==[string compare slider [set element [$w identify $x $y]]]} { tkScrollStartDrag $w $x $y } else { $w configure -activerelief sunken tkScrollSelect $w $element initial } } proc tkScrollButton2Down {w x y} { global tkPriv set element [$w identify $x $y] if {0==[string compare $element arrow1]||0==[string compare $element arrow2]} { tkScrollButtonDown $w $x $y return } tkScrollToPos $w [$w fraction $x $y] set tkPriv(relief) [$w cget -activerelief] update idletasks # $w configure -activerelief sunken $w activate slider tkScrollStartDrag $w $x $y } option add *Dialog.msg.wrapLength 3i widgetDefault proc pts_message_box {args} { global sa_normfont #** similar to tkMessageBox; ignores platform's native MessageBox support. global tkPriv tcl_platform set w tkPrivMsgBox upvar #0 $w data # # The default value of the title is space (" ") not the empty string # because for some window managers, a # wm title .foo "" # causes the window title to be "foo" instead of the empty string. # set specs { {-default "" "" ""} {-icon "" "" "info"} {-message "" "" ""} {-parent "" "" .} {-title "" "" " "} {-type "" "" "ok"} } tclParseConfigSpec $w $specs "" $args if {[lsearch {info warning error question} $data(-icon)] == -1} { error "invalid icon \"$data(-icon)\", must be error, info, question or warning" } if {$tcl_platform(platform) == "macintosh"} { if {$data(-icon) == "error"} { set data(-icon) "stop" } elseif {$data(-icon) == "warning"} { set data(-icon) "caution" } elseif {$data(-icon) == "info"} { set data(-icon) "note" } } if {![winfo exists $data(-parent)]} { error "bad window path name \"$data(-parent)\"" } switch -- $data(-type) { abortretryignore { set buttons { {abort -width 6 -text Abort -under 0} {retry -width 6 -text Retry -under 0} {ignore -width 6 -text Ignore -under 0} } } ok { set buttons { {ok -width 6 -text OK -under 0} } if {$data(-default) == ""} { set data(-default) "ok" } } okcancel { set buttons { {ok -width 6 -text OK -under 0} {cancel -width 6 -text Cancel -under 0} } } retrycancel { set buttons { {retry -width 6 -text Retry -under 0} {cancel -width 6 -text Cancel -under 0} } } yesno { set buttons { {yes -width 6 -text Yes -under 0} {no -width 6 -text No -under 0} } } yesnocancel { set buttons { {yes -width 6 -text Yes -under 0} {no -width 6 -text No -under 0} {cancel -width 6 -text Cancel -under 0} } } default { error "invalid message box type \"$data(-type)\", must be abortretryignore, ok, okcancel, retrycancel, yesno or yesnocancel" } } if {[string compare $data(-default) ""]} { set valid 0 foreach btn $buttons { if {![string compare [lindex $btn 0] $data(-default)]} { set valid 1 break } } if {!$valid} { error "invalid default button \"$data(-default)\"" } } # 2. Set the dialog to be a child window of $parent # # if {[string compare $data(-parent) .]} { set w $data(-parent).__tk__messagebox } else { set w .__tk__messagebox } # 3. Create the top-level window and divide it into top # and bottom parts. catch {destroy $w} toplevel $w -class Dialog wm title $w $data(-title) wm iconname $w Dialog wm protocol $w WM_DELETE_WINDOW { } wm transient $w $data(-parent) if {$tcl_platform(platform) == "macintosh"} { unsupported1 style $w dBoxProc } frame $w.bot pack $w.bot -side bottom -fill both frame $w.top pack $w.top -side top -fill both -expand 1 if {$tcl_platform(platform) != "macintosh"} { $w.bot configure -relief raised -bd 1 $w.top configure -relief raised -bd 1 } # 4. Fill the top part with bitmap and message (use the option # database for -wraplength so that it can be overridden by # the caller). label $w.msg -justify left -text $data(-message) #catch {$w.msg configure -font \ # -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-* #} pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m if {$data(-icon) != ""} { label $w.bitmap -bitmap $data(-icon) pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m } # 5. Create a row of buttons at the bottom of the dialog. set i 0 foreach but $buttons { set name [lindex $but 0] set opts [lrange $but 1 end] if {![string compare $opts {}]} { # Capitalize the first letter of $name set capName \ [string toupper \ [string index $name 0]][string range $name 1 end] set opts [list -text $capName] } eval button $w.$name $opts -font $sa_normfont -borderwidth 1 -pady 2 -underline 0 -command [list "set tkPriv(button) $name"] if {![string compare $name $data(-default)]} { $w.$name configure -default active } pack $w.$name -in $w.bot -side left -expand 1 \ -padx 3m -pady 2m # create the binding for the key accelerator, based on the underline # set underIdx [$w.$name cget -under] if {$underIdx >= 0} { set key [string index [$w.$name cget -text] $underIdx] bind $w "$w.$name invoke" bind $w "$w.$name invoke" } incr i } # 6. Create a binding for on the dialog if there is a # default button. if {[string compare $data(-default) ""]} { bind $w "tkButtonInvoke $w.$data(-default)" } # 7. Withdraw the window, then update all the geometry information # so we know how big it wants to be, then center the window in the # display and de-iconify it. wm withdraw $w update idletasks set x [expr {[winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \ - [winfo vrootx [winfo parent $w]]}] set y [expr {[winfo screenheight $w]/2 - [winfo reqheight $w]/2 \ - [winfo vrooty [winfo parent $w]]}] wm geom $w +$x+$y wm deiconify $w # 8. Set a grab and claim the focus too. set oldFocus [focus] set oldGrab [grab current $w] if {$oldGrab != ""} { set grabStatus [grab status $oldGrab] } grab $w if {[string compare $data(-default) ""]} { focus $w.$data(-default) } else { focus $w } # 9. Wait for the user to respond, then restore the focus and # return the index of the selected button. Restore the focus # before deleting the window, since otherwise the window manager # may take the focus away so we can't redirect it. Finally, # restore any grab that was in effect. tkwait variable tkPriv(button) catch {focus $oldFocus} destroy $w if {$oldGrab != ""} { if {$grabStatus == "global"} { grab -global $oldGrab } else { grab $oldGrab } } return $tkPriv(button) } # --- proc sa_radio {framePath variable value labelCaption args} { global $variable sa_normfont # Imp: use -text set $variable "" frame $framePath lappend args -variable $variable -value $value -indicatoron true -borderwidth 1 # lappend args -value $value -indicatoron true -borderwidth 1 eval "radiobutton $framePath.r $args" $framePath.r configure -activebackground [$framePath.r cget -background] label $framePath.l -text $labelCaption -font $sa_normfont ;# Imp: Why doesn't -anchor work?? bind $framePath.l "$framePath.r invoke" pack $framePath.r $framePath.l -side left # bind $framePath.r {tkTabToWindow [tk_focusPrev %W]} } #proc sa_radio_pack {framePath} {} proc sa_check {wPath variable labelCaption args} { global sa_boldfont # Imp: clicking to the right from the caption shouldn't have effect lappend args -font $sa_boldfont -text $labelCaption -anchor w -borderwidth 1 -variable $variable eval "checkbutton $wPath $args" $wPath configure -activebackground [$wPath cget -background] } proc sa_check_update {wPath variable labelCaption} { sa_check $wPath $variable $labelCaption -command "update_check $variable $wPath" } proc sa_int {framePath variable labelCaption entryWidth args} { # Imp: clicking to the right from the caption shouldn't have effect # Imp: check for int... global sa_normfont sa_boldfont frame $framePath ;# may already exist?? label $framePath.l -text $labelCaption -font $sa_boldfont lappend args -relief sunken -width $entryWidth -font $sa_normfont \ -borderwidth 1 -foreground black -background white \ -selectbackground yellow -selectforeground black -selectborderwidth 0 eval "entry $framePath.i $args" pack $framePath.l $framePath.i -side left # $framePath configure -activebackground [$framePath cget -background] } proc sa_w_text {args} { lappend args -relief solid -highlightcolor gray30 \ -borderwidth 1 -foreground black -background white \ -selectbackground gray85 -selectforeground black -selectborderwidth 0 eval "text $args" } proc sa_w_entry {args} { lappend args -relief sunken -borderwidth 1 -foreground black -background white \ -selectbackground yellow -selectforeground black -selectborderwidth 0 eval "entry $args" } set sa_frame 0 proc sa_vframe {parentPath} { #** Creates and packs vertical frame, which is 5 pixel high global sa_frame set w $parentPath.saf[incr sa_frame] frame $w -height 5 -width 1 pack $w -fill x } # vvv The mouse must be used to insert visible selection (of other apps) bind Text {} bind Text {} bind Text {} # puts T[bind Text]T # vvv allow the well-known (almost indrustry standard) Windows/Borland/GTK # cliboard key bindings on all platforms event add <> event add <> event add <> # event add <> # Dat: <> is normal, paste, which requires prior # . Works across applications. # Dat: <> is xterm/netscape-like paste, which does not # require . Also works across applications. # vvv this <> deletes current selection even on UNIX; but we don't like that # bind Text <> {catch {%W delete sel.first sel.last}; catch {%W insert insert [selection get -displayof %W -selection CLIPBOARD]}} # vvv this <> leaves visible selection intact # bind Text <> {catch {%W insert insert [selection get -displayof %W -selection CLIPBOARD]}} # vvv this <> sets visible selection to the newly pasted data bind Text <> {pts_paste %W} # vvv our <> doesn't move the cursor (like xterm, unlike Motif) bind Text <> {pts_text_paste_selection %W %x %y} bind Text {} bind Text {} # bind Text {puts evt; pts_text_paste_selection %W %x %y} #catch { #event delete <> #} #catch { #event add <> #event add <> #} # puts EI[event info <>] # puts A[event info <>]BN proc pts_text_paste_selection {w x y} { #** If has focus, than pastes visible selection to the unchanged cursor #** position; otherwise claims focus and sets cursor position to mouse. if {0==[string compare $w [focus -displayof $w]]} { catch {$w insert insert [selection get -displayof $w]} if {0==[string compare normal [$w cget -state]]} {focus $w} } {$w mark set insert [tkTextClosestGap $w $x $y]; focus $w} } # vvv overrides text.tcl, doesn't clobber the selection. bind Text <1> {tkTextButton1 %W %x %y} proc ptsTextDelLn W { # puts [%W index {insert linestart}]..[%W index {insert lineend + 1 chars}] if {[$W compare {insert lineend + 1 chars} == end]} { # in the last line must not move the cursor $W delete {insert linestart} {insert lineend} } { $W delete {insert linestart} {insert lineend + 1 chars} } } # vvv Overriding text.tcl, so we won't clobber the visible selection when moving # the cursor or just inserting proc tkTextSetCursor {w pos} { if {[$w compare $pos == end]} {set pos {end - 1 chars}} $w mark set insert $pos # $w tag remove sel 1.0 end $w see insert } # vvv Overriding text.tcl, so PageUp and PageDown will jump within the page. proc tkTextScrollPages {w count} { set tmp [expr {([$w cget -height]-1)*$count}] $w yview scroll $tmp units return "insert + $tmp lines" } # vvv Overrides text.tcl with Turbo Pascal-style Shift+Arrow selection: # Shift+Movement-key, when moved _from_ either end of the selection, # updates that end appropriately. Otherwise, it clobbers the selection, # and creates a new selection from the current `insert' position to the # position the cursor is moved to. proc tkTextKeySelect {w newIndex} { # puts "[$w index insert] -> [$w index $newIndex] ([$w index end])" if {[$w compare end == $newIndex]} {set newIndex "end - 1 char"} $w mark set anchor insert if {[$w tag nextrange sel 1.0 end] == ""} { if {[$w compare $newIndex < insert]} {$w tag add sel $newIndex insert} {$w tag add sel insert $newIndex} } { # already have a selection # puts "a=[$w index sel.first]-[$w index sel.last] i=[$w index insert]" if {[$w compare insert == sel.first]} {pts_tag_set_first $w sel $newIndex} \ elseif {[$w compare insert == sel.last]} {pts_tag_set_last $w sel $newIndex} \ { $w tag remove sel 1.0 end if {[$w compare $newIndex < insert]} {$w tag add sel $newIndex insert} {$w tag add sel insert $newIndex} } } $w mark set insert $newIndex; $w see insert update idletasks # puts "[$w tag ranges sel]" # puts "b=[$w index sel.first]-[$w index sel.last] i=[$w index insert]" } # Imp: ^K B: Control-Space, ^K K: Control-Shift-Space bind Text {ptsTextDelLn %W} bind Text [bind Text ] bind Text {if {[%W compare {insert + 1 chars} != end]} {%W delete insert}} # ^^^ ensures that pressing `Delete' on the last empty line is a no-op bind Text [bind Text ] # ^^^ don't clobber visible selection bind Text {if {[%W compare insert != 1.0]} {%W delete insert-1c; %W see insert}} # ^^^ don't clobber visible selection proc pts_entry_Delete {w} { set i 0 set j -1 set k -1 set i [$w index insert] catch {set j [$w index sel.first]} catch {set k [$w index sel.last]} if {0==[string compare $i $j] || 0==[string compare $i $k]} \ {$w delete sel.first sel.last} \ {$w delete insert} } bind Entry {} bind Entry {} # vvv Overrides entry.tcl, so it won't clobber the selection. bind Entry {pts_entry_Delete %W} # vvv Overrides entry.tcl, so it won't clobber the selection. bind Entry {pts_entry_Delete %W} bind Entry {%W insert insert \t} # vvv Overrides entry.tcl, so it won't clobber the selection. proc tkEntrySetCursor {w pos} {$w icursor $pos; tkEntrySeeInsert $w} # vvv Overrides entry.tcl, so it won't clobber the selection. proc tkEntryInsert {w s} {if {[string length $s]} { $w insert insert $s tkEntrySeeInsert $w }} # vvv Overrides entry.tcl with Turbo Pascal look and feel. proc tkEntryKeySelect {w new} { if {[$w selection present]} { set i [$w index insert] if {[$w index sel.first]==$i} {$w selection from sel.last} \ elseif {[$w index sel.last]==$i} {$w selection from sel.first} \ {$w selection from insert} } {$w selection from insert} $w selection to $new $w icursor $new # tkEntrySeeInsert will be called by our caller. } # vvv Overrides entry.tcl, so it won't clobber the selection. proc tkEntryBackspace w { set x [expr {[$w index insert] - 1}] if {$x >= 0} {$w delete $x} if {[$w index @0] >= [$w index insert]} { set range [$w xview] set left [lindex $range 0] set right [lindex $range 1] $w xview moveto [expr {$left - ($right - $left)/2.0}] } } proc pts_entry_paste_selection {w x y} { #** If has focus, than pastes visible selection to the unchanged cursor #** position; otherwise claims focus and sets cursor position to mouse. if {0==[string compare $w [focus -displayof $w]]} { catch {$w insert insert [selection get -displayof $w]} if {0==[string compare normal [$w cget -state]]} {focus $w} } {$w icursor [tkEntryClosestGap $w $x]; focus $w} } bind Entry <> {pts_entry_paste_selection %W %x %y} bind Entry {} ;# already OK. # vvv override tk.tcl, so it won't select the whole Entry when tab is pressed} proc tkTabToWindow w {focus $w} # --- # vvv Imp: improve this on Windows set sa_normfont [pts_last_font \ system variable helvetica \ arial {arial -12 normal} \ -adobe-helvetica-medium-r-normal--11-*-100-100-*-*-iso8859-* \ -adobe-helvetica-medium-r-normal--12-*-75-75-*-*-iso8859-* \ sansserif dialog}] set sa_boldfont [pts_last_font \ sansserif system variable helvetica \ arial {arial -12 bold} \ -adobe-helvetica-bold-r-normal--12-*-75-75-*-*-iso8859-1 \ -adobe-helvetica-bold-r-normal--11-80-100-100-p-60-iso8859-1 \ dialogb] set sa_fixfont [pts_last_font \ fixed systemfixed fixsedsys monospaced monospace \ -*-fixed-*-*-*--13-*-*-*-*-*-iso8859-1 \ -misc-fixed-medium-r-semicondensed--13-*-75-75-*-*-iso8859-1 \ 6x13] # puts sa_normfont=$sa_normfont; puts sa_boldfont=$sa_boldfont # Dat: 100 DPI, 14-point Helvetica is too large, 11-point is somewhat small option add *Dialog.msg.font $sa_normfont ;# respected option add *Dialog.Button*font $sa_boldfont ;# respected wm title . {sam2p Job Editor} set tk_StrictMotif 0 pts_fix_shift_tab # . configure -bg red frame .gtop set g .gtop.g0 frame $g label $g.lFileFormat -text FileFormat -anchor w -font $sa_boldfont sa_radio $g.fPSL1 FileFormat PSL1 "PS L1" -command {update_radio FileFormat PSL1} sa_radio $g.fPSLC FileFormat PSLC "PS LC" -command {update_radio FileFormat PSLC} sa_radio $g.fPSL2 FileFormat PSL2 "PS L2" -command {update_radio FileFormat PSL2} sa_radio $g.fPSL3 FileFormat PSL3 "PS L3" -command {update_radio FileFormat PSL3} sa_radio $g.fPDFB10 FileFormat PDFB1.0 "PDF B 1.0" -command {update_radio FileFormat PDFB1.0} sa_radio $g.fPDFB12 FileFormat PDFB1.2 "PDF B 1.2" -command {update_radio FileFormat PDFB1.2} sa_radio $g.fPDF10 FileFormat PDF1.0 "PDF 1.0" -command {update_radio FileFormat PDF1.0} sa_radio $g.fPDF12 FileFormat PDF1.2 "PDF 1.2" -command {update_radio FileFormat PDF1.2} sa_radio $g.fGIF89a FileFormat GIF89a "GIF 89a" -command {update_radio FileFormat GIF89a} sa_radio $g.fEmpty FileFormat Empty Empty -command {update_radio FileFormat Empty} sa_radio $g.fMeta FileFormat Meta Meta -command {update_radio FileFormat Meta} sa_radio $g.fPNM FileFormat PNM PNM -command {update_radio FileFormat PNM} sa_radio $g.fPAM FileFormat PAM PAM -command {update_radio FileFormat PAM} sa_radio $g.fPIP FileFormat PIP PIP -command {update_radio FileFormat PIP} sa_radio $g.fJPEG FileFormat JPEG JPEG -command {update_radio FileFormat JPEG} sa_radio $g.fTIFF FileFormat TIFF TIFF -command {update_radio FileFormat TIFF} sa_radio $g.fPNG FileFormat PNG PNG -command {update_radio FileFormat PNG} pack $g.lFileFormat -fill x pack $g.fPSL1 $g.fPSLC $g.fPSL2 $g.fPSL3 $g.fPDFB10 $g.fPDFB12 $g.fPDF10 $g.fPDF12 $g.fGIF89a \ $g.fEmpty $g.fMeta $g.fPNM $g.fPAM $g.fPIP $g.fJPEG $g.fTIFF $g.fPNG -fill x frame $g.pFileFormat -height 5 -width 1 pack $g.pFileFormat -fill x set g .gtop.g1 frame $g label $g.lSampleFormat -text SampleFormat -anchor w -font $sa_boldfont sa_radio $g.fOpaque SampleFormat Opaque Opaque -command {update_radio SampleFormat Opaque} sa_radio $g.fTransparent SampleFormat Transparent Transparent -command {update_radio SampleFormat Transparent} sa_radio $g.fGray1 SampleFormat Gray1 "Gray 1" -command {update_radio SampleFormat Gray1} sa_radio $g.fIndexed1 SampleFormat Indexed1 "Indexed 1" -command {update_radio SampleFormat Indexed1} sa_radio $g.fMask SampleFormat Mask Mask -command {update_radio SampleFormat Mask} sa_radio $g.fTransparent2 SampleFormat Transparent2 "Transparent 2" -command {update_radio SampleFormat Transparent2} sa_radio $g.fGray2 SampleFormat Gray2 "Gray 2" -command {update_radio SampleFormat Gray2} sa_radio $g.fIndexed2 SampleFormat Indexed2 "Indexed 2" -command {update_radio SampleFormat Indexed2} sa_radio $g.fTransparent4 SampleFormat Transparent4 "Transparent 4" -command {update_radio SampleFormat Transparent4} sa_radio $g.fRGB1 SampleFormat RGB1 "RGB 1" -command {update_radio SampleFormat Rgb1} sa_radio $g.fGray4 SampleFormat Gray4 "Gray 4" -command {update_radio SampleFormat Gray4} sa_radio $g.fIndexed4 SampleFormat Indexed4 "Indexed 4" -command {update_radio SampleFormat Indexed4} sa_radio $g.fTransparent8 SampleFormat Transparent8 "Transparent 8" -command {update_radio SampleFormat Transparent8} sa_radio $g.fRgb2 SampleFormat Rgb2 "RGB 2" -command {update_radio SampleFormat Rgb2} sa_radio $g.fGray8 SampleFormat Gray8 "Gray 8" -command {update_radio SampleFormat Gray8} sa_radio $g.fIndexed8 SampleFormat Indexed8 "Indexed 8" -command {update_radio SampleFormat Indexed8} sa_radio $g.fRgb4 SampleFormat Rgb4 "RGB 4" -command {update_radio SampleFormat Rgb4} sa_radio $g.fRgb8 SampleFormat Rgb8 "RGB 8" -command {update_radio SampleFormat Rgb8} pack $g.lSampleFormat -fill x pack $g.fOpaque $g.fTransparent $g.fGray1 $g.fIndexed1 $g.fMask $g.fTransparent2 $g.fGray2 $g.fIndexed2 $g.fTransparent4 \ $g.fRGB1 $g.fGray4 $g.fIndexed4 $g.fTransparent8 $g.fRgb2 $g.fGray8 \ $g.fIndexed8 $g.fRgb4 $g.fRgb8 -fill x frame $g.pSampleFormat -height 5 -width 1 pack $g.pSampleFormat -fill x set g .gtop.g2 frame $g proc find_val_range {key} { #** @param key for example "/Compression", "/InputFile", of type tKey #** @return "" or [beg end] abs.index of the value associated with that key #** (may span multiple tokens) global jtw ;# text widget containing the tagged job file set end 1.0 while {[llength [set lst [$jtw tag nextrange tKey $end]]]} { set beg [lindex $lst 0] set end [lindex $lst 1] ##puts "key=<[$jtw get $beg $end]>" set ikey [$jtw get $beg $end] if {0==[string compare $ikey $key]} { ## puts prev=[$jtw tag prevrange tAny $end] set lst [$jtw tag prevrange tAny $end] if {0!=[llength $lst] && [$jtw compare [lindex $lst 0] < $end] && [$jtw compare $end < [lindex $lst 1]]} { set lst [list $end [lindex $lst 1]] } { if {![llength [set lst [$jtw tag nextrange tAny $end]]]} return "" # ^^^ Imp: show error: found, but no value } ##puts "lst=$lst end=$end." ##eval "puts \[$jtw get $lst\]" if {2!=[llength [set tns [$jtw tag names [lindex $lst 0]]]]} return "" # ^^^ Imp: show error: found, but untagged value ##puts LT=[lindex $tns 1]:$tns: if {![llength [set lst [$jtw tag nextrange [lindex $tns 1] $end]]]} return "" # ^^^ This trick is used to find only a single tag. A single tag often # means a single PostScript token, but -- for example `(a)(b)' and # `[]' contain a single tag, but two tokens. # Imp: show better error message set white [$jtw get $end [lindex $lst 0]] ##puts aaa($white) if {[regexp "\[^\\000\011-\015 ]" $white]} return "" # ^^^ Imp: show error: key and value separated by non-whitespace ##puts bbb set beg [lindex $lst 0] set end [lindex $lst 1] set val [$jtw get $beg $end] set openc [expr {2*[string match <<* $val]+[string match \\\[* $val]}] ;# ] ## puts "openc=$openc; val=<$val>" if {$openc} { set end "$beg + $openc chars" set openc 1 while {1} { if {![llength [set lst [$jtw tag nextrange tBrac $end]]]} return "" # ^^^ Imp: show error: unclosed >> set val [$jtw get [lindex $lst 0] [lindex $lst 1]] if {[string match <<* $val]} {incr openc; set end 2} \ elseif {[string match \\\[* $val]} {incr openc; set end 1} \ elseif {[string match >>* $val]} {incr openc -1; set end 2} \ elseif {[string match \]* $val]} {incr openc -1; set end 1} \ {return ""} # ^^^ Imp: show error: invalid tBrac set end "[lindex $lst 0] + $end chars" if {!$openc} {return "$beg [$jtw index $end]"} } } # puts "val=<$val>" # return [$jtw get $beg $end] return $lst } } return "" } proc update_psval {key newval} { #** return oldval or "" global jtw if {![llength [set found [find_val_range $key]]]} {return ""} set oldval [eval "$jtw get $found"] eval "$jtw delete $found" set found [lindex $found 0] if {[string match /* $newval]} {$jtw insert $found $newval {tAny tNameval}} \ elseif {[string match (* $newval]} {$jtw insert $found $newval {tAny tString}} \ elseif {[string match \[-0-9\]* $newval]} {$jtw insert $found $newval {tAny tInt}} \ {$jtw insert $found $newval {tAny tSing}} $jtw mark set insert "$found + 1 chars"; $jtw see insert return $oldval } proc update_radio {key newval} { global jtw # puts "got=([find_val_range /Compression])" #set found [find_val_range /Hints] # set found [find_val_range /Profile] #puts "found=$found." #puts "is=([$jtw get [lindex $found 0] [lindex $found 1]])." if {![string length [update_psval /$key /$newval]]} { bell pts_message_box -title Warning -message "Cannot find key /$key. Please verify that the .job file is correct." } } proc update_check {key wPath} { set varname [$wPath cget -variable] global $varname if {[set $varname]} {update_psval /$key true} {update_psval /$key false} } #set psstr_map "" #proc psstr_map_init {} { # for {set i 0} {$i<32} {incr i} {lappend psstr_map [format %c $i] [format \\%02o $i]} # for {set i 127} {$i<256} {incr i} {lappend psstr_map [format %c $i] [format \\%02o $i]} #} #(\\)' #psstr_map_init #regexp {^[] -'+-[^]+} str proc pts_psstr_q {str} { #** This would be <60 chars in Perl. TCL is stupid, lame and sloow. set ret "" while {1} { regexp {^[] -'+-[^-~]*} $str head # ^^^ rejects low-unprintable, >=127, backslash, lparen and rparen set ret $ret$head if {[string length $str]==[set headlen [string length $head]]} break scan [string index $str $headlen] %c charcode set ret $ret[format \\%03o [expr {$charcode&255}]] set str [string range $str [expr {1+$headlen}] end] } return $ret } proc update_str {key newval empty} { # Imp: regsub... # set newval [string map $psstr_map $newval] if {[string length $newval]} {set newval ([pts_psstr_q $newval])} {set newval $empty} if {![string length [update_psval /$key $newval]]} { bell pts_message_box -title Warning -message "Cannot find key /$key. Please verify that the .job file is correct." } } proc update_int {key newval empty} { if {[catch {set intval [expr {0+$newval}]}] || [string compare $intval $newval]} {set intval $empty} if {![string length [update_psval /$key $intval]]} { bell pts_message_box -title Warning -message "Cannot find key /$key. Please verify that the .job file is correct." } } proc but_save {} { global jtw jfn set f [open [$jfn get] w] catch {fconfigure $f -encoding binary} ;# TCL 8.2 fconfigure $f -translation binary puts -nonewline $f [$jtw get 1.0 end] close $f # bell } set tmpfnb "sam2p_tmp_[pid]" proc but_relight {} { # Imp: error checks # Imp: \n transl # set f [open |[list tr a-z A-Z >tmp.tmp] w] global jtw tmpfnb set f [open "|perl -I. -Msam2ptol -e sam2ptol::highlight $jtw >$tmpfnb.tjb" w] catch {fconfigure $f -encoding binary} ;# TCL 8.2 fconfigure $f -translation binary puts -nonewline $f [$jtw get 1.0 end] close $f set f [open $tmpfnb.tjb r] catch {fconfigure $f -encoding binary} ;# TCL 8.2 fconfigure $f -translation binary # puts [read $f] eval [read $f] close $f file delete -- $tmpfnb.tjb } proc but_load {} { global jtw jfn tmpfnb if {[catch {set f [open [$jfn get] r]} err]} { pts_message_box -message "Load failed: $err" } { catch {fconfigure $f -encoding binary} ;# TCL 8.2 fconfigure $f -translation binary $jtw delete 1.0 end $jtw insert end [read $f] close $f but_relight # bell global InputFile InputFileOK set InputFile "" if {[llength [set found [find_val_range /InputFile]]]} { set val [eval "$jtw get $found"] if {[string match (*) $val]} { # vvv Imp: real PS backslash interpolation, not TCL set InputFile [subst -nocommands -novariables [string range $val 1 [expr {[string length $val]-2}]]] } } set InputFileOK [pts_read_ok $InputFile] global OutputFile OutputFileOK set OutputFile "" if {[llength [set found [find_val_range /OutputFile]]]} { set val [eval "$jtw get $found"] if {[string match (*) $val]} { # vvv Imp: real PS backslash interpolation, not TCL set OutputFile [subst -nocommands -novariables [string range $val 1 [expr {[string length $val]-2}]]] } } set OutputFileOK [pts_write_ok $OutputFile] global FileFormat set FileFormat "" if {[llength [set found [find_val_range /FileFormat]]]} { set FileFormat [string range [eval "$jtw get $found"] 1 end] } global SampleFormat set SampleFormat "" if {[llength [set found [find_val_range /SampleFormat]]]} { set SampleFormat [string range [eval "$jtw get $found"] 1 end] } global Compression set Compression "" if {[llength [set found [find_val_range /Compression]]]} { set Compression [string range [eval "$jtw get $found"] 1 end] } global TransferEncoding set TransferEncoding "" if {[llength [set found [find_val_range /TransferEncoding]]]} { set TransferEncoding [string range [eval "$jtw get $found"] 1 end] } global Predictor set Predictor "" if {[llength [set found [find_val_range /Predictor]]]} { set Predictor [eval "$jtw get $found"] } global TransferCPL set TransferCPL "" if {[llength [set found [find_val_range /TransferCPL]]]} { set TransferCPL [eval "$jtw get $found"] } global Effort set Effort "" if {[llength [set found [find_val_range /Effort]]]} { set Effort [eval "$jtw get $found"] } global RecordSize set RecordSize "" if {[llength [set found [find_val_range /RecordSize]]]} { set RecordSize [eval "$jtw get $found"] } global K set K "" if {[llength [set found [find_val_range /K]]]} { set K [eval "$jtw get $found"] } global Quality set Quality "" if {[llength [set found [find_val_range /Quality]]]} { set Quality [eval "$jtw get $found"] } global WarningOK set WarningOK "" if {[llength [set found [find_val_range /WarningOK]]]} { if {[string compare true [eval "$jtw get $found"]]} {set WarningOK 1} {set WarningOK 1} } global TmpRemove set TmpRemove "" if {[llength [set found [find_val_range /TmpRemove]]]} { if {[string compare true [eval "$jtw get $found"]]} {set TmpRemove 1} {set TmpRemove 1} } } } proc but_quit {} { if {0==[string compare yes [pts_message_box -type yesno -title {Confirm quit} -message "Quit now, without saving?"]]} exit } proc but_run {} { # by pts@fazekas.hu at Fri Apr 26 23:43:17 CEST 2002 global JobFile sa_debug_append "exec sam2p $JobFile:\n" # if {[catch {set ret [exec sam2p $JobFile 2>@ stdout]} ret]} {} if {[catch {set ret [exec sh -c {exec sam2p $1 2>&1} sam2p. $JobFile]} ret]} { set ret "Error running sam2p:\n$ret" } # puts ($ret) sa_debug_append $ret\n\n } # option add *Dialog*Label*font fixed # option add *Label*Font times #option add *font times #option add *$g*font times #option add *Dialog.msg.background red label $g.lCompression -text Compression -anchor w -font $sa_boldfont sa_radio $g.fNone Compression None None -command {update_radio Compression None} sa_radio $g.fLZW Compression LZW LZW -command {update_radio Compression LZW} sa_radio $g.fZIP Compression ZIP ZIP -command {update_radio Compression ZIP} sa_int $g.fZIP.fEffort Effort Effort 2 -textvariable Effort bind $g.fZIP.fEffort.i {update_int Effort [%W get] pop} pack $g.fZIP.fEffort -side left sa_radio $g.fRLE Compression RLE RLE -command {update_radio Compression RLE} sa_int $g.fRLE.fRecordSize RecordSize R.S 3 -textvariable RecordSize bind $g.fRLE.fRecordSize.i {update_int RecordSize [%W get] pop} pack $g.fRLE.fRecordSize -side left sa_radio $g.fFax Compression Fax Fax -command {update_radio Compression Fax} sa_int $g.fFax.fK K K 5 -textvariable K bind $g.fFax.fK.i {update_int K [%W get] pop} pack $g.fFax.fK -side left sa_radio $g.fDCT Compression DCT DCT -command {update_radio Compression DCT} sa_radio $g.fIJG Compression IJG IJG -command {update_radio Compression IJG} sa_int $g.fIJG.fQuality Quality Q'lty 3 -textvariable Quality bind $g.fIJG.fQuality.i {update_int Quality [%W get] pop} pack $g.fIJG.fQuality -side left sa_radio $g.fJAI Compression JAI JAI -command {update_radio Compression JAI} #label $g.fJAI.haha -text haha #pack $g.fJAI.haha -side left pack $g.lCompression -fill x pack $g.fNone $g.fLZW $g.fZIP $g.fRLE $g.fFax $g.fDCT $g.fIJG $g.fJAI -fill x sa_vframe $g sa_int $g.lPredictor Predictor Predictor 3 -textvariable Predictor bind $g.lPredictor.i {update_int Predictor [%W get] pop} pack $g.lPredictor -fill x sa_vframe $g sa_check_update $g.cWarningOK WarningOK WarningOK # -textvariable WarningOK pack $g.cWarningOK -fill x sa_vframe $g label $g.lTransferEncoding -text TransferEncoding -anchor w -font $sa_boldfont sa_radio $g.fBinary TransferEncoding Binary Binary -command {update_radio TransferEncoding Binary} sa_radio $g.fASCII TransferEncoding ASCII ASCII -command {update_radio TransferEncoding ASCII} sa_radio $g.fHex TransferEncoding Hex Hex -command {update_radio TransferEncoding Hex} sa_radio $g.fA85 TransferEncoding A85 A85 -command {update_radio TransferEncoding A85} pack $g.lTransferEncoding -fill x pack $g.fBinary $g.fASCII $g.fHex $g.fA85 -fill x frame $g.pTransferEncoding -height 5 -width 1 pack $g.pTransferEncoding -fill x sa_int $g.fTransferCPL TransferCPL TransferCPL 3 -textvariable TransferCPL bind $g.fTransferCPL.i {update_int TransferCPL [%W get] pop} pack $g.fTransferCPL -fill x sa_vframe $g sa_check_update $g.cTmpRemove TmpRemove {Tmp Remove} pack $g.cTmpRemove -fill x sa_vframe $g set g .gtop.g3 frame $g sa_w_text $g.t -width 58 -height 18 -wrap none -font $sa_fixfont pts_fix_one_tab $g.t pts_text_autoindent $g.t 1 pts_text_auto_overstrike $g.t 0 # $g.t insert end "<<%sam2p job file\n /InputFile (alma)\n /OutputFile (korte)\n /Profile \[\n /Compression /LZW/Predictor 13\n /Hints<>)>> >>\n ]\n>>\n" # $g.t insert end [read [open template.job r]] # Imp: close file... $g.t mark set insert 1.0; $g.t see insert $g.t tag configure tAny; $g.t tag lower tAny sel $g.t tag configure tSing -foreground "#003f7f"; $g.t tag raise tSing sel $g.t tag configure tString -foreground "#007f7f"; $g.t tag raise tString sel $g.t tag configure tKey -foreground "#00007f"; $g.t tag raise tKey sel $g.t tag configure tNameval -foreground "#0000ff"; $g.t tag raise tNameval sel $g.t tag configure tBrac -foreground "#ff0000"; $g.t tag raise tBrac sel $g.t tag configure tComment -foreground "#007f00"; $g.t tag raise tComment sel $g.t tag configure tInt -foreground "#3f0000"; $g.t tag raise tInt sel $g.t tag configure tError -background "#ffdddd"; $g.t tag lower tError sel # puts X[bindtags $g.t]X # puts X[bind $g.t]X # puts XZ[bind all]X set jtw $g.t # Imp: delete tmp.tmp # -font sansserif # puts [$g.t tag ranges tSing] # reground blue # update idletasks; puts [winfo geometry $g.t] ;# not ready, has to be packed first frame $g.f sa_w_text $g.f.td -width 1 -height 13 -wrap char -font $sa_fixfont \ -yscrollcommand "$g.f.sd set" -spacing3 2 $g.f.td configure -selectbackground yellow ;# override scrollbar $g.f.sd -command "$g.f.td yview" -width 11 -elementborderwidth 2 \ -relief flat -borderwidth 1 -takefocus 0 -troughcolor gray65 $g.f.sd configure -activebackground [$g.f.sd cget -background] # OK: non-editable, but not disabled (we need the cursor!) # $g.f.td configure -background [lindex [$g.f.td configure -background] 3] pts_readonly_color $g.f.td # puts $g.f.td # puts TD:[bind .gtop.g3.f.td ] pts_fix_one_tab $g.f.td $g.f.td insert end "Debug messages, sam2p output:\n\n" # $g.f.td insert end "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n" # $g.f.td insert end "21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n" $g.f.td mark set insert 1.0; $g.f.td see insert set debugtext $g.f.td pack $g.t -expand 0 -fill x pack $g.f.td -expand 1 -fill both -side left pack $g.f.sd -fill both -side left pack $g.f -expand 1 -fill both pack .gtop.g0 .gtop.g1 .gtop.g2 -side left pack .gtop.g3 -expand 1 -fill both -side left frame .gbot frame .gbot.gbl set g .gbot.gbl.fCurdir frame $g label $g.l -text "Current dir" -font $sa_boldfont sa_w_entry $g.e -font $sa_normfont # bind $g.e {update_str e [%W get] pop} pack $g.l -side left pack $g.e -expand 1 -fill x -side left $g.e insert 0 [pwd] # puts [bind .gbot.gbl.fCurdir.e] bind Text {} bind Text {} # puts T[bind Text]T # puts [bind Text ] #puts ([bind Entry ]) #foreach evtseq [bind Entry] { # if {[string match $evtseq] # || [string match <*-Key-*> $evtseq] # || [string match <*-Key> $evtseq] # } { # bind $g.e $evtseq {break} # puts +:$evtseq # } { # #puts -:$evtseq # } #} # Dat: this assumes [lindex [bindtags $g.e] 0] == $g.e #foreach tag [bindtags $g.e] { # foreach evtseq [bind $tag] { # # if {0==[string length [bind $g.e $evtseq]]} {bind $g.e $evtseq [bind $tag $evtseq]} # } #} pts_readonly_color $g.e # event info <> #bind $g.e {# nothing} #bind $g.e {# nothing} # puts /[bind $g.e] # puts :[bind $g.e ] set g .gbot.gbl.fJobFile frame $g label $g.l -text JobFile -font $sa_boldfont sa_w_entry $g.e -font $sa_normfont -textvariable JobFile label $g.r -text OK -font $sa_normfont -textvariable JobFileOK -width 2 bind $g.e {set JobFileOK [pts_write_ok $JobFile]} set jfn $g.e pack $g.l -side left pack $g.e -expand 1 -fill x -side left pack $g.r -side left set g .gbot.gbl.fInputFile frame $g label $g.l -text InputFile -font $sa_boldfont sa_w_entry $g.e -font $sa_normfont -textvariable InputFile label $g.r -text OK -font $sa_normfont -textvariable InputFileOK -width 2 bind $g.e {update_str InputFile [%W get] pop; set InputFileOK [pts_read_ok $InputFile]} pack $g.l -side left pack $g.e -expand 1 -fill x -side left pack $g.r -side left set InputFileOK [pts_read_ok $InputFile] set g .gbot.gbl.fOutputFile frame $g label $g.l -text OutputFile -font $sa_boldfont sa_w_entry $g.e -font $sa_normfont -textvariable OutputFile label $g.r -text OK -font $sa_normfont -textvariable OutputFileOK -width 2 bind $g.e {update_str OutputFile [%W get] pop; set OutputFileOK [pts_write_ok $OutputFile]} pack $g.l -side left pack $g.e -expand 1 -fill x -side left pack $g.r -side left pack .gbot.gbl.fCurdir .gbot.gbl.fJobFile .gbot.gbl.fInputFile .gbot.gbl.fOutputFile -expand 1 -fill x frame .gbot.ha button .gbot.ha.bLoad -text {Load Job} -font $sa_normfont -borderwidth 1 -pady 2 -underline 0 \ -command but_load bind . but_load button .gbot.ha.bSave -text {Save Job} -font $sa_normfont -borderwidth 1 -pady 2 -underline 0 \ -command but_save bind . but_save frame .gbot.hb button .gbot.hb.bRun -text {Run} -font $sa_normfont -borderwidth 1 -pady 2 -underline 0 \ -command but_run bind . but_run button .gbot.hb.bQuit -text {Quit} -font $sa_normfont -borderwidth 1 -pady 2 -underline 0 \ -command but_quit bind . but_quit pack .gbot.gbl -expand 1 -fill x -side left pack .gbot.ha.bLoad .gbot.ha.bSave pack .gbot.hb.bRun .gbot.hb.bQuit pack .gbot.ha .gbot.hb -side left pack .gtop -expand 1 -fill both pack .gbot -expand 0 -fill x update idletasks ;# a sima [update] helyett, hogy a "geometry" j legyen scan [wm geometry .] "%dx%d%s" width height tmp wm minsize . $width $height set env(PATH) $env(PATH)[pts_PATH_sep]. #if {[catch {set ret [exec sam2p --help 2>&1]} ret]} {} if {[catch {set ret [exec sh -c {exec sam2p --help 2>&1}]} ret]} { set ret "Error:\n$ret" } proc sa_debug_append msg { global debugtext $debugtext insert end $msg $debugtext mark set insert end $debugtext see insert } sa_debug_append $ret\n\n # puts ($ret) $jfn delete 0 end if {[llength $argv]} {$jfn insert 0 [lindex $argv 0]; but_load} { $jfn insert 0 template.job; but_load; $jfn delete 0 end set InputFileOK 0 set OutputFileOK 0 set JobFileOK 0 } # set InputFile hello # but_load # puts $argv # puts TD:[bind .gtop.g3.f.td ] #__END__ sam2p-0.49.2/contrib/sam2ptol.pm0000644000175100017510000000543012211371426014570 0ustar ptspts# sam2ptol.pm by pts@math.bme.hu at Sun Apr 7 14:48:27 CEST 2002 package sam2ptol; BEGIN{$^W=1} use integer; use strict; my %keys=qw{/InputFile 1 /OutputFile 1 /TmpRemove 1 /Profile 1 /FileFormat 1 /SampleFormat 1 /WarningOK 1 /TransferEncoding 1 /Compression 1 /Predictor 1 /Transparent 1 /Hints 1 /Effort 1 /RecordSize 1 /K 1 /Quality 1 /ColorTransform 1 /TransferCPL 1 /EncoderColumns 1 /EncoderRows 1 /EncoderColors 1 /PredictorColumns 1 /PredictorBPC 1 /PredictorColors 1 /Comment 1 /Title 1 /Subject 1 /Author 1 /Creator 1 /Producer 1 /Created 1 /Produced 1 /LoadHints 1 /Templates 1}; # Dat: DCT is not key! my %values=qw{ /PSL1 1 /PSLC 1 /PSL2 1 /PSL3 1 /PDFB1.0 1 /PDFB1.2 1 /PDF1.0 1 /PDF1.2 1 /GIF89a 1 /Empty 1 /Meta 1 /PNM 1 /PAM 1 /PIP 1 /Opaque 1 /Transparent 1 /Transparent2 1 /Transparent4 1 /Transparent8 1 /Gray1 1 /Gray2 1 /Gray4 1 /Gray8 1 /Indexed1 1 /Indexed2 1 /Indexed4 1 /Indexed8 1 /Mask 1 /Rgb1 1 /Rgb2 1 /Rgb4 1 /Rgb8 1 /RGB1 1 /RGB2 1 /RGB4 1 /RGB8 1 /Asis 1 /Binary 1 /ASCII 1 /Hex 1 /AHx 1 /ASCIIHex 1 /A85 1 /ASCII85 1 /None 1 /LZW 1 /ZIP 1 /Flate 1 /Fl 1 /RLE 1 /RunLength 1 /RunLengthEncoded 1 /RL 1 /PackBits 1 /Fax 1 /CCITTFax 1 /CCF 1 /DCT 1 /JPEG 1 /JPG 1 /JFIF 1 /IJG 1 /JAI 1 }; sub highlight { #** Example: perl -I. -Msam2ptol -e sam2ptol::highlight alma ; my($beg,$end,$c,$ta,$tb); for (qw{tError tInt tComment tString tSing tKey tNameval tBrac}) { print "$w tag remove tString 1.0 end\n" } while (m@( \((\\.|[^\\()]+)*\) # String. Imp: nesting?? |/([^\000-\040/\%{}<>\[\]()\177-\377]*) # Sname |[_A-Za-z_]([^\000-\040/\%{}<>\[\]()\177-\377]*) # Ename |<<|>>|\[|\] |true|false|pop|null |%[^\r\n]* |-?\d+ )@gsx) { my $e=$1; $beg=($end=pos())-length($e); $c=substr($e,0,1); $ta="$w tag add"; $tb=" {1.0 + $beg chars} {1.0 + $end chars}\n"; if ($c eq'/') { if (exists $keys{$e}) { print "$ta tKey$tb"; # print STDERR "($e)\n"; } elsif (exists $values{$e}) { print "$ta tNameval$tb"; } else { print "$ta tError$tb"; } } elsif ($c eq'(') { print "$ta tString$tb"; print "$w tag add tString {1.0 + $beg chars} {1.0 + $end chars}\n" } elsif ($e eq'true' or $e eq'false' or $e eq'pop' or $e eq'null') { print "$ta tSing$tb"; } elsif ($e=~/\A[_A-Za-z]/) { # } elsif ($e=~/\A\w/) { # print STDERR "($e)\n"; print "$ta tError$tb"; } elsif ($c eq'%') { print "$ta tComment$tb"; } elsif ($c eq'-' or ord($c)>=ord('0') and ord($c)<=ord('9')) { print "$ta tInt$tb"; } else { print "$ta tBrac$tb"; } print "$ta tAny$tb"; # print "[".pos()."]\n"; } } 1; sam2p-0.49.2/contrib/template.job0000644000175100017510000000140112211371426014772 0ustar ptspts<<%sam2p job file template (.cpp code is _not_ generated from this) /InputFile pop /OutputFile pop /TmpRemove true /LoadHints pop /Templates pop /Profile [<< /FileFormat pop /SampleFormat pop /WarningOK true /TransferEncoding pop /Compression /None /Predictor 1 /Transparent null /Hints << /Effort -1 /RecordSize 0 /K 0 /Quality 75 /ColorTransform pop /TransferCPL 78 /DCT <<>> /EncoderColumns 0 /EncoderRows 0 /EncoderColors 0 /PredictorColumns 0 /PredictorBPC 0 /PredictorColors 0 /Comment pop /Title pop /Subject pop /Author pop /Creator pop /Producer pop /Created pop /Produced pop >> >>] >>% __EOF__ sam2p-0.49.2/examples/a_jpg.job0000644000175100017510000000031612211371426014421 0ustar ptspts<<%sam2p-job; by Sun Mar 17 21:59:30 CET 2002 /InputFile (examples/a.jpg) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Asis /TransferEncoding/Binary /Compression/JAI >> ] >> sam2p-0.49.2/examples/a_jpg2.job0000644000175100017510000000031612211371426014503 0ustar ptspts<<%sam2p-job; by Sun Mar 17 21:59:30 CET 2002 /InputFile (examples/a.jpg) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Rgb8 /TransferEncoding/Binary /Compression/JAI >> ] >> sam2p-0.49.2/examples/a_l1r8r_eps.job0000644000175100017510000000034312211371426015460 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 16:57:49 CEST 2002 /InputFile (examples/a.jpg) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/RGB8 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/at-logo_none_xpm.job0000644000175100017510000000037112211371426016607 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 20:16:14 CEST 2002 /InputFile (examples/at-logo.gif) /OutputFile (test.xpm) /Profile [ << /FileFormat/XPM /SampleFormat/Transparent4 /TransferEncoding/ASCII /Compression/None >> ] >> sam2p-0.49.2/examples/fishg_lzw12_pdf.job0000644000175100017510000000037212211371426016333 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 22:07:29 CEST 2002 /InputFile (examples/fishg.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/LZW /Predictor 12 >> ] >> sam2p-0.49.2/examples/fishg_lzw2_pdf.job0000644000175100017510000000037112211371426016251 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 22:07:29 CEST 2002 /InputFile (examples/fishg.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/fishwbb_l128n_eps.job0000644000175100017510000000036312211371426016562 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 12:11:08 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l128r_eps.job0000644000175100017510000000036212211371426016565 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l12bn_eps.job0000644000175100017510000000036612211371426016637 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:38:24 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l12br_eps.job0000644000175100017510000000036512211371426016642 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:24:53 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l12hn_eps.job0000644000175100017510000000036312211371426016642 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:38:24 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/Hex /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l12hr_eps.job0000644000175100017510000000036212211371426016645 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:24:53 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed2 /TransferEncoding/Hex /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l148n_eps.job0000644000175100017510000000036312211371426016564 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 12:11:08 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l148r_eps.job0000644000175100017510000000036212211371426016567 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l14bn_eps.job0000644000175100017510000000036612211371426016641 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:38:28 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l14br_eps.job0000644000175100017510000000036512211371426016644 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:29:41 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l14hn_eps.job0000644000175100017510000000036312211371426016644 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:38:28 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/Hex /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l14hr_eps.job0000644000175100017510000000036212211371426016647 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 14:29:41 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed4 /TransferEncoding/Hex /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l188n_eps.job0000644000175100017510000000036312211371426016570 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 12:11:08 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l188r_eps.job0000644000175100017510000000036212211371426016573 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l18bn_eps.job0000644000175100017510000000036612211371426016645 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 12:11:08 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l18br_eps.job0000644000175100017510000000036512211371426016650 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 13:23:31 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/fishwbb_l18hn_eps.job0000644000175100017510000000036312211371426016650 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 12:11:08 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/None >> ] >> sam2p-0.49.2/examples/fishwbb_l18hr_eps.job0000644000175100017510000000036212211371426016653 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 13:23:31 CEST 2002 /InputFile (examples/fishwbb.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/RLE >> ] >> sam2p-0.49.2/examples/fusi2_png.job0000644000175100017510000000044212211371426015235 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 16:49:24 CEST 2002 /InputFile (examples/fusi2.pnm) %/InputFile (examples/fusiblack.ppm) /OutputFile (test.png) /Profile [ << /FileFormat/PNG /SampleFormat/Transparent4 /TransferEncoding/Binary /Compression/ZIP /Predictor 15 >> ] >> sam2p-0.49.2/examples/fusi_gif.job0000644000175100017510000000050312211371426015132 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 16:49:24 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.gif) /Profile [ << /FileFormat/GIF89a /SampleFormat/Transparent4 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fusi_l1t8r_eps.job0000644000175100017510000000036412211371426016213 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 16:15:00 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent8 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/fusi_l1tbr_eps.job0000644000175100017510000000036712211371426016270 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:59:13 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent4 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/fusi_l1thn_eps.job0000644000175100017510000000050612211371426016265 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:58:00 CEST 2002 % original fusi_tral1_eps.job by pts@fazekas.hu at Sat Jun 1 19:00:48 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent4 /TransferEncoding/Hex /Compression/None >> ] >> sam2p-0.49.2/examples/fusi_l1thr_eps.job0000644000175100017510000000036412211371426016273 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 16:14:01 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent4 /TransferEncoding/Hex /Compression/RLE >> ] >> sam2p-0.49.2/examples/fusi_png.job0000644000175100017510000000044012211371426015151 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 16:49:24 CEST 2002 /InputFile (examples/fusi.tiff) %/InputFile (examples/fusiblack.ppm) /OutputFile (test.png) /Profile [ << /FileFormat/PNG /SampleFormat/Transparent4 /TransferEncoding/Binary /Compression/ZIP /Predictor 15 >> ] >> sam2p-0.49.2/examples/fusi_pnm.job0000644000175100017510000000037012211371426015161 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 21:42:08 CEST 2002 /InputFile (examples/fusi.gif) /OutputFile (test.pnm) /unknown pop /Profile [ << /FileFormat/PNM /SampleFormat/Transparent4 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fusi_pnm_ascii.job0000644000175100017510000000036712211371426016337 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 15:03:47 CEST 2002 /InputFile (examples/fusi.gif) /OutputFile (test.pnm) /unknown pop /Profile [ << /FileFormat/PNM /SampleFormat/Transparent4 /TransferEncoding/ASCII /Compression/None >> ] >> sam2p-0.49.2/examples/fusi_tiff_bad_pdf.job0000644000175100017510000000035112211371426016755 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Apr 14 15:14:32 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Gray8 /TransferEncoding/Binary /Compression/ZIP >> ] >> sam2p-0.49.2/examples/fusi_tiff_eps.job0000644000175100017510000000034612211371426016171 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Apr 14 15:14:32 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Gray8 /TransferEncoding/Binary /Compression/ZIP >> ] >> sam2p-0.49.2/examples/fusi_tra_eps.job0000644000175100017510000000052012211371426016021 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 24 13:32:12 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Transparent4 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/A85 /Predictor 45 /Compression/ZIP >> ] >> sam2p-0.49.2/examples/fusi_trabin_eps.job0000644000175100017510000000050112211371426016511 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 24 13:32:12 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Transparent4 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fusi_tradct_eps.job0000644000175100017510000000046612211371426016525 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 18:18:51 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Gray8 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/A85 /Compression/DCT >> ] >> sam2p-0.49.2/examples/fusi_tradct_jpeg.job0000644000175100017510000000047112211371426016657 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 18:18:51 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.jpg) /Profile [ << /FileFormat/JPEG /SampleFormat/Gray8 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/Binary /Compression/DCT >> ] >> sam2p-0.49.2/examples/fusi_trafax_eps.job0000644000175100017510000000047512211371426016531 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 24 13:32:12 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Transparent4 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/A85 /Compression/Fax >> ] >> sam2p-0.49.2/examples/fusi_traijg_eps.job0000644000175100017510000000067412211371426016525 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 24 13:32:12 CEST 2002 % Doesn't work (of course), because JPEG compression requires a bit depth of % 8, but /Transparent* provides a bit depth of 1. /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Transparent4 %/SampleFormat/Indexed4 % doesn't work, contains transparent pixels /TransferEncoding/A85 /Compression/IJG >> ] >> sam2p-0.49.2/examples/fusi_tral1a85_eps.job0000644000175100017510000000036512211371426016603 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 19:54:45 CEST 2002 /InputFile (examples/fusi.tiff) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent4 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/fusiblack_png.job0000644000175100017510000000043412211371426016151 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 16:49:24 CEST 2002 %/InputFile (examples/fusi.tiff) /InputFile (examples/fusiblack.ppm) /OutputFile (test.png) /Profile [ << /FileFormat/PNG /SampleFormat/Indexed4 /TransferEncoding/Binary /Compression/ZIP /Predictor 15 >> ] >> sam2p-0.49.2/examples/fusiwhite_a85none.job0000644000175100017510000000034712211371426016711 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 19:30:08 CEST 2002 /InputFile (examples/fusiwhite.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray4 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/fusiwhite_binnone.job0000644000175100017510000000035212211371426017060 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 16:46:25 CEST 2002 /InputFile (examples/fusiwhite.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray4 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/fusiwhite_xwd.job0000644000175100017510000000036712211371426016240 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Aug 10 23:30:08 CEST 2002 /InputFile (examples/fusiwhite.gif) /OutputFile (test.xwd) /Profile [ << /FileFormat/XWD /SampleFormat/Gray8 /TransferEncoding/Binary /Compression/None /Predictor 1 >> ] >> sam2p-0.49.2/examples/j_taska_lzw_eps.job0000644000175100017510000000045312211371426016522 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 20:09:17 CEST 2002 %/InputFile (/tmp/j_taska.png) /InputFile (/tmp/j_taska.gif) /OutputFile (test.eps) %/LoadHints (asis) /Profile [ << /FileFormat/PSL2 /SampleFormat/Gray8 /TransferEncoding/A85 /Compression/LZW % /Predictor 15 >> ] >> sam2p-0.49.2/examples/j_taska_rle_bmp.job0000644000175100017510000000042412211371426016455 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 23 21:20:59 CEST 2002 /InputFile (/tmp/j_taska.png) /OutputFile (test.bmp) %/LoadHints (asis) /Profile [ << /FileFormat/BMP /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/RLE % /Compression/None >> ] >> sam2p-0.49.2/examples/mixing_ijg.job0000644000175100017510000000032112211371426015461 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/mixing1.xpm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/RGB8 /TransferEncoding/A85 /Compression/IJG >> ] >> sam2p-0.49.2/examples/mixing_pcx_zip.job0000644000175100017510000000034112211371426016366 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/mixing1.pcx) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Indexed2 /TransferEncoding/A85 /Compression/ZIP /Predictor 2>> ] >> sam2p-0.49.2/examples/mixing_zip.job0000644000175100017510000000034112211371426015514 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/mixing0.xpm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Indexed2 /TransferEncoding/A85 /Compression/ZIP /Predictor 2>> ] >> sam2p-0.49.2/examples/pts2_l1g8n_eps.job0000644000175100017510000000035012211371426016107 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 16:25:06 CEST 2002 /InputFile (examples/pts2.pbm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray4 /TransferEncoding/A85 /Compression/None >> ] >> sam2p-0.49.2/examples/pts2_l1g8r_eps.job0000644000175100017510000000035212211371426016115 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:31:48 CEST 2002 /InputFile (examples/pts2.pbm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray2 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/pts2_l1gbr_eps.job0000644000175100017510000000035212211371426016167 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:30:22 CEST 2002 /InputFile (examples/pts2.pbm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray1 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/pts2_pbm.job0000644000175100017510000000046012211371426015067 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Mar 17 16:21:44 CET 2002 % This is file (named test0.job). /InputFile (examples/pts2.pbm) /OutputFile (test.eps) /unknown pop /Profile [ << /FileFormat/PSL1 /SampleFormat/Gray8 /TransferEncoding/A85 /Compression/ZIP /Hints<> /Predictor 1 >> ] >> sam2p-0.49.2/examples/pts2_pbm_pnm.job0000644000175100017510000000036412211371426015744 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 21:42:08 CEST 2002 /InputFile (examples/pts2.pbm) /OutputFile (test.pnm) /unknown pop /Profile [ << /FileFormat/PNM /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/pts2_pbm_zip0.job0000644000175100017510000000046312211371426016034 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Mar 17 16:21:44 CET 2002 % This is file (named test0.job). /InputFile (examples/pts2.pbm) /OutputFile (test.eps) /unknown pop /Profile [ << /FileFormat/PSL3 /SampleFormat/Gray8 /TransferEncoding/Binary /Compression/ZIP /Hints<> /Predictor 1 >> ] >> sam2p-0.49.2/examples/ptsbanner2_ijg_tiff.job0000644000175100017510000000037712211371426017267 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 19:49:26 CEST 2002 /InputFile (examples/ptsbanner2a.jpg) /OutputFile (test.tiff) %/LoadHints (asis) /Profile [ << /FileFormat/TIFF /SampleFormat/Rgb8 /TransferEncoding/Binary /Compression/IJG >> ] >> sam2p-0.49.2/examples/ptsbanner2_jai.job0000644000175100017510000000034712211371426016246 0ustar ptspts<<%sam2p-job; by Sun Mar 17 21:59:30 CET 2002 /InputFile (examples/ptsbanner2.jpg) /OutputFile (test.eps) %/LoadHints (asis) /Profile [ << /FileFormat/PSL3 /SampleFormat/Asis /TransferEncoding/Hex /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbanner2_jai_jpeg.job0000644000175100017510000000037512211371426017254 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 17 13:49:02 CEST 2002 /InputFile (examples/ptsbanner2.jpg) /OutputFile (test.jpg) %/LoadHints (asis) /Profile [ << /FileFormat/JPEG /SampleFormat/Asis /TransferEncoding/Binary /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbanner2_jai_pdf.job0000644000175100017510000000035112211371426017072 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 17 12:26:49 CEST 2002 /InputFile (examples/ptsbanner2.jpg) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.2 /SampleFormat/Asis /TransferEncoding/A85 /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbanner2_jai_tiff.job0000644000175100017510000000037712211371426017261 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 22:28:37 CEST 2002 /InputFile (examples/ptsbanner2a.jpg) /OutputFile (test.tiff) %/LoadHints (asis) /Profile [ << /FileFormat/TIFF /SampleFormat/Asis /TransferEncoding/Binary /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbanner2_jpeg_tiff.job0000644000175100017510000000037712211371426017443 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 19:49:26 CEST 2002 /InputFile (examples/ptsbanner2a.jpg) /OutputFile (test.tiff) %/LoadHints (asis) /Profile [ << /FileFormat/TIFF /SampleFormat/Rgb8 /TransferEncoding/Binary /Compression/DCT >> ] >> sam2p-0.49.2/examples/ptsbanner__jpeg.job0000644000175100017510000000035112211371426016500 0ustar ptspts<<%sam2p-job; by Sun Mar 17 21:59:30 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.jpg) %/LoadHints (asis) /Profile [ << /FileFormat/JPEG /SampleFormat/Rgb8 /TransferEncoding/Binary /Compression/IJG >> ] >> sam2p-0.49.2/examples/ptsbanner_bbox_pdf.job0000644000175100017510000000051512211371426017201 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 16:47:10 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.0 /SampleFormat/Bbox /TransferEncoding/Hex % /Compression/LZW /Predictor 15 /Compression/RLE % /Compression/LZW /Predictor 2 % /Compression/LZW >> ] >> sam2p-0.49.2/examples/ptsbanner_gif_xwd.job0000644000175100017510000000037212211371426017046 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Aug 10 23:30:08 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.xwd) /Profile [ << /FileFormat/XWD /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/None /Predictor 1 >> ] >> sam2p-0.49.2/examples/ptsbanner_jpeg.job0000644000175100017510000000032512211371426016342 0ustar ptspts<<%sam2p-job; by Sun Mar 17 22:34:14 CET 2002 /InputFile (examples/ptsbanner2.jpg) /OutputFile (test.eps) /Profile [ << /FileFormat/PSLC /SampleFormat/Rgb8 /TransferEncoding/Hex /Compression/None >> ] >> sam2p-0.49.2/examples/ptsbanner_jpg_xwd.job0000644000175100017510000000036712211371426017065 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Aug 10 23:30:08 CEST 2002 /InputFile (examples/ptsbanner2.jpg) /OutputFile (test.xwd) /Profile [ << /FileFormat/XWD /SampleFormat/Rgb8 /TransferEncoding/Binary /Compression/None /Predictor 1 >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw.job0000644000175100017510000000034512211371426016233 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_framed.job0000644000175100017510000000053612211371426017553 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Sep 7 15:48:57 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 /Hints << /LeftMargin 20 /TopMargin 15 /RightMargin 10 /BottomMargin 25 >> >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_margin.job0000644000175100017510000000055312211371426017571 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Sep 7 15:26:41 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 /Hints << /LeftMargin 10.5 pt /TopMargin -360dd /RightMargin 3 bp /BottomMargin 5.0in >> >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_margin_pdf.job0000644000175100017510000000054012211371426020416 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Sep 7 22:48:18 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 /Hints << /LeftMargin 20 /TopMargin 15 /RightMargin 10 /BottomMargin 25 >> >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_pdf.job0000644000175100017510000000052112211371426017060 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 19:03:10 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.0 /SampleFormat/Indexed8 /TransferEncoding/Hex % /Compression/LZW /Predictor 15 % /Compression/RLE /Compression/LZW /Predictor 2 % /Compression/LZW >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_pdfb.job0000644000175100017510000000052612211371426017227 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 19:03:39 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed8 /TransferEncoding/Hex % /Compression/LZW /Predictor 2 % OK in pdftops 0.92 /Compression/LZW /Predictor 10 % triggers bug in pdftops 0.92 >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_ps.job0000644000175100017510000000052712211371426016737 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Aug 16 17:22:27 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.ps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 /Hints << /Scale/OK /LeftMargin 10.5 pt /RightMargin 21dd /TopMargin 0 bp >> >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_rot_ps.job0000644000175100017510000000045112211371426017617 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.ps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed8 /TransferEncoding/Hex /Compression/LZW /Predictor 15 /Hints << /Scale/RotateOK /LeftMargin 10.5 /RightMargin 21 >> >> ] >> sam2p-0.49.2/examples/ptsbanner_lzw_tiff.job0000644000175100017510000000045112211371426017241 0ustar ptspts<<%sam2p-job; by Tue Jun 4 18:28:53 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF /SampleFormat/Indexed8 % /SampleFormat/Rgb8 /TransferEncoding/LSBfirst /Compression/LZW /Predictor 2 % /Compression/None >> ] >> sam2p-0.49.2/examples/ptsbanner_none_tiff.job0000644000175100017510000000034012211371426017361 0ustar ptspts<<%sam2p-job; by Tue Jun 4 18:28:53 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF /SampleFormat/Indexed8 /TransferEncoding/LSBfirst /Compression/None >> ] >> sam2p-0.49.2/examples/ptsbanner_png.job0000644000175100017510000000034212211371426016200 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.png) /Profile [ << /FileFormat/PNG /SampleFormat/RGB8 /TransferEncoding/Binary /Compression/ZIP /Predictor 12>> ] >> sam2p-0.49.2/examples/ptsbanner_rle_pdf.job0000644000175100017510000000052112211371426017026 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 18:46:53 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.0 /SampleFormat/Indexed8 /TransferEncoding/Hex % /Compression/LZW /Predictor 15 /Compression/RLE % /Compression/LZW /Predictor 2 % /Compression/LZW >> ] >> sam2p-0.49.2/examples/ptsbanner_rle_tiff.job0000644000175100017510000000040312211371426017204 0ustar ptspts<<%sam2p-job; by Tue Jun 4 18:28:53 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF /SampleFormat/Indexed8 % /SampleFormat/Rgb8 /TransferEncoding/LSBfirst /Compression/RLE >> ] >> sam2p-0.49.2/examples/ptsbanner_tralzw.job0000644000175100017510000000056212211371426016743 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile(test.eps) /Profile [ % sasdasdasd /Korte [ << /FileFormat /PSL2 /SampleFormat/Transparent8 /TransferEncoding/Binary /WarningOK true % /TransferEncoding/Hex % /Compression/LZW /Predictor 1 /Compression /RLE /Hints << /K 42 >> >> ] >> sam2p-0.49.2/examples/ptsbanner_xpm_zip.job0000644000175100017510000000034612211371426017106 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.xpm) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/Rgb4 /TransferEncoding/A85 /Compression/ZIP /Predictor 2>> ] % /a 4 >> sam2p-0.49.2/examples/ptsbanner_zip.job0000644000175100017510000000033712211371426016222 0ustar ptspts<<%sam2p-job; by Fri Mar 22 13:10:53 CET 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL3 /SampleFormat/RGB4 /TransferEncoding/A85 /Compression/ZIP /Predictor 2>> ] >> sam2p-0.49.2/examples/ptsbanner_ziprgb4_tiff.job0000644000175100017510000000055412211371426020012 0ustar ptspts<<%sam2p-job; by Tue Jun 4 19:41:52 CEST 2002 % Note: this doesn't work with libtiff, because they haven't implemented % the predictor... /InputFile (examples/ptsbanner.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Rgb4 /TransferEncoding/LSBfirst /Compression/ZIP /Predictor 2 >> ] >> sam2p-0.49.2/examples/ptsbanner_ziprgb8_tiff.job0000644000175100017510000000044212211371426020012 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 19:42:29 CEST 2002 /InputFile (examples/ptsbanner.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Rgb8 /TransferEncoding/LSBfirst /Compression/ZIP /Predictor 2 >> ] >> sam2p-0.49.2/examples/ptsbannerg_jai.job0000644000175100017510000000034712211371426016333 0ustar ptspts<<%sam2p-job; by Sun Mar 17 21:59:30 CET 2002 /InputFile (examples/ptsbannerg.jpg) /OutputFile (test.eps) %/LoadHints (asis) /Profile [ << /FileFormat/PSL3 /SampleFormat/Asis /TransferEncoding/Hex /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbannerg_jai_pdf.job0000644000175100017510000000035212211371426017160 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 17 12:26:49 CEST 2002 /InputFile (examples/ptsbannerg.jpg) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Asis /TransferEncoding/A85 /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbannerg_jai_tiff.job0000644000175100017510000000037612211371426017345 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 15:15:20 CEST 2002 /InputFile (examples/ptsbannerg.jpg) /OutputFile (test.tiff) %/LoadHints (asis) /Profile [ << /FileFormat/TIFF /SampleFormat/Asis /TransferEncoding/Binary /Compression/JAI >> ] >> sam2p-0.49.2/examples/ptsbannerg_lzw_tiff.job0000644000175100017510000000045312211371426017412 0ustar ptspts<<%sam2p-job; by Tue Jun 4 18:28:53 CEST 2002 /InputFile (examples/ptsbannerg.jpg) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Gray8 /TransferEncoding/LSBfirst /Compression/LZW /Predictor 2 % /Compression/None >> ] >> sam2p-0.49.2/examples/sam2p_fishg.job0000644000175100017510000000037312211371426015546 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 /InputFile (talk/fishg.gif) /OutputFile (talk/fishg.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/sam2p_fisht.job0000644000175100017510000000037312211371426015563 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 /InputFile (talk/fishg.gif) /OutputFile (talk/fishg.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/sam2p_fishwbb.job0000644000175100017510000000037712211371426016076 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 /InputFile (talk/fishwbb.gif) /OutputFile (talk/fishwbb.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/sam2p_fishwbg.job0000644000175100017510000000037712211371426016103 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 /InputFile (talk/fishwbg.gif) /OutputFile (talk/fishwbg.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed4 /TransferEncoding/Binary /Compression/LZW /Predictor 10>> ] >> sam2p-0.49.2/examples/sam2p_fishwbg_bug.job0000644000175100017510000000046712211371426016740 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 % Shows acroread4 bug (Predictor 2 with indexed images) /InputFile (talk/fishwbg.gif) /OutputFile (talk/fishwbg.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed4 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/sam2p_fishwww.job0000644000175100017510000000037512211371426016146 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Fri Apr 26 09:33:29 CEST 2002 /InputFile (talk/fishwww.gif) /OutputFile (talk/fishwww.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Opaque /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/sam2psho.job0000644000175100017510000000040112211371426015070 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Thu Apr 25 09:09:51 CEST 2002 /InputFile (talk/sam2psho.png) /OutputFile (talk/sam2psho.pdf) /Profile [ << /FileFormat/PDFB1.0 /SampleFormat/Indexed8 /TransferEncoding/Binary /Compression/LZW /Predictor 2 >> ] >> sam2p-0.49.2/examples/shot_fax31d_tiff.job0000644000175100017510000000047312211371426016500 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 22:13:03 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Indexed1 /TransferEncoding/MSBfirst /Compression/CCITTFax % default: /Hints << /K 0 >> >> ] >> sam2p-0.49.2/examples/shot_fax32d_tiff.job0000644000175100017510000000052312211371426016475 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 22:13:03 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Indexed1 /TransferEncoding/MSBfirst /Compression/CCITTFax %/Compression/RLE /Hints << /K 5 >> % Group3 2D >> ] >> sam2p-0.49.2/examples/shot_fax4_tiff.job0000644000175100017510000000047212211371426016253 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 4 22:13:03 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF % /SampleFormat/Indexed8 /SampleFormat/Indexed1 /TransferEncoding/MSBfirst /Compression/CCITTFax /Hints << /K -1 >> % Group4 >> ] >> sam2p-0.49.2/examples/shot_gif.job0000644000175100017510000000037212211371426015145 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/shot_large.gif) %/OutputFile (examples/shot.gif) /OutputFile (test.gif) /Profile [ << /FileFormat/GIF89a /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/shot_i1.job0000644000175100017510000000032012211371426014702 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l118r_eps.job0000644000175100017510000000035712211371426016121 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Indexed1 /TransferEncoding/A85 /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l11bn_eps.job0000644000175100017510000000036312211371426016164 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/shot_l11br_eps.job0000644000175100017510000000036212211371426016167 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l11hr_eps.job0000644000175100017510000000035712211371426016201 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 1 21:56:11 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Indexed1 /TransferEncoding/Hex /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l1m8r_eps.job0000644000175100017510000000055712211371426016217 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:17:55 CEST 2002 % original (shot_mask.eps) by pts@fazekas.hu at Sat Mar 23 14:32:58 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Mask /TransferEncoding/A85 /Transparent % Means RGB color triplet #ff0080 /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l1mbn_eps.job0000644000175100017510000000056312211371426016262 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:16:11 CEST 2002 % original (shot_mask.eps) by pts@fazekas.hu at Sat Mar 23 14:32:58 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Mask /TransferEncoding/Binary /Transparent % Means RGB color triplet #ff0080 /Compression/None >> ] >> sam2p-0.49.2/examples/shot_l1mbr_eps.job0000644000175100017510000000056212211371426016265 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 2 15:16:11 CEST 2002 % original (shot_mask.eps) by pts@fazekas.hu at Sat Mar 23 14:32:58 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Mask /TransferEncoding/Binary /Transparent % Means RGB color triplet #ff0080 /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_l1mhr_eps.job0000644000175100017510000000053512211371426016273 0ustar ptspts<<%sam2p-job; by Sun Jun 2 15:17:43 CEST 2002 % original (shot_mask.eps) by pts@fazekas.hu at Sat Mar 23 14:32:58 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Mask /TransferEncoding/Hex /Transparent % Means RGB color triplet #ff0080 /Compression/RLE >> ] >> sam2p-0.49.2/examples/shot_pdfb.job0000644000175100017510000000045612211371426015316 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 20:55:37 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.pdf) % triggers Ghostscript 5.50 lowest-bit rendering bug /Profile [ << /FileFormat/PDFB1.2 /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/ZIP /Predictor 45 >> ] >> sam2p-0.49.2/examples/shot_pdfb_hex.job0000644000175100017510000000045312211371426016157 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sun Jun 23 19:18:10 CEST 2002 /InputFile (examples/shot.gif) /OutputFile (test.pdf) % triggers Ghostscript 5.50 lowest-bit rendering bug /Profile [ << /FileFormat/PDFB1.2 /SampleFormat/Indexed1 /TransferEncoding/Hex /Compression/ZIP /Predictor 45 >> ] >> sam2p-0.49.2/examples/shot_png.job0000644000175100017510000000034312211371426015162 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/shot_large.gif) /OutputFile (test.png) /Profile [ << /FileFormat/PNG /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/ZIP /Predictor 45 >> ] >> sam2p-0.49.2/examples/shot_ppm.job0000644000175100017510000000040712211371426015173 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Mar 23 14:32:58 CET 2002 /InputFile (examples/shot.gif) /OutputFile (test.ppm) /Profile [ << /FileFormat/PNM /SampleFormat/Rgb8 /TransferEncoding/ASCII % /TransferEncoding/Binary /Compression/None >> ] >> sam2p-0.49.2/examples/sziget_al.job0000644000175100017510000000045212211371426015323 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/sziget_al.ppm) %/InputFile (examples/sziget.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Mask /TransferEncoding/Binary % /Compression/RLE /Compression/LZW % /Compression/None >> ] >> sam2p-0.49.2/examples/sziget_al_pdf.job0000644000175100017510000000035512211371426016156 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Apr 20 20:49:05 CEST 2002 /InputFile (examples/sziget_al.ppm) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.0 /SampleFormat/Mask /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/sziget_ma.job0000644000175100017510000000032312211371426015321 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/sziget.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Mask /TransferEncoding/Binary /Compression/Fax >> ] >> sam2p-0.49.2/examples/transparent_tr.job0000644000175100017510000000033212211371426016405 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:54:01 CET 2002 /InputFile (examples/transparent.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Transparent /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/transparent_tr_pdf.job0000644000175100017510000000036012211371426017237 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 17 13:26:00 CEST 2002 /InputFile (examples/transparent.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDFB1.2 /SampleFormat/Transparent /TransferEncoding/Binary /Compression/ZIP >> ] >> sam2p-0.49.2/examples/xv_cant_display_eps.job0000644000175100017510000000055612211371426017405 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 11:38:37 CEST 2002 /InputFile (examples/xv_cant_display.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 % /SampleFormat/Rgb8 % /SampleFormat/Indexed8 % /SampleFormat/Gray1 /SampleFormat/Transparent2 /TransferEncoding/Binary /Compression/RLE % /Transparent null >> ] >> sam2p-0.49.2/examples/xv_cant_display_eps_gray.job0000644000175100017510000000055712211371426020430 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 15:16:11 CEST 2002 /InputFile (examples/xv_cant_display.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Gray1 % /SampleFormat/Indexed8 % /SampleFormat/Gray1 % /SampleFormat/Transparent2 /TransferEncoding/Binary /Compression/RLE % /Transparent null >> ] >> sam2p-0.49.2/examples/xv_cant_display_eps_rgb.job0000644000175100017510000000055612211371426020237 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 11:38:37 CEST 2002 /InputFile (examples/xv_cant_display.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL2 /SampleFormat/Rgb8 % /SampleFormat/Indexed8 % /SampleFormat/Gray1 % /SampleFormat/Transparent2 /TransferEncoding/Binary /Compression/RLE % /Transparent null >> ] >> sam2p-0.49.2/examples/xv_cant_display_gif.job0000644000175100017510000000056012211371426017356 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Sat Jun 15 12:18:10 CEST 2002 /InputFile (examples/xv_cant_display.gif) /OutputFile (test.gif) /Profile [ << /FileFormat/GIF89a % /SampleFormat/Rgb8 % /SampleFormat/Indexed8 % /SampleFormat/Gray1 /SampleFormat/Transparent2 /TransferEncoding/Binary /Compression/LZW % /Transparent null >> ] >> sam2p-0.49.2/examples/yellow_gif.job0000644000175100017510000000034512211371426015503 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/yellow_large.gif) /OutputFile (examples/yellow.gif) /Profile [ << /FileFormat/GIF89a /SampleFormat/Indexed1 /TransferEncoding/Binary /Compression/LZW >> ] >> sam2p-0.49.2/examples/yellow_op.job0000644000175100017510000000061312211371426015352 0ustar ptspts<<%sam2p-job; by Fri Mar 22 17:36:41 CET 2002 /InputFile (examples/yellow.gif) /OutputFile (test.eps) /Profile [ << /FileFormat/PSL1 /SampleFormat/Opaque /TransferEncoding/Binary /Compression/RLE >> % << /FileFormat/PSL1 /SampleFormat/Transparent /TransferEncoding/Binary /Compression/RLE >> % << /FileFormat/PSL2 /SampleFormat/Indexed2 /TransferEncoding/Binary /Compression/RLE >> ] >> sam2p-0.49.2/examples/yellow_op_pdf.job0000644000175100017510000000034212211371426016202 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Wed Apr 17 13:15:22 CEST 2002 /InputFile (examples/yellow.gif) /OutputFile (test.pdf) /Profile [ << /FileFormat/PDF1.0 /SampleFormat/Opaque /TransferEncoding/AHx /Compression/RLE >> ] >> sam2p-0.49.2/examples/yellow_rle_tiff.job0000644000175100017510000000042212211371426016524 0ustar ptspts<<%sam2p-job; by pts@fazekas.hu at Tue Jun 11 20:36:42 CEST 2002 /InputFile (examples/yellow.gif) /OutputFile (test.tiff) /Profile [ << /FileFormat/TIFF /SampleFormat/Indexed8 % /SampleFormat/Rgb8 /TransferEncoding/LSBfirst /Compression/RLE >> ] >> sam2p-0.49.2/bts.ttt0000644000175100017510000013657312211371426012373 0ustar ptspts% % bts.ttt -- Built-in TemplateS, contains most .tte and .ttm files % by pts@math.bme.hu at Wed Apr 17 10:37:42 CEST 2002 % Sat Jun 1 18:40:04 CEST 2002 % ADSC fixups at Sun Jun 23 18:16:29 CEST 2002 % fixed %%EndComments, bts2.ttt at Sun Sep 22 14:25:45 CEST 2002 % /l148z, /l1thl at ... % % These OutputFile-generation templates will be built in to the sam2p % executable at compile time. The contents of this file can be referenced as % `(%bts) run' in .job files. % % _l23_ /l23 (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: `0 %%EndComments %%Page: 1 1 save`s 9 dict begin {/T currentfile`T def`1setcolorspace /F T`F def <> image `t} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l23_ /l23mask (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: `0 %%EndComments %%Page: 1 1 save`s 9 dict begin {`r setrgbcolor /T currentfile`T def /F T`F def `w `h false[1 0 0 -1 0 `h]F imagemask `t} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l23_ /l23ind1 (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: `0 %%EndComments %%Page: 1 1 save`s 9 dict begin {`R/T currentfile`T def /F T`F def `w `h true[1 0 0 -1 0 `h]F imagemask `t} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % Dat: vvv last color not necessarily transparent % T `P string readstring pop dup length 0 exch 3 sub getinterval % Used by /Transparent2, /Transparent4 and /Transparent8. % This implemetation does: % rgb-palette imagemask-newcompress-transfer % Alternative implementation (not this one!): % ( rgb-transfer imagemask-newcompress-transfer )* % It would be tedious to flush buffers etc. % Doesn't work with JPEG compressions, because JPEG requires a bit depth of % 8. Works with any other /Compression and any /Predictor. % _l23_ /l23tran2 (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: `0 %%EndComments %%Page: 1 1 save`s 9 dict begin {/T currentfile`T def T `P string readstring pop 0 `p getinterval /F T`F def /m 0 def {255 div m 1 add dup 3 eq{pop setrgbcolor `w `h false[1 0 0 -1 0 `h]F imagemask 0}if/m exch def}forall `t} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l23_ % With old (pre-Wed Feb 5 17:46:59 CET 2003) PDF code, /Length was one less, % because it hasn't counted the last \n newline in the content stream. This % made a problem with pdfTeX 0.12 shipped with Debian Slink. % Old code (focus on the \n's) %[ (3 0 obj\n<>\nstream\n) %3 %[ (q`s\n`w 0 0 `h 0 0 cm /S Do Q) ] %4.0 %(\nendstream\nendobj\n) %5 % At Fri Feb 7 11:56:14 CET 2003 modified all /MediaBox specifications to % precede the image data, and be in a separate line, to ease parsing. % vvv tested at Sat Jan 8 12:31:00 CET 2005 /p02 [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 18:33:30 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`w 0 0 `h 0 0 cm /S Do Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>stream\n) %10 [ (`S) ] %11 (\nendstream\nendobj\n) %12 [ (5 0 obj\n<>/ProcSet[/PDF`C]>>/Contents 3 0 R>>\n endobj\n) ] % 13 (xref\n0 6\n0000000000 65535 f \n) %14 7 %15 ( 00000 n \n) %16 1 %17 ( 00000 n \n) %18 2 %19 ( 00000 n \n) %20 8 %21 ( 00000 n \n) %22 13 %23 ( 00000 n \ntrailer\n<>\nstartxref\n) %24 14 %25 (\n%%EOF\n) %26 ] % _l23_ % vvv tested at Sat Jan 8 12:31:00 CET 2005 /p02mask [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 20:34:35 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`g rg `w 0 0 `h 0 0 cm /S Do Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>stream\n) %10 [ (`S) ] %11 (\nendstream\nendobj\n) %12 [ (5 0 obj\n<>/ProcSet[/PDF`C]>>/Contents 3 0 R>>\nendobj\n) ] %14 (xref\n0 6\n0000000000 65535 f \n) %15 7 %16 ( 00000 n \n) %17 1 %18 ( 00000 n \n) %19 2 %20 ( 00000 n \n) %21 8 %22 ( 00000 n \n) %21 13 %22 ( 00000 n \ntrailer\n<>\nstartxref\n) %23 14 %24 (\n%%EOF\n) %25 ] % _l23_ % vvv tested at Sat Jan 8 12:31:00 CET 2005 /p02maskbb [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 18:36:35 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`g rg `w 0 0 `h 0 0 cm\nBI/W `w/H `h/ImageMask true/BPC 1`F ID `S EI\nQ\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % _l23_ /p02ind1 [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 20:34:35 CEST 2002 % vvv tested at Sat Jan 8 12:31:00 CET 2005 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 % `G rg 0 0 `w `h re B [ (q`s `G rg 0 0 m `w 0 l `w `h l 0 `h l F `g rg `w 0 0 `h 0 0 cm /S Do Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>stream\n) %10 [ (`S) ] %11 (\nendstream\nendobj\n) %12 [ (5 0 obj\n<>/ProcSet[/PDF`C]>>/Contents 3 0 R>>\nendobj\n) ] %13 (xref\n0 6\n0000000000 65535 f \n) %14 7 %15 ( 00000 n \n) %16 1 %16 ( 00000 n \n) %17 2 %18 ( 00000 n \n) %18 8 %19 ( 00000 n \n) %20 13 %21 ( 00000 n \ntrailer\n<>\nstartxref\n) %22 14 %23 (\n%%EOF\n) %24 ] % _l23_ % vvv tested at Sat Jan 8 12:31:00 CET 2005 /p02ind1bb [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 18:36:35 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 % `G rg 0 0 `w `h re B [ (q`s `G rg 0 0 m `w 0 l `w `h l 0 `h l F `g rg `w 0 0 `h 0 0 cm\nBI/W `w/H `h/ImageMask true/BPC 1`F ID `S EI\nQ\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % _l23_ % vvv tested at Sat Jan 8 12:31:00 CET 2005 /p02bb [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 18:36:35 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`w 0 0 `h 0 0 cm\nBI/Interpolate false/W `w/H `h/CS`1/BPC `b`F ID `S EI\nQ\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % Dat: /Kids with direct objects are not valid PDF % (reported by Sid Steward) % The PDF Reference 1.5 (and 1.3) actually describes the page Kids array % as: "An array of indirect references to the immediate children of this % node. The children may be page objects or other page tree nodes." %/pd02bb [%sam2p-ttm; by pts@fazekas.hu at Sat Apr 20 18:36:35 CEST 2002 %(%PDF-1.`0\n`B) %0 %[ (2 0 obj\n<>/Contents %3 0 R>>]/Count 1>>\nendobj\n) ] %1 %[ (3 0 obj\n<>\nstream\n) %4 %[ (q`s\n`w 0 0 `h 0 0 cm\nBI/Interpolate false/W `w/H `h/CS`1/BPC `b`F ID %`S %EI\nQ\n) ] %5.0 %(endstream\nendobj\n) %6 %[ (1 0 obj\n<>\nendobj\n) ] %7.0 %(xref\n0 4\n0000000000 65535 f \n) %8 %7 %9: offset of chunk 7, printf("%010u") %( 00000 n \n) %10 %1 %11 %( 00000 n \n) %12 %2 %13 %( 00000 n \ntrailer\n<>\nstartxref\n) %14 %8 %15 %(\n%%EOF\n) %16 %] % --- % _l2jbin_ /l2jbin (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 2 %%EndComments %%Page: 1 1 save`s 2 dict begin {/Device`d setcolorspace /T currentfile`T def /F T/DCTDecode filter def <> image`t} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l2jbin_ /p0jbin [%sam2p-ttm; by pts@fazekas.hu at Mon Apr 15 21:58:26 CEST 2002 (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`w 0 0 `h 0 0 cm /S Do Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>stream\n) %10 [ (`S) ] %11 (\nendstream\nendobj\n) %12 [ (5 0 obj\n<>/ProcSet[/PDF`C]>>/Contents 3 0 R>>\nendobj\n) ] %13 (xref\n0 6\n0000000000 65535 f \n) %14 7 %15 ( 00000 n \n) %16 1 %17 ( 00000 n \n) %18 2 %19 ( 00000 n \n) %20 8 %21 ( 00000 n \n) %22 13 %23 ( 00000 n \ntrailer\n<>\nstartxref\n) %24 14 %25 (\n%%EOF\n) %26 ] % _l2jbin_ /p0jbb [%sam2p-ttm; by pts@fazekas.hu at Mon Apr 15 21:58:26 CEST 2002 % Dat: CropBox is required by buggy gs/gv viewer code (%PDF-1.`0\n`B) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s\n`w 0 0 `h 0 0 cm\nBI/W `w/H `h/CS/Device`d/BPC `b`F ID `S EI\nQ\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % --- % _l1tr_ /l1tr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 showpage %%Trailer %%EOF\n) % _l1tr_ /l1op (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s `r setrgbcolor 0 0 moveto `w 0 lineto 0 `h rlineto -`w 0 rlineto closepath fill restore showpage %%Trailer %%EOF\n) % by pts@fazekas.hu at Sat Jun 15 16:09:25 CEST 2002 % _l1tr_ /l1bb (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 0 0 moveto `w 0 lineto 0 `h rlineto -`w 0 rlineto closepath stroke restore showpage %%Trailer %%EOF\n) % _l1tr_ /p0op [%sam2p-ttm; by pts@fazekas.hu at Wed Apr 17 10:34:36 CEST 2002 (%PDF-1.0\n) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 % [ (q `g rg 0 0 `w `h re B Q) ] %4.0 % ^^^ SUXX `re' draws a rectangle with black border in acroread :-( [ (q `g rg 0 0 m `w 0 l `w `h l 0 `h l F Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % /p0bb: draws the bounding box (./sam2p -s:bbox examples/yellow.gif test.pdf), % see also /l1bb. Half of the linewidth is cropped by /MediaBox /p0bb [%sam2p-ttm; by pts@fazekas.hu at Sat Jun 15 16:08:38 CEST 2002 (%PDF-1.0\n) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ (q`s `g rg 0 0 m `w 0 l `w `h l 0 `h l S Q\n) ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %15 8 %16 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % _l1tr_ /p0tr [%sam2p-ttm; by pts@fazekas.hu at Wed Apr 17 10:34:36 CEST 2002 (%PDF-1.0\n) %0 [ (2 0 obj\n<>\nendobj\n) ] %1 [ (3 0 obj\n<>\nstream\n) %4 [ ] %5.0 (endstream\nendobj\n) %6 [ (1 0 obj\n<>\nendobj\n) ] %7.0 [ (4 0 obj\n<>/Contents 3 0 R>>\nendobj\n) ] %8 (xref\n0 5\n0000000000 65535 f \n) %9 7 %10: offset of chunk 7, printf("%010u") ( 00000 n \n) %11 1 %12 ( 00000 n \n) %13 2 %14 ( 00000 n \n) %14 8 %15 ( 00000 n \ntrailer\n<>\nstartxref\n) %17 9 %18 (\n%%EOF\n) %19 ] % --- % at Sun Jun 2 15:49:39 CEST 2002 % derived from /l1m8r % _l1c_ /l1t8r (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 36 dict begin `r setrgbcolor /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E /B `? " E/L 128 " E/Ex()E `P " u ? 1 - 0 c 1 c{d 3 y put O O}for 0 `p ;/m 0 E{255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; u ? 1 - 0 c 1 c{d 3 y put O O}for}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}imagemask 0}if/m c E}forall d O d O}bind exec}{ T `P " readstring O 0 `p ;/m 0 E/F T/RunLengthDecode filter E {255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]F imagemask 0}if/m c E}forall F closefile T closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 15:49:46 CEST 2002 % derived from /l1mhr % _l1c_ /l1thr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 36 dict begin `r setrgbcolor /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ /C(.)E/d{A C S O 0 get}E /B `? " E/L 128 " E/Ex()E A `P " S O 0 `p ;/m 0 E{255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; A c S O}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}imagemask 0}if/m c E}forall d O A read O O}bind exec}{ T `P " readstring O 0 `p ;/m 0 E/F T/RunLengthDecode filter E {255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]F imagemask 0}if/m c E}forall F closefile T closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 15:49:59 CEST 2002 % derived from /l1mbr % _l1c_ /l1tbr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 36 dict begin `r setrgbcolor /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ /B `? " E/L 128 " E/Ex()E A `P " S O 0 `p ;/m 0 E{255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i A read O u 128 le{L c 0 c 1 + ; A c S O}{L c A read O c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}imagemask 0}if/m c E}forall A read O O}bind exec}{ O/F A/RunLengthDecode filter E A `P " S O 0 `p ;/m 0 E{255 div m 1 + u 3 eq{O setrgbcolor `w `h false[1 0 0 -1 0 `h]F imagemask 0}if/m c E}forall F closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % PSL1 implementation of /l23tran2 /A85 % _l1c_ /l1t8n (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 16 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /d{{27 S ge{exit}if A read not{511}if dup 122 eq{/S 27 E/D 0 E/C 0 E}{dup 117 gt{A read{pop}if/S 54 S sub E}{dup 33 ge{S 32 eq{dup/C c E/D -1670420001 E}{dup 117 sub{1 85 7225 614125}S 28 sub get mul D add/D c E}i/S S 1 sub E}if}i}i pop} loop S 22 eq{511}{C 1868977 mul D add S 24 and neg bitshift 23 S lt{C 3 mul add }if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 sub}i}i E}i}bind E /s `? string E {`P string dup length 1 sub 0 c 1 c{d 3 copy put pop pop}for 0 `p getinterval /m 0 E {255 div m 1 add dup 3 eq{pop setrgbcolor `w `h false[1 0 0 -1 0 `h] {s dup length 1 sub 0 c 1 c{d 3 copy put pop pop}for}imagemask 0}if/m exch def}forall d pop}bind %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % PSL1 implementation of /l23tran2 /Hex % _l1c_ /l1thn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 2 dict begin /s `? string def {currentfile `P string readhexstring pop 0 `p getinterval /m 0 def {255 div m 1 add dup 3 eq{pop setrgbcolor `w `h false[1 0 0 -1 0 `h] {currentfile s readhexstring pop}imagemask 0}if/m exch def}forall currentfile read pop pop}bind %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % PSL1 implementation of /l23tran2 /Binary % Used by /Transparent2, /Transparent4 and /Transparent8. % This implemetation does: % rgb-palette imagemask-newcompress-transfer % _l1c_ /l1tbn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 %%EndComments %%Page: 1 1 save`s 2 dict begin /s `? string def {currentfile `P string readstring pop 0 `p getinterval /m 0 def {255 div m 1 add dup 3 eq{pop setrgbcolor `w `h false[1 0 0 -1 0 `h] {currentfile s readstring pop}imagemask 0}if/m exch def}forall}bind %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 15:21:53 CEST 2002 % derived from /l118r % l1g8r: /Compression/RLE /TransferEncoding/A85 /SampleFormat/Gray* /FileFormat/PSL1 % _l1c_ /l1g8r (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R26 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E /B `? " E/L 128 " E/Ex()E `w `h `b[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; u ? 1 - 0 c 1 c{d 3 y put O O}for}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}`i d O d O}bind exec}{ /F T/RunLengthDecode filter def `w `h `b[1 0 0 -1 0 `h]F `i F closefile T closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 15:22:10 CEST 2002 % derived from /l1ghr % _l1c_ /l1ghr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R26 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ /C(.)E/d{A C S O 0 get}E /B `? " E/L 128 " E/Ex()E `w `h `b[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; A c S O}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}`i d O A read O O}bind exec}{ /F T/RunLengthDecode filter def `w `h `b[1 0 0 -1 0 `h]F `i F closefile T closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 15:22:21 CEST 2002 % derived from /l11br % _l1c_ /l1gbr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R26 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/RunLengthDecode filter/F exch def}stopped /B exch def cleartomark B{{ /B `? " E/L 128 " E/Ex()E `w `h `b[1 0 0 -1 0 `h]{B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i A read O u 128 le{L c 0 c 1 + ; A c S O}{L c A read O c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B}`i A read O O}bind exec}{ `w `h `b[1 0 0 -1 0 `h]F `i F closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % l1g8n: /Compression/None /TransferEncoding/A85 /SampleFormat/Gray* /FileFormat/PSL1 % _l1c_ /l1g8n (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R16 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E{ {mark A/ASCII85Decode filter/F exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if dup 122 eq{/S 27 E/D 0 E/C 0 E}{dup 117 gt{A read{pop}if/S 54 S sub E}{dup 33 ge{S 32 eq{dup/C c E/D -1670420001 E}{dup 117 sub{1 85 7225 614125}S 28 sub get mul D add/D c E}i/S S 1 sub E}if}i}i pop} loop S 22 eq{511}{C 1868977 mul D add S 24 and neg bitshift 23 S lt{C 3 mul add }if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 sub}i}i E}i}bind E /s `? string E `w `h `b[1 0 0 -1 0 `h] {s dup length 1 sub 0 c 1 c{d 3 copy put pop pop}for}`i d pop}bind exec}{ `w `h `b[1 0 0 -1 0 `h]F `i F closefile}i} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l1c_ /l1ghn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R1 dict begin /s `? string def {`w `h `b[1 0 0 -1 0 `h]{currentfile s readhexstring pop}`i currentfile read pop pop}bind %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % _l1c_ /l1gbn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s `R1 dict begin /s `? string def {`w `h `b[1 0 0 -1 0 `h]{currentfile s readstring pop}`i}bind %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sat Jun 1 21:19:30 CEST 2002 % _l1c_ /l128r (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 12 " u/B c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; u ? 1 - 0 c 1 c{d 3 y put O O}for}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage d O d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:19:02 CEST 2002 % derived from /l128r % _l1c_ /l12hr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ /C(.)E/d{A C S O 0 get}E A 12 " u/B c E 0 `p ; S O O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; A c S O}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage d O A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:41:59 CEST 2002 % derived from /l12hr % _l1c_ /l12br (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter}stopped /B exch def cleartomark B{{ A 12 " u/B c E 0 `p ; S O O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i A read O u 128 le{L c 0 c 1 + ; A c S O}{L c A read O c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - A `p " S O]setcolorspace /F A/RunLengthDecode filter def<> image F closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 12:00:13 CEST 2002 % _l1c_ /l128n (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 12 " u/B c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 B u ? 1 - 0 c 1 c{d 3 y put O O}for {12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:31:07 CEST 2002 % derived from /l128n % _l1c_ /l12hn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ A 12 " u/B c E 0 `p ; S O O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 A B S O {12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 00:05:36 CEST 2002 % _l1c_ /l148r (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 48 " u/B c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; u ? 1 - 0 c 1 c{d 3 y put O O}for}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage d O d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:26:37 CEST 2002 % derived from /l148r % _l1c_ /l14hr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ /C(.)E/d{A C S O 0 get}E A 48 " u/B c E 0 `p ; S O O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; A c S O}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage d O A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:49:40 CEST 2002 % derived from /l14hr % _l1c_ /l14br (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ A 48 " u/B c E 0 `p ; S O O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{B3 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i A read O u 128 le{L c 0 c 1 + ; A c S O}{L c A read O c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage A read O O}bind exec}{ O[/Indexed/DeviceRGB `# 1 - A `p " S O]setcolorspace /F A/RunLengthDecode filter def<> image F closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 12:13:50 CEST 2002 % _l1c_ /l148n (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 48 " u/B c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 B u ? 1 - 0 c 1 c{d 3 y put O O}for {6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:34:26 CEST 2002 % derived from /l148n % _l1c_ /l14hn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ A 48 " u/B c E 0 `p ; S O O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 A B S O {6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 00:05:36 CEST 2002 % _l1c_ /l188r (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 768 " u/H c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O /B `w " E/R `w 3 * " E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{R 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; u ? 1 - 0 c 1 c{d 3 y put O O}for}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage d O d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 00:05:36 CEST 2002 % derived from /l188r % _l1c_ /l18hr (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ /C(.)E/d{A C S O 0 get}E A 768 " u/H c E 0 `p ; S O O/B `w " E/R `w 3 * " E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{R 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i d u 128 le{L c 0 c 1 + ; A c S O}{L c d c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage d O A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace /F T/RunLengthDecode filter def<> image F closefile T closefile }ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 00:05:36 CEST 2002 % derived from /l18hr % _l1c_ /l18br (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ A 768 " u/H c E 0 `p ; S O O/B `w " E/R `w 3 * " E/L 128 " E/Ex()E `w `h 8[1 0 0 -1 0 `h]{R 0 B Ex{2 y ? c ? ge{2 y c ? 0 c ; 2 index y ? 2 y c ? c - ;/Ex c E O exit}{2 y c y O ? 2 y c ? c - ;}i A read O u 128 le{L c 0 c 1 + ; A c S O}{L c A read O c 257 c - 3 y 1 - -1 0{3 y c put O}for O O c O 0 c ;}i}loop B{3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage A read O O}bind exec}{ O[/Indexed/DeviceRGB `# 1 - A `p " S O]setcolorspace /F A/RunLengthDecode filter def<> image F closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 12:14:04 CEST 2002 % derived from /l188r % _l1c_ /l188n (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S 32 E/D 0 E/C 0 E /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCII85Decode filter/T exch def}stopped /B exch def cleartomark B{{ /d{{27 S ge{exit}if A read not{511}if u 122 eq{/S 27 E/D 0 E/C 0 E}{u 117 gt{ A read{O}if/S 54 S - E}{u 33 ge{S 32 eq{u/C c E/D -1670420001 E}{u 117 -{1 85 7225 614125}S 28 - get * D +/D c E}i/S S 1 - E}if}i}i O}loop S 22 eq{511}{C 1868977 * D + S 24 and neg b 23 S lt{C 3 * +}if 255 and/S S 3 eq{32}{S 7 mod 3 eq{22}{S 8 -}i}i E}i}E 768 " u/H c E 0 `p ; u ? 1 - 0 c 1 c{d 3 y put O O}for O/B `w " E/R `w 3 * " E `w `h 8[1 0 0 -1 0 `h]{R 0 B u ? 1 - 0 c 1 c{d 3 y put O O}for {3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage d O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 12:25:13 CEST 2002 % derived from l188n % _l1c_ /l18hn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/d/readhexstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ {mark A/ASCIIHexDecode filter/T exch def}stopped /B exch def cleartomark B{{ A 768 " u/H c E 0 `p ; d O O/B `w " E/R `w 3 * " E `w `h 8[1 0 0 -1 0 `h]{R 0 A B d O {3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage A read O O}bind exec}{ [/Indexed/DeviceRGB `# 1 - T `p " readstring O]setcolorspace <>image T closefile}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:45:14 CEST 2002 % derived from /l12hn % _l1c_ /l12bn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ A 12 " u/B c E 0 `p ; S O O/H 3072 " E/R 0 E 0 1 255{u -6 b B c 3 * 3 ; H c R c p/R R 3 + E u -4 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E u -2 b 3 and B c 3 * 3 ; H c R c p/R R 3 + E 3 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 3 + -2 b " E/B3 B ? 2 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 A B S O {12 * H c 12 ; 3 y p O 12 +}forall O O R}false 3 colorimage}bind exec}{ O[/Indexed/DeviceRGB `# 1 - A `p " S O]setcolorspace <>image}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 14:47:31 CEST 2002 % derived from /l14hn % _l1c_ /l14bn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/S/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ A 48 " u/B c E 0 `p ; S O O/H 1536 " E/R 0 E 0 1 255{u -4 b B c 3 * 3 ; H c R c p/R R 3 + E 15 and B c 3 * 3 ; H c R c p/R R 3 + E }for/B `w 1 + -1 b " E/B3 B ? 1 b 3 * " E/R B3 0 `w 3 * ; E `w `h 8[1 0 0 -1 0 `h]{B3 0 A B S O {6 * H c 6 ; 3 y p O 6 +}forall O O R}false 3 colorimage}bind exec}{ O[/Indexed/DeviceRGB `# 1 - A `p " S O]setcolorspace <>image}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % at Sun Jun 2 12:25:13 CEST 2002 % BUGFIX at Sun Sep 22 20:02:47 CEST 2002 % derived from l18hn % _l1c_ /l18bn (%!PS-Adobe-3.0`E %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 save`s 36 dict begin /x{load def}def/E/def x/A/currentfile x/c/exch x/i/ifelse x/d/readstring x /;/getinterval x/p/putinterval x/b/bitshift x/+/add x/O/pop x/*/mul x/u/dup x /-/sub x/"/string x/?/length x/y/copy x{ /filter where not{{ A 768 " u/H c E 0 `p ; d O O/B `w " E/R `w 3 * " E `w `h 8[1 0 0 -1 0 `h]{R 0 A B d O {3 * H c 3 ; 3 y p O 3 +}forall O O R}false 3 colorimage}bind exec}{ O[/Indexed/DeviceRGB `# 1 - A `p " d O]setcolorspace <>image}ifelse} %%BeginData:; exec `S %%EndData end restore showpage %%Trailer %%EOF\n) % long before Sun Sep 22 13:57:08 CEST 2002 % /lcrb -> l1gbn % /lcr8 -> l1g8n % /lcrh -> l1ghn % --- % Templates missing from this file: % l1g8z: /Compression/ZIP /TransferEncoding/A85 /SampleFormat/Gray* /FileFormat/PSL1 % (formerly l1fa85g.tte, now: l1zip.psm) % l1ghz: /Compression/ZIP /TransferEncoding/Hex /SampleFormat/Gray* /FileFormat/PSL1 % l1gbz: /Compression/ZIP /TransferEncoding/Binary /SampleFormat/Gray* /FileFormat/PSL1 % l1g8l: /Compression/LZW /TransferEncoding/A85 /SampleFormat/Gray* /FileFormat/PSL1 % (formerly l1fa85g.tte, now: l1lzw.psm) % l1ghl: /Compression/LZW /TransferEncoding/Hex /SampleFormat/Gray* /FileFormat/PSL1 % l1gbl: /Compression/LZW /TransferEncoding/Binary /SampleFormat/Gray* /FileFormat/PSL1 %%EOF sam2p-0.49.2/l1zip.psm0000644000175100017510000014216012211371426012613 0ustar ptspts/*% % l1zip.psm -- /FlateDecode image data implementation for /PSL1 % by pts@fazekas.hu at Sun Sep 22 01:01:00 CEST 2002 % formerly flatedecode.psm -- please run faltedecode_eps_helper.sh... % by pts@fazekas.hu at Fri Sep 20 23:31:36 CEST 2002 % -- Sat Sep 21 01:11:10 CEST 2002 % doesn't work -- Sat Sep 21 02:52:36 CEST 2002 % disallow preread==8, allow preread==0 WORKS -- Sat Sep 21 20:22:07 CEST 2002 % derived from statecat.psm -- a stateful, faster minimalistic zcat (gzip -cd) % implementation, implemented in pure PostScript LanguageLevel1 (Run % through cpp (C preprocessor) to get the PostScript file % statecat.psm by pts@fazekas.hu % originally rcm.c % original author: Ron McFarland , 1996 % formally muzcat.c (at Tue Dec 25 11:07:47 CET 2001) % based on statecat.ps.3 by pts@fazekas.hu % rewritten, restructured and extended at Tue Dec 25 21:00:33 CET 2001 % translated to PostScript except fvWork at Tue Dec 25 23:11:31 CET 2001 % translated to PostScript altogether at Thu Dec 27 01:10:58 CET 2001 % translation works with `cat random.file.gz random.file.gz'' at Thu Dec 27 14:19:36 CET 2001 % Thu Dec 27 18:37:03 CET 2001: % statecat.ps: 1071960 ms user time (249.293 times slower than gunzip) % function inlining at Thu Dec 27 21:51:45 CET 2001 % shorter keywords at Thu Dec 27 23:52:46 CET 2001 % at Sat Feb 23 17:05:43 CET 2002: % statecat.ps originally: 5388 bytes % after eliminate-NULLs trick: 5349 bytes % after anti-32768... trick 5229 bytes % 5041 %*/ /* % Imp: more efficient optimize CFG_FMT_ZLIB_ONLY % Imp: do `F closefile', `T closefile' in % % Not: don't inline TE_read for USE_HEXD (15*5 bytes for ACSO0g is not tolerable) % OK : verify a85_getc for really eating EOD (~>) chars % OK : find and catalogize `|' and other one-char abbrs % OK : shorter operator names (i.e `E' for `def', as in test_vm_eps.eps) % OK : shorter var names (such as `preread', `past') % Not: make global vars numbered, not named... % OK : make constU[]-3 a string, not an array % OK : make constW, constP, constL strings, not arrays % Imp: inline all except fvMktree (too long), fvFree (recursive) and fvWork (too long) % OK : verify, examine StateCatDict (45) % OK : find unused vars (such as `moo') in StateCatDict % OK : is constM or 1<< faster?? (decided 1<<) % OK : anti-`/z 42 eq', ensure `eq' compares numbers (INT_EQ) % OK : verify if/ifelse for ENDIF % OK : verify direction of `for's % OK : eliminate `stopped' context because it catches errors % OK : clear stack before `exit' % OK : verify `/name' against `name'; grep m@/@ % OK : verify that `}' is followed by correct if|ifelse|def|bind|stopped|loop|for % % Typical error: syntax: /^#/ % Typical error: syntax: m@/ +\w@ % Typical error: mispelling % Typical error: missing `pop' at `dup ... eq{exit}if' % Typical error: missing `for|if|...' after '}' */ #include "psmlib.psm" #if USE_A85D #else #if USE_HEXD #else #define USE_BINARY 1 #endif #endif #if USE_NO_BIND #define BIND_DEF def #else #define BIND_DEF bind def #endif /* --- .pin begins */ % %!PS-Adobe-3.0`E %%Inflater: pts@fazekas.hu l1zip.psm %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 % % save`s `R % /* 88 dict dup /TokDict exch def begin */ % begin % % % best to make it first % % best to make it second % % % % % % % % % % /*!=LZW*/ % /*!=LZW*/ % % % % % % % % % % % % #if 0 /* important in LZW, but not in Flate */ % % % % #endif #if USE_A85D % % % % #endif #if USE_HEXD % % % % #endif #if USE_BINARY % #if USE_PALETTE % #endif % % #endif #if USE_SHORT_NAMES % Free for short names: *?\^_`| BFGIKLMNPQRTUVWYZ efhklmnopqrsvwz % Numerical comments denote # calls or # accesses % : B: TokSubs % /* F must be overridden with array to avoid early TokSubs */ % : G % % ? + 3 % % % 5 % % 5 % % % % 6 % % 6 % /* T must be overridden with array to avoid early TokSubs */ % % 5 % % 5 % % 7 /* formerly: C */ % % 4 % % % 7 % % % % 4 % % 3 % % % 6 % % % % % 10 % % % % 6 % /* % % 3 */ /* not a function anymore */ % % 1 % % 1 % % #endif % #if USE_CURRENTFILE #define STDIN currentfile #endif % #if USE_DEBUG2 /FP /fileposition x #endif #if USE_BINARY {mark /F currentfile/FlateDecode filter def}stopped #endif #if USE_A85D {mark /T currentfile/ASCII85Decode filter def /F T/FlateDecode filter def}stopped #endif #if USE_HEXD {mark /T currentfile/ASCIIHexDecode filter def /F T/FlateDecode filter def}stopped #endif /Z exch def cleartomark /G{`i}def % image, imagemask or `false 3 colorimage` `w `h `b[1 0 0 -1 0 `h] #if USE_TRUE true #else Z #endif % % 32768 string dup /Sbuf exch def % % fvMain % % F G F closefile #if !USE_BINARY T closefile #endif % #define ZZZ_ASET(aname,idx,b) aname idx b put #define ZZZ_AREF(aname,idx) aname idx get #define PASS #define GLOBAL_VAR0(t,name) #define SLOCAL_VAR0(t,name) #define GLOBAL_VAR(t,name) /name null def #define SLOCAL_VAR(t,name) /name null def #define GLOBAL_ARRAY(t,name,size) /name size t def #define LOCAL_VAR(a,b) #if 0 /* LINE_DEBUG */ #define put (put:__LINE__) === put #define get (get:__LINE__) === get #endif % % Imp: F closefile, T closefile /* We must define constants and global arrays first. */ #define NULL 0 #define NODESIZE 1998 /* NODESIZE%3==0 */ /** Binary (Huffman) tree of nodes. */ GLOBAL_ARRAY(array,N,NODESIZE) /** * Contains the code word lengths used for Huffman code generation in * fvMktree(). 320==288+32. 320 is large enough to hold both the code lengths * of the literal--length (288) and the distance (32) Huffman trees -- and * large enough to hold the auxilary Huffman tree (used for building the * real tree) of length 19. */ GLOBAL_ARRAY(array,Z,320) GLOBAL_ARRAY(array,Bary,17) GLOBAL_ARRAY(array,Gary,17) #if CFG_NO_VAR_S #else GLOBAL_ARRAY(string,Sbuf,32768) #endif /constZ19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 packedarray def #if USE_HEXD /C(.)def #endif { /* We start declaring functions inside the brace */ #define constW { 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15 } /* 19 packedarray def */ #define constU { 3 4 5 6 7 8 9 10 11 13 15 17 19 23 27 31 35 43 51 59 67 83 99 115 131 163 195 227 258 } /* 29 packedarray def */ #define constP { 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 0 } /* 29 packedarray def */ #define constQ { 1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 257 385 513 769 1025 1537 2049 3073 4097 6145 8193 12289 16385 24577 } /* 30 packedarray def */ #define constL { 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 } /* 30 packedarray def */ #if 0 #define constM { 0 1 3 7 15 31 63 127 255 511 1023 2047 4095 8191 } /* 14 packedarray def */ #endif #if USE_A85D GLOBAL_VAR0(SINT32,xS) /* Variable `xS' was formerly called: `sx' */ GLOBAL_VAR0(SINT32,xD) /* Variable `xD' was formerly called: `dx' */ GLOBAL_VAR0(SINT32,xC) /* Variable `xC' was formerly called: `c0' */ /** - a85_getc <0..255|511> * Reads a char from `currentfile' as /ASCII85Decode */ /a85_getc{ % Simple getchar() of ASCII85Decode filter :-)), formerly /d PSM_A85_GETC }BIND_DEF #endif #if USE_NO_EOF #define my_getchar() TE_read( ) #define my_ignorechar() TE_read(pop) #else #define my_getchar() TE_read() {511}ifelse #define my_ignorechar() TE_read(pop) if #endif /** Index of the first free node in N. */ GLOBAL_VAR0(WORD,Dvar) GLOBAL_VAR0(WORD,Tvar) /* index (in S) of the first free position, [0..32767] */ /* GLOBAL_VAR(NODEN,no) -- unused */ /* GLOBAL_VAR(WORD,roo) -- unused */ /* GLOBAL_VAR(WORD,rf) -- unused */ /* GLOBAL_VAR(WORD,moo) -- unused */ /* GLOBAL_VAR(WORD,mo) -- unused */ /* GLOBAL_VAR(WORD,oooo) -- unused */ /* GLOBAL_VAR(WORD,x) -- unused */ GLOBAL_VAR0(WORD,mQ) GLOBAL_VAR0(WORD,mF) GLOBAL_VAR0(WORD,o) GLOBAL_VAR0(WORD,q) GLOBAL_VAR0(WORD,mode) /* MODE_* */ GLOBAL_VAR0(WORD,tY) /* FMT_*; formerly ty */ GLOBAL_VAR0(WORD,oO) GLOBAL_VAR0(WORD,oP) GLOBAL_VAR0(WORD,f) GLOBAL_VAR0(WORD,p) GLOBAL_VAR0(WORD,v) GLOBAL_VAR0(WORD,h) #define AREF_S(idx) AREF(Sbuf,idx) #define ASET_S(idx,val) ASET(Sbuf,idx,val) /* Reading Operations: -- fxRead8(): read a 8-bit byte at byte boundary -- fxRead16z(): read a 16-bit word at byte boundary, MSB first (ZIP) -- fxRead16(): read a 16-bit word at byte boundary, LSB first (normal) -- fxSkip(): skip to next byte boundary -- fxRead1(): read 1 bit (for Huffman) -- fvRead(): read any amount of bits (0..13), LSB first */ /* Dat: FlateDecode bit packing order is: (b7*128+...+b0)+(b15*128+...+b8) /** char, 0..255 */ SLOCAL_VAR0(WORD,preread) /** -1..-8: bits of bufread[pos] already read */ SLOCAL_VAR0(WORD,past) % static void fxInit(void) { % /fxInit { #define fxInit \ /preread 0 def \ /past -8 def % }BIND_DEF /* #define ASSERT_PREREAD_NOT_EOF() preread 255 gt ASSERT_FALSE_POP((unexpected eof)) */ #define ASSERT_NOT_EOF(val) ASSERT_TRUE(val dup 255 and eq,(non-EOF expected)) #define ASSERT_PREREAD_NOT_EOF() ASSERT_NOT_EOF(preread) /** reads 0..13 bits */ % static WORD fvRead(WORD arg) { /fvRead { DEBUG(dup (==> fvRead\() exch 42 string cvs concatstrings (\)\n) concatstrings) DEBUG(( past=) past neg 42 string cvs concatstrings ( preread=) preread 42 string cvs concatstrings (\n) concatstrings concatstrings) dup 0 INT_NE{ ASSERT_PREREAD_NOT_EOF() past % Stack: arg -opast dup preread exch bitshift exch % SHR % Stack: arg preread>>opast opast dup 3 index sub % Stack: arg ret==:preread>>-opast -opast -past==:-opast-arg dup -8 ge{ /past exch def % BUG fixed at Thu Dec 27 14:53:53 CET 2001 pop % Stack: arg ret }{ ASSERT_TRUE(dup -9 le,(-past>=9)) /preread my_getchar() def ASSERT_PREREAD_NOT_EOF() dup -16 ge{ /* _GT_ */ 8 add /past exch def 8 add % Stack: arg ret==:preread>>opast 8-opast preread exch bitshift % SHL add % Stack: arg ret'' }{ 16 add /past exch def 8 add 2 copy % Stack: arg retold 8-opast ret 8-opast preread exch bitshift add % SHL % Stack: arg retold 8-opast ret'' /preread my_getchar() def % BUG fixed at Thu Dec 27 15:40:53 CET 2001 ASSERT_TRUE(past -1 le,(-past>=1)) ASSERT_TRUE(past -4 ge,(-past<=4)) ASSERT_PREREAD_NOT_EOF() exch 8 add preread exch bitshift add % Stack: arg retold ret'' exch pop % Stack: arg ret'' }ifelse }ifelse % Stack: arg ret % exch constM exch get and % ret&=((1<0)) \ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \ ASSERT_PREREAD_NOT_EOF() \ -1 2 {pop my_ignorechar()}for \ /preread my_getchar() def #define fxIgnore8z \ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \ ASSERT_PREREAD_NOT_EOF() \ dup 0 INT_NE{ \ -1 2 {pop DEBUG2((fI8z)===) my_ignorechar()}for \ /preread my_getchar() def \ }{pop}ifelse % static WORD fxRead8EOF(void) { % /fxRead8EOF{ #define fxRead8EOF \ ASSERT_TRUE(past 0 INT_EQ,(past==0)) \ preread \ /* Stack: ret */ \ /preread my_getchar() def % }BIND_DEF #else #if 0 /* old-style: past==0 */ % static void fxSkip(void) { /fxSkip{ past 0 INT_NE{ ASSERT_PREREAD_NOT_EOF() /preread my_getchar() def /past 0 def }if }BIND_DEF % static WORD fxRead8(void) { /fxRead8{ ASSERT_TRUE(past 0 INT_EQ,(past==0)) ASSERT_PREREAD_NOT_EOF() preread /* Stack: ret */ /preread my_getchar() def }BIND_DEF /fxIgnore8z{ % Same as void fxIgnore8(WORD how_many_bytes), but allow 0 as arg ASSERT_TRUE(past 0 INT_EQ,(past==0)) ASSERT_PREREAD_NOT_EOF() dup 0 INT_NE{ -1 2 {pop DEBUG2((fI8z)===) my_ignorechar()}for /preread my_getchar() def }{pop}ifelse }BIND_DEF /fxRead8EOF{ ASSERT_TRUE(past 0 INT_EQ,(past==0)) preread /* Stack: ret */ /preread my_getchar() def }BIND_DEF #else #define fxSkip /past -8 def #define fxRead8 \ ASSERT_TRUE(past -8 INT_EQ,(past==-8)) \ my_getchar() ASSERT_NOT_EOF(dup) % }BIND_DEF #define fxRead8EOF \ ASSERT_TRUE(past -8 INT_EQ,(past==-8)) \ my_getchar() % }BIND_DEF #endif % static WORD fxRead16(void) { /fxRead16{ ASSERT_TRUE(past -8 INT_EQ,(past==-8)) my_getchar() ASSERT_NOT_EOF(dup) my_getchar() ASSERT_NOT_EOF(dup) 8 bitshift add }BIND_DEF % static void fxIgnore8(WORD how_many_bytes) { /fxIgnore8{ ASSERT_TRUE(dup 0 gt,(fxIgnore8arg>0)) ASSERT_TRUE(past -8 INT_EQ,(past==-8)) ASSERT_PREREAD_NOT_EOF() {my_getchar() ASSERT_NOT_EOF(dup) pop }repeat }BIND_DEF #define fxIgnore8z fxIgnore8 #endif #define fvReadq fvRead /** Reads an uint16 from the ZIP file */ #define fxRead16z fxRead16 /** * Allocates a new node and initializes it with empty content. This function * lets us get rid of the global variable F (which was buggily uninitialized * in the original scm.c). * @return pointer to the newly allocated node * @whichcode -1 */ % DEFUN_0(NODEN,fvNalloc) % /fvNalloc{ #define fvNalloc \ /* GLOBAL_REF(N) */ \ /* GLOBAL_REF(Dvar) */ \ /* LOCAL_VAR(NODEN,no) */ /* the first/next free node */ \ /* FUNCODE */ \ Dvar \ /* Stack: no */ \ ASSERT_TRUE(dup NODESIZE lt,(Dvarroot recursively. * Used I as input only. * Moved I into a argeter. * @param arg root node index in N */ % DEFUN_1_VOID(fvFree,NODEN) /fvFree{ % GLOBAL_REF(N) % GLOBAL_REF(Dvar) N exch dup NULL INT_NE{ 2 copy get fvFree 2 copy 1 add get fvFree % fvFree(AREF(N,arg+1)); 2 copy 1 add NULL put % ASET(N,arg+1,NULL); /* clear */ 2 copy 2 add 0 put % ASET(N,arg+2,0); /* clear */ 2 copy Dvar put % ASET(N,arg,Dvar); /* link to the beginning of the free list */ /Dvar exch def pop % SET(Dvar,arg); /* set it free */ }{ % BUG fixed at Thu Dec 27 11:52:59 CET 2001 pop pop }ifelse }BIND_DEF /** * Goes down (descends) enough levels in the binary tree of (struct node)s. * Reads numbers from input encoded as a Huffman tree represented by the * (struct node)s. * Called only from 2 places. * Used I as both input and output, but the output is never used * in the program. So I've put I to a argument. * @param arg root is only for input * @whichcode 3 */ % DEFUN_1(WORD,fvDescend,NODEN) % /fvDescend{ #define fvDescend \ /* GLOBAL_REF(N) */ \ /* FUNCODE */ \ DEBUG(dup (==> fvDescend\() exch 42 string cvs concatstrings (\)\n) concatstrings) \ N exch \ { /* Stack: N arg */ \ 2 copy get NULL INT_EQ{exit}if /* WHILE(NE(NULL,AREF(N,arg))) */ \ 2 copy fxRead1 add get exch pop /* SET(arg,AREF(N,arg+fxRead1())); */ \ }loop /* ENDWHILE */ \ /* Stack: N arg */ \ 2 add get \ DEBUG(dup (<-- fvDescend=) exch 42 string cvs concatstrings (\n) concatstrings) \ /* RETURN(fvDescend,AREF(N,arg+2)) */ /* arg->value; */ % }BIND_DEF /** * Allocates new (struct node)s. This is the Huffman tree * builder. It reads the global array Z: the code lengths have * been already stored there. * Used I as output only, so I moved it to the return value. * @param arg the number of entries (codes) of the Huffman tree to be built * @return the root of the Huffman tree just built * @whichcode 5 */ % DEFUN_1(NODEN,fvMktree,WORD) /fvMktree{ % BUG fixed at Thu Dec 27 11:54:02 CET 2001 % GLOBAL_REF(B) % GLOBAL_REF(G) % GLOBAL_REF(N) % GLOBAL_REF(Z) % LOCAL_VAR(WORD,moo) % LOCAL_VAR(WORD,mQ) % LOCAL_VAR(WORD,mo) % LOCAL_VAR(WORD,mF) % FUNCODE constZ19 0 17 getinterval Bary copy pop % OK to copy packedarray -> array % Stack: arg Bary Z 0 1 4 index 1 sub % Stack: arg Bary Z 0 1 arg-1 { % Stack: arg Bary Z moo 3 copy get % Stack: arg Bary Z moo Bary Z[moo] 2 copy get 1 add put % Stack: arg Bary Z moo pop }for % WHILE(LT(moo,arg)) INCR(AREF(Bary,AREF(Z,moo))); INCR(moo); ENDWHILE % Stack: arg Bary Z pop 0 0 put % ASET(Bary,0,0); Gary 0 0 put % ASET(Gary,0,0); % Stack: arg Gary Bary 0 1 15 % SET(moo,0); WHILE(LT(moo,16)) { % Stack: arg Gary Bary moo 2 copy get % Stack: arg Gary Bary moo Bary[moo] 3 index 2 index get % Stack: arg Gary Bary moo Bary[moo] Gary[moo] add dup add % BUG fixed at Thu Dec 27 15:05:51 CET 2001 % Stack: arg Gary Bary moo 2*(Bary[moo]+Gary[moo]) 3 index exch 2 index 1 add exch % Stack: arg Gary Bary moo Gary moo+1 2*(Bary[moo]+Gary[moo]) % ASET(Gary, moo+1,TWICE(AREF(Gary,moo)+AREF(Bary,moo))); put pop }for % BUG fixed at Thu Dec 27 14:59:52 CET 2001 % Stack: arg Gary Bary pop pop /* Dat: anode is the ->left pointer of the Sentinel node */ N 3 0 put % ASET(N,3,NULL); /* anode=NULL; */ % Stack: arg 1 sub 0 exch 1 exch{ % SET(moo,0); WHILE(LT(moo,arg)) % Stack: moo dup Z exch get dup 0 INT_NE{ % IF(NZ(AREF(Z,moo))) % Stack: moo Z[moo] % /* WORD o, f; */ /* struct node **f; */ dup Gary exch get /mQ exch def % SET(mQ,AREF(Gary,AREF(Z,moo))); % Stack: moo Z[moo] dup Gary exch 2 copy % Stack: moo Z[moo] Gary Z[moo] Gary Z[moo] get 1 add put % INCR(AREF(Gary,AREF(Z,moo))); % Stack: moo Z[moo] /mF 3 def % SET(mF,3); /* mF=&anode; */ % BUG fixed at Thu Dec 27 12:03:31 CET 2001 % SET(mo,AREF(Z,moo)); 1 sub -1 0 % Stack: moo Z[moo]-1 -1 0 { % WHILE(NZ(mo)); DECR(mo); % Stack: moo mo N mF get NULL INT_EQ{ N mF fvNalloc put }if % IF(EQ(AREF(N,mF),NULL)); ASET(N,mF,fvNalloc NOARGS); ENDIF 1 exch bitshift mQ and 0 INT_EQ{0}{1}ifelse N mF get add /mF exch def % SET(mF,AREF(N,mF)+TAND_P(mQ,SHL(1,mo))); % Stack: moo }for N exch % Stack: N moo N mF 2 copy fvNalloc put % ASET(N,mF,fvNalloc NOARGS); get 2 add % Stack: N moo AREF(N,mF)+2 exch put % ASET(N,AREF(N,mF)+2,moo); /* (*f)->value=moo; */ % Stack: - }{pop pop}ifelse % ENDIF }for % Stack: - N 3 get }BIND_DEF #define FMT_ZLIB 120 #define FMT_STOP 4 /* stop processing and flush STDIN */ #if CFG_FMT_ZLIB_ONLYX #else #define FMT_ZIP_STORED 0 /* file is stored, not Deflated in ZIP file */ #define FMT_GZIP 31 #define FMT_NONE 3 #define FMT_ZIP_DEFLATED 8 #endif #define MODE_BOS 0 /* at beginning of (sub)file */ #define MODE_MOB 1 /* at middle of a DEFLATE block */ #define MODE_REP 2 /* printing a repeating string in a DEFLATE block */ #define MODE_BOB 3 /* at the beginning of a block, just before BFINAL and BTYPE */ #define MODE_COPY1 4 /* copying from input to output (a stored block) */ #if CFG_FMT_ZLIB_ONLYX #else #define MODE_ZSTO 5 /* copying from input to output (FMT_ZIP_STORED) */ #endif /** * Root of the literal--length Huffman tree in N * (see RFC 1951). Its length is at most 288 with values 0..287. Values * 286 and 287 are invalid. A value in 0..255 means a literal byte, a * value of 256 indicates end-of-block, and a * value in 257..285 is a prefix (with 29 possible values) of a length * in 3..258. See subsubsection 3.2.5 of RFC 1951. */ SLOCAL_VAR0(NODEN,v) /** * Root of the distance Huffman tree in N (see RFC 1951). * Its length is at most 32 with values 0..31. Values 30 and 31 are invalid. * A value of 0..29 is a prefix (with 30 possible values) of a distance in * 1..32768. See subsubsection 3.2.5 of RFC 1951. */ SLOCAL_VAR0(NODEN,h) #define SLIDEE dup 32767 INT_EQ{pop 0}{1 add}ifelse #if CFG_FMT_ZLIB_ONLY #define fvAFB \ DEBUG2((f0:__LINE__) ===only) DEBUG2(currentfile FP ===) \ /mode MODE_BOS def \ /tY FMT_STOP def /* force EOF */ \ fxSkip \ DEBUG2((f1:__LINE__) ===only) DEBUG2(currentfile FP ===) \ 4 fxIgnore8z \ DEBUG2((f2:__LINE__) ===only) DEBUG2(currentfile FP ===) #else % static void fvAFB(void) { % /fvAFB{ /* after final block (BFINAL) */ #define fvAFB \ \ /mode MODE_BOS def /* SET(mode,MODE_BOS); */ \ fxSkip /* fxSkip(); */ \ /* ^^^ skip till we reach byte boundary. fvRead! 0..7 bits */ \ tY FMT_GZIP INT_EQ{ /* IF(EQ(tY,FMT_GZIP)) */ \ /* CRC32 and ISIZE remaining */ \ /* vvv IGNORE fxRead16(); IGNORE fxRead16(); IGNORE fxRead16(); IGNORE fxRead16(); */ \ 8 \ }{ \ tY FMT_ZLIB INT_EQ{ /* ELSE_IF(EQ(tY,FMT_ZLIB)) */ \ /* ADLER32 remaining */ \ 4 \ }{0}ifelse \ }ifelse \ fxIgnore8z % }BIND_DEF #endif /* CFG_FMT_ZLIB_ONLY */ /** Reads data from input, uncompresses and saves it to Sbuf. Sbuf.length==32768. * Saves 32768 bytes into Sbuf unless EOF prevents it. After return, the caller * may read Sbuf, but it may not modify it. * @return length to be saved to Sbuf */ % static WORD fvWork(void) { /fvWork{ % GLOBAL_REF(J) % GLOBAL_REF(Y) % GLOBAL_REF(Tvar) % GLOBAL_REF(N) % GLOBAL_REF(Dvar) { % `{'': establish fake loop context for return mode MODE_REP INT_EQ{ % IF(EQ(mode,MODE_REP)) ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0)) ASSERT_TRUE(f 258 le,(f<=258)) % /* f==0 is OK now */ Tvar oO 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Tvar oO Sbuf 3 copy exch get % Stack: Tvar oO Sbuf Tvar S[oO] put % ASET_S(Tvar,AREF_S(oO)); SLIDEE % SLIDE(oO); exch 1 add exch % INCR(Tvar); % DECR(f); }for % ENDWHILE pop /Tvar exch def /mode MODE_MOB def }{ mode MODE_COPY1 INT_EQ{ % ELSE_IF(EQ(mode,MODE_COPY1)) % /* Now: f: copy count unsinged word16 */ ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0)) % /* f==0 is OK now */ f 32767 gt{ /* _GT_ */ % IF((unsigned short)f>=32768) ASSERT_TRUE(f 32768 sub f 32767 and eq,((f&32767)==f-32768)) /f f 32767 and def 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8()); % INCR(T); % DECR(f); }for % ENDWHILE /Tvar 0 def % SET(Tvar,0); % Stack: - ASSERT_TRUE(mode MODE_COPY INT_EQ,(mode==MODE_COPY1)) % bbb111 32768 exit % return (WORD)32768; outside loops }{ % ELSE Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Sbuf Tvar 2 copy fxRead8 put % ASET_S(Tvar,fxRead8()); 1 add % INCR(Tvar); }for % ENDWHILE /Tvar exch def pop % /mode MODE_BOB def % SET(mode,MODE_BOB); % BUG fixed at Thu Dec 27 14:16:57 CET 2001 o 0 INT_NE{ % IF(NZ(o)) fvAFB % goto on_bos; SET(mode,MODE_BOS); }{ % ELSE /mode MODE_BOB def % SET(mode,MODE_BOB); % beginning of next block }ifelse % ENDIF }ifelse % ENDIF } #if CFG_FMT_ZLIB_ONLY if #else {mode MODE_ZSTO INT_EQ{ % ELSE_IF(EQ(mode,MODE_ZSTO)) % /* Now: f: copy count low unsinged word16, oP: high unsigned word16 */ % /* Now: oo: 0..1 flag for decrementing oP */ ASSERT_TRUE(Tvar 0 INT_EQ,(Tvar==0)) % /* f==0 is OK now */ f 32767 gt{ /* _GT_ */ % IF((unsigned short)f>=32768) ASSERT_TRUE(f 32768 sub f 32767 and eq,((f&32767)==f-32768)) /f f 32767 and def 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8()); % INCR(Tvar); % DECR(f); }for % ENDWHILE /Tvar 0 def % SET(Tvar,0); % Stack: - ASSERT_TRUE(mode MODE_ZSTO INT_EQ,(mode==MODE_ZSTO)) % bbb222 32768 exit % return (WORD)32768; outside loops }{ oP 0 INT_NE{ % ELSE_IF(NZ(oP)) 0 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8()); % INCR(Tvar); % DECR(f); }for % ENDWHILE /Tvar 0 def % SET(Tvar,0); % Stack: - oO 0 INT_NE{ % IF(NZ(oO)) /oP oP 1 sub def % DECR(oP); /oO 0 def % SET(oO,0); }{ % ELSE /oO 1 def % SET(oO,1); }ifelse ASSERT_TRUE(mode MODE_ZSTO INT_EQ,(mode==MODE_ZSTO)) % bbb333 32768 exit % return (WORD)32768; outside loops }{ % ELSE Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Sbuf Tvar 2 copy fxRead8 put % ASET_S(Tvar,fxRead8()); 1 add % INCR(Tvar); }for % ENDWHILE /Tvar exch def pop /mode MODE_BOS def % SET(mode,MODE_BOS); }ifelse % oO!=0 }ifelse % f>=32768 }if % MODE==MODE_ZSTO }ifelse % MODE==MODE_COPY1 #endif /* CFG_FMT_ZLIB_ONLY */ }ifelse % MODE==MODE_REP -1 exit % don''t return yet }loop % Stack: retval||-1 { % big-big MODE_MOB||MODE_BOB||MODE_BOS loop #ifndef NDEBUG % mode ===only ( big-big\n) print #endif ASSERT_TRUE(mode MODE_MOB INT_EQ mode MODE_BOB INT_EQ mode MODE_BOS INT_EQ or or,(MODE_MOB||MODE_BOB||MODE_BOS)) % Stack: retval||-1 dup -1 INT_NE{%ccc999 exit}if mode MODE_MOB INT_EQ{ % IF(EQ(mode,MODE_MOB)); mode_mob: ASSERT_TRUE(dup -1 INT_EQ,(was -1)) pop % -1 /** * Uncompresses the data block with the Huffman codes set up. * * Reads at most 33 bits per entry. Unfortunately the block can be of * arbitrary length (terminated by an entry of 256). */ % /* vvv reads 0..15 bits, see subsubsection 3.2.7 of RFC 1951 */ { % Dat: most of the time is spent inside fvDescend, fvRead and % inside this loop v fvDescend dup 256 INT_EQ{pop -1 exit}if % WHILE(NE(oo, 256)) dup 257 lt{ % IF(LT(oO,257)) % /* ^^^ BUG corrected */ Sbuf exch Tvar exch put % ASET_S(Tvar,oO); % Stack: - % vvv SLIDE(Tvar); /* Tvar++; Tvar&=32767; */ % vvv if (Tvar==0) return (WORD)32768; /* remain in MODE_MOB */ Tvar 32767 INT_EQ{ /Tvar 0 def % bbb444 32768 exit % return % in big-big-loop and MOB-loop }if /Tvar Tvar 1 add def }{ % ELSE 257 sub % SUB(oO,257); % Stack: oO dup constU exch get exch constP exch get fvRead add /f exch def % SET(f,AREF(constU,oO) + fvRead(AREF(constP,oO))); /* fvRead! 0..5 bits */ ASSERT_TRUE(3 f le f 258 le and,(3<=f && f<=258)) h fvDescend % SET(oO,fvDescend(h)); dup constQ exch get exch constL exch get fvRead add % SET(oO,AREF(constQ,oO) + fvRead(AREF(constL,oO))); /* fvRead! 0..13 bits */ Tvar exch sub 32767 and % /* oO = oO <= Tvar ? Tvar - oO : 32768 - oO + Tvar; */ f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar) pop % Stack: oO Tvar exch 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Tvar oO Sbuf 3 copy exch get % Stack: Tvar oO Sbuf Tvar S[oO] put % ASET_S(Tvar,AREF_S(oO)); SLIDEE % SLIDE(oO); exch 1 add exch % INCR(Tvar); % DECR(f); }for % ENDWHILE % Dat: oO doesn''t have to be remembered here pop /Tvar exch def % Stack: - ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768)) }{ % ELSE /f exch def % SUB(f,32768-Tvar); % Stack: oO Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) % Stack: oO Tvar exch % Stack: Tvar oO Sbuf 3 copy exch get % Stack: Tvar oO Sbuf Tvar S[oO] put % ASET_S(Tvar,AREF_S(oO)); SLIDEE % SLIDE(oO); exch pop % INCR(Tvar); }for % ENDWHILE /oO exch def % Stack: - /Tvar 0 def % SET(Tvar,0); /mode MODE_REP def % SET(mode,MODE_REP); % bbb555 32768 exit % return (WORD)32768; % in big-big-loop and MOB-loop }ifelse % ENDIF }ifelse % ENDIF }loop % ENDWHILE % Stack: retval||-1 dup -1 INT_EQ{ % BUG fixed at Thu Dec 27 15:52:18 CET 2001 v fvFree % fvFree(v); h fvFree % fvFree(h); o 0 INT_NE{ % IF(NZ(o)) fvAFB % goto on_bos; SET(mode,MODE_BOS); }{ % ELSE /mode MODE_BOB def % SET(mode,MODE_BOB); % beginning of next block }ifelse % ENDIF }if }if % ENDIF % Stack: retval||-1 dup -1 INT_NE{%ccc888 exit}if pop DEBUG2((;)===) mode MODE_BOB INT_EQ{ % WHILE(EQ(mode,MODE_BOB)); mode_bob: DEBUG(counttomark 42 string cvs) DEBUG(( kope\n)) % assert(mode==MODE_BOB); /o fxRead1 def % SET(o,fxRead1()); /* BFINAL: 1 iff this is the last data block */ /q 2 fvRead def % SET(q,fvRead(2)); /* BTYPE: block type; 0=stored, 1=fixed Huff, 2=dyn Huff */ % #if NDEBUG % #else % fprintf(stderr, "MODE_BOB o=%d q=%d %ld\n", o, q, ftell(stdin)); % #endif DEBUG((MODE:BOB o=) o 42 string cvs ( q=) q 42 string cvs ( ) Stdin fileposition 42 string cvs (\n) concatstrings concatstrings concatstrings concatstrings concatstrings concatstrings) ASSERT_TRUE(q 0 INT_EQ q 1 INT_EQ q 2 INT_EQ or or,(q==0 || q==1 || q==2)) q 0 INT_NE{ % IF(NZ(q)) /** * Now: q==BTYPE, q==1 or q==2. (BTYPE==3 means error). Handles * compressed data blocks, see subsubsection 3.2.5 of RFC 1951. */ q 1 INT_EQ{ % IF(EQ(q,1)) /** * Initializes the fixed Huffman codes for BTYPE==1. */ % /* WORD oO; */ 287 -1 0{ % SET(oO,288); WHILE(NZ(oO)); DECR(oO); Z exch dup 144 lt{8}{dup 256 lt{9} {dup 280 lt{7}{8}ifelse}ifelse}ifelse put /* ^^^ AREF(Z,oO) = oO < 144 ? 8 : oO < 256 ? 9 : oO < 280 ? 7 : 8; */ }for % ENDWHILE /v 288 fvMktree def % SET(v,fvMktree(288)); 0 1 31{Z exch 5 put}for % SET(f,0); WHILE(LT(f,32)) ASET(Z,f,5); INCR(f); ENDWHILE /h 32 fvMktree def % SET(h,fvMktree(32)); }{ % ELSE /** * Reads dynamic Huffman codes for BTYPE==2. * * Maximum read: 5+5+4+3*19+7*289 == 2094 bits */ ASSERT_TRUE(q 2 INT_EQ,(q==2)) % /* WORD oO, oP, oPo, f, p, x, v; */ /p 5 fvRead 257 add def % SET(p, fvRead(5) + 257); /* HLIT: 257..286 (287--289 are unused) */ /oO 5 fvRead 1 add def % SET(oO, fvRead(5) + 1); /* HDIST: 1..32 */ /v 4 fvRead 4 add def % SET(v, fvRead(4) + 4); /* HCLEN: 4..19 */ /* small v */ constZ19 Z copy pop % WHILE(LT(oO,19)) ASET(Z,AREF(constW,oO), 0); INCR(oO); ENDWHILE 0 1 v 1 sub{ Z exch constW exch get 3 fvRead put % WHILE(LT(oO,v)) ASET(Z,AREF(constW,oO), fvRead(3)); INCR(oO); ENDWHILE /* small v */ }for % Stack: - (verified) /v 19 fvMktree def % SET(v,fvMktree(19)); /oP 0 def % SET(oP,0); % Stack: - Z 0 { % SET(oO,0); WHILE(LT(oO,p + oO)) % Stack: Z oO dup p oO add ge{exit}if v fvDescend % SET(oPo,fvDescend(v)); % Stack: Z oO oPo dup 16 INT_EQ{ pop oP /f 2 fvRead 3 add def % SET(oPo,oP); SET(f,3+fvRead(2)); }{ dup 17 INT_EQ{ pop 0 /f 3 fvRead 3 add def % SET(oPo,0); SET(f,3+fvRead(3)); }{ dup 18 INT_EQ{ pop 0 /f 7 fvRead 11 add def % SET(oPo,0); SET(f,11+fvRead(7)); }{ dup /oP exch def /f 1 def % SET(oP,oPo); SET(f,1); }ifelse }ifelse }ifelse % Stack: Z oO oPo 1 1 f{ % SET(q,f); WHILE(NZ(q)) pop % BUG fixed at Thu Dec 27 12:17:58 CET 2001 3 copy put % ASET(Z,oO,oPo); exch 1 add exch % INCR(oO); % DECR(q); }for % ENDWHILE pop % oPo, BUG fixed at Thu Dec 27 12:18:47 CET 2001 }loop % ENDWHILE % Stack: Z oO''==p+oO pop pop v fvFree % fvFree(v); /v p fvMktree def % SET(v,fvMktree(p)); % Stack: - % /* vvv No need for array copy, just change/pass the pointer to Z... */ oO 1 sub -1 0{ % SET(oO'',oO); WHILE(NZ(oO'')) DECR(oO''); Z exch dup % Stack: Z oO'' oO'' p add Z exch get put % ASET(Z,oO'',AREF(Z,oO'' + p)); }for % ENDWHILE /h oO fvMktree def % SET(h,fvMktree(x)); }ifelse % ENDIF /mode MODE_MOB def % SET(mode,MODE_MOB); % goto mode_mob; }{ % ELSE /* inline: fv(..., 7); */ /** * Copies a block of input to output (mostly) verbatim. This is for * BTYPE==0, non-compressed block, subsubsection 3.2.4 of RFC 1951. * (We need non-compressed because * some blocks cannot be compressed effectively, so gzip inserts them * as is.) * @whichcode 7 */ fxSkip % fxSkip(); % /* ^^^ skip till we reach byte boundary. fvRead! 0..7 bits */ /f fxRead16 def % SET(f,fxRead16()); /* length of block: 0..65535 */ % #if NDEBUG % #else % fprintf(stderr, "COPY1_BLK=%d Tvar=%d\n", f, Tvar); % #endif 2 fxIgnore8 % IGNORE fxRead16(); /* one's complement of length; ignored */ f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar) pop Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Sbuf Tvar 2 copy fxRead8 put % ASET_S(Tvar,fxRead8()); 1 add % INCR(Tvar); }for % ENDWHILE /Tvar exch def pop ASSERT_TRUE(mode MODE_BOB INT_EQ,(mode==MODE_BOB)) ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768)) }{ % ELSE % /* Even if f>=32768 */ /f exch def % SUB(f,32768-Tvar); Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8()); % INCR(Tvar); % DECR(f); }for % ENDWHILE /Tvar 0 def % SET(Tvar,0); /mode MODE_COPY1 def % SET(mode,MODE_REP); % bbb666 DEBUG(counttomark 42 string cvs) DEBUG(( whata\n)) % trtr ASSERT_TRUE(counttomark 0 eq,(seccounttomark==0)) DEBUG((whatb\n)) 32768 exit % return (WORD)32768; % exit from big-big loop }ifelse % ENDIF o 0 INT_NE{fvAFB}if % IF(NZ(o)); fvAFB(); ENDIF DEBUG( counttomark 42 string cvs) DEBUG((pikula\n)) }ifelse % ENDIF }if % ENDWHILE /* MODE_BOB */ % Stack: - mode MODE_BOS INT_EQ{ DEBUG(counttomark 42 string cvs) DEBUG(( booski\n)) DEBUG2((boost)===only) DEBUG2(currentfile FP ===) { DEBUG(counttomark 42 string cvs) DEBUG(( boosbe\n)) tY FMT_STOP INT_EQ{ % WHILE(NE(tY,FMT_STOP)) Tvar 0 INT_NE{ % /* Flush unwritten buffer. */ Tvar% BUG fixed at Thu Dec 27 14:05:32 CET 2001 /Tvar 0 def % Stack: Tvar_old }{0}ifelse % ccc777 exit % return % in big-big loop and BOS-loop }if % /* SET(oO,0); SET(oP,0); */ /* avoid GCC warnings */ % /* fxInit(); */ /* assert(Y==0); SET(J,0); SET(Y,0); */ /v NULL def /h NULL def % SET(v,NULL); SET(h,NULL); % N 0 NULL put N 1 NULL put N 2 0 put % ASET(N,0,NULL); ASET(N,1,NULL); ASET(N,2,0); /* the NULL node is initially empty */ % N 3 NULL put N 4 NULL put N 5 0 put % ASET(N,3,NULL); ASET(N,4,NULL); ASET(N,5,0); /* the Sentinel node is initially empty */ constZ19 N copy pop % eliminate-NULLs trick: overwrites 1st >=6 elements of N /Dvar 6 def % SET(Dvar,6); /* first free node is 6. `0' is NULL, `3' is Sentinel */ 6{ % SET(o,Dvar); dup NODESIZE ge{pop exit}if % WHILE (LT(o,NODESIZE)) dup N exch dup 3 add put 1 add % ASET(N,o,o+3); INCR(o); /* next free node is next node */ dup N exch NULL put 1 add % ASET(N,o,NULL); INCR(o); /* empty RIGHT */ dup N exch 0 put 1 add % ASET(N,o,0); INCR(o); /* empty NVAL */ }loop % ENDWHILE % Stack: - fxRead8EOF dup /tY exch def % SET(tY,fxRead8EOF()); /* read first byte of the header */ % tY kkkkkkkkkk dup 511 INT_EQ{ % IF(EQ(tY,511)) /* EOF */ /tY FMT_STOP def % SET(tY,FMT_STOP); }{ #if CFG_FMT_ZLIB_ONLY 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x01 or 0x5e or 0x9c or 0xda */ #else dup FMT_ZLIB INT_EQ{ % ELSE_IF(EQ(tY,120)) /* ZLIB format */ 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x01 or 0x5e or 0x9c or 0xda */ % /* SET(tY,FMT_ZLIB); */ }{ dup 80 INT_EQ{ % ELSE_IF(EQ(tY,80)) /* ZIP format */ 1 fxIgnore8 % IGNORE fxRead8(); /* skip second header byte: 0x48 */ /tY FMT_NONE def % SET(tY,FMT_NONE); fxRead8 % SET(o,fxRead8()); dup 3 INT_EQ{ % IF(EQ(o,3)) /* Local file header */ % fxRead8 pop % IGNORE fxRead8(); /* skip: 0x04 */ % fxRead16 pop % IGNORE fxRead16(); /* skip: version needed to extract file (0x0020) */ % fxRead16 pop % IGNORE fxRead16(); /* LOCFLG flags */ 5 fxIgnore8 /tY fxRead8 def % SET(tY,fxRead8()); /* lower half of compression method */ ASSERT_TRUE(tY FMT_ZIP_STORED INT_EQ tY FMT_ZIP_DEFLATED INT_EQ or,(ty==FMT_ZIP_STORED || ty==FMT_ZIP_DEFLATED)) % ^^^ BUG fixed at Thu Dec 27 20:55:52 CET 2001 % fxRead8 pop % IGNORE fxRead8(); /* upper half of compression method */ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* file modification time in MS-DOS format */ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* some kind of CRC-32 */ 9 fxIgnore8 /f fxRead16z def % SET(f, fxRead16z()); /* lower compressed file size */ /oP fxRead16z def % SET(oP,fxRead16z()); /* higher compressed file size */ 4 fxIgnore8 % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* uncompressed file size */ fxRead16z % SET(oO,fxRead16z()); /* length of filename */ fxRead16z add % SET(q,fxRead16z()); /* length of extra field */ % WHILE(NZ(oO)) IGNORE fxRead8(); DECR(oO); ENDWHILE /* file name */ % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE /* extra field */ % -1 1{fxRead8 pop}for fxIgnore8z }{ dup 7 INT_EQ{ % ELSE_IF(EQ(o,7)) /* Extended local header of previous file in ZIP */ % 1 1 13{fxRead8 pop}for % SET(o,0); WHILE(LT(o,13)) IGNORE fxRead8(); INCR(o); ENDWHILE /* BUGFIX: was 15 */ 13 fxIgnore8 }{ dup 5 INT_EQ{ % ELSE_IF(EQ(o,5)) /* End of Central Directory Structure in ZIP */ /* fprintf(stderr,"EOCDS\n"); */ % 1 1 17{fxRead8 pop}for % SET(o,0); WHILE(LT(o,17)) IGNORE fxRead8(); INCR(o); ENDWHILE 17 fxIgnore8 fxRead16z % SET(o,fxRead16z()); /* CML: archive comment length */ % -1 1{fxRead8 pop}for % WHILE (NZ(o)) IGNORE fxRead8(); DECR(o); ENDWHILE fxIgnore8z }{ dup 1 INT_EQ{ % ELSE_IF(EQ(o,1)) /* Central Directory Structure */ /* fprintf(stderr,"CDS\n"); */ % 1 1 25{fxRead8 pop}for % SET(oO,0); WHILE(LT(oO,25)) IGNORE fxRead8(); INCR(oO); ENDWHILE 25 fxIgnore8 fxRead16z % SET(f,fxRead16z()); /* LEN: length of file name */ fxRead16z add % SET(o,fxRead16z()); /* XLN: length of extra field */ fxRead16z add % SET(q,fxRead16z()); /* CML: length of file comment */ % fxRead16 pop fxRead16 pop fxRead16 pop % fxRead16 pop fxRead16 pop fxRead16 pop % ^^^ SET(oO,0); WHILE(LT(oO,12)) IGNORE fxRead8(); INCR(oO); ENDWHILE 12 fxIgnore8 fxIgnore8z % ^^^ WHILE(NZ(f)) IGNORE fxRead8(); DECR(f); ENDWHILE /* file name */ % WHILE(NZ(o)) IGNORE fxRead8(); DECR(o); ENDWHILE /* extra field */ % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE /* file comment */ }if % o==1 }ifelse % o==5 }ifelse % o==7 }ifelse % o==3 % ENDIF /* IF ZIP structure sub-type */ % Stack: tY_old o pop }{ dup 31 INT_EQ{ % ELSE_IF(EQ(tY,31)) /* gzip/RFC 1952 format */ /* fprintf(stderr,"gzip!\n"); */ /* SET(tY,FMT_GZIP); */ /* The most simple gzip header (10 bytes): * ID1 hex 0x1f == dec 31 == FMT_GZIP * ID2 hex 0x8b * CM hex 0x08 * FLG hex 0x00 * MTIME hex 0x00, 0x00, 0x00, 0x00 (1 Jan 1970, UNIX epoch) * XFL hex 0x00 * OS hex 0xff * After that comes the compressed data stream. * After that comes the CRC32 and ISIZE (byte aligned? ?) */ 2 fxIgnore8 % fxRead16 pop % IGNORE fxRead16(); /* ignore ID2 and CM */ % kkkkkkkkkl fxRead8 % SET(o,fxRead8()); /* FLG */ % fxRead16 pop fxRead16 pop % IGNORE fxRead16(); IGNORE fxRead16(); /* ignore MTIME */ % fxRead16 pop % IGNORE fxRead16(); /* ignore XFL, OS */ 6 fxIgnore8 % Stack: o==FLG dup 2 and 0 INT_NE{ % IF(TAND_P(o,2)) /* GCONT: skip part number of continuation */ %fxRead16 pop % IGNORE fxRead16(); 2 fxIgnore8 }if % ENDIF dup 4 and 0 INT_NE{ % IF(TAND_P(o,4)) /* ignore FEXTRA */ fxRead16 fxIgnore8 % 1 1 fxRead16{fxRead8 pop}for % SET(q,fxRead16()); % WHILE(NZ(q)) IGNORE fxRead8(); DECR(q); ENDWHILE }if % ENDIF dup 8 and 0 INT_NE{ % IF(TAND_P(o,8)) {fxRead8 0 INT_EQ{exit}if}loop % WHILE(NZ(fxRead8())); PASS; ENDWHILE }if % ENDIF /* ignore FNAME */ dup 17 and 0 INT_NE{ % IF(TAND_P(o,16)) {fxRead8 0 INT_EQ{exit}if}loop % WHILE(NZ(fxRead8())); PASS; ENDWHILE }if % ENDIF /* ignore FCOMMENT */ dup 32 and 0 INT_NE{ % IF(TAND_P(o,32)) /* skip encryption header */ % fxRead16 pop fxRead16 pop fxRead16 pop % fxRead16 pop fxRead16 pop fxRead16 pop % SET(f,0); WHILE(LT(f,12)) IGNORE fxRead8(); INCR(f); ENDWHILE 12 fxIgnore8 }if % ENDIF % Stack: tY o pop }if % tY==31 (gzip/RFC 1952 format) }ifelse % tY==80 (ZIP format) }ifelse % tY==FMT_ZLIB #endif /* CFG_FMT_ZLIB_ONLY */ }ifelse % tY==511 % ENDIF /* IF file format */ % Stack: tY_old pop % /* fprintf(stderr,"tY=%d\n", tY); */ % tY bbbbbc #if CFG_FMT_ZLIB_ONLYX /* FMT_ZIP_STORED can become alive somehow... */ tY FMT_STOP INT_NE tY 3 INT_NE and{ /mode MODE_BOB def % SET(mode,MODE_BOB); -1 exit % goto mode_bob; }if #else tY FMT_ZIP_STORED INT_EQ{ % IF(EQ(tY,FMT_ZIP_STORED)) % /* fprintf(stderr,"ZIP_STORED oO=%d oP=%d\n", oO, oP); */ /oO 0 def % SET(oO,0); f 32768 Tvar sub sub dup 0 lt{ % IF((unsigned short)f<32768-(unsigned short)Tvar) pop Sbuf Tvar 1 1 f{ % WHILE(NZ(f)) -- inverse for pop % Stack: Sbuf Tvar 2 copy fxRead8 put % ASET_S(Tvar,fxRead8()); 1 add % INCR(Tvar); }for % ENDWHILE /Tvar exch def pop ASSERT_TRUE(Tvar 32768 lt,(Tvar<32768)) oP 0 INT_NE{ /mode MODE_ZSTO def % ccc555 Tvar exit % in big-big loop and BOS-loop }if % ^^^ IF(NZ(oP)); mode=MODE_ZSTO; return Tvar; ENDIF ASSERT_TRUE(mode MODE_BOS INT_EQ,(mode==MODE_BOS)) }{ % ELSE % /* Even if f>=32768 */ /f exch def % SUB(f,32768-Tvar); Tvar 1 32767{ % WHILE(NE((unsigned short)Tvar,32768)) Sbuf exch fxRead8 put % ASET_S(Tvar,fxRead8()); % INCR(Tvar); % DECR(f); }for % ENDWHILE /Tvar 0 def % SET(Tvar,0); /mode MODE_ZSTO def % SET(mode,MODE_REP); % bbb777 32768 exit % return (WORD)32768; % in big-big loop and BOS-loop }ifelse % ENDIF }{ tY FMT_STOP INT_NE tY FMT_NONE INT_NE and{ /mode MODE_BOB def % SET(mode,MODE_BOB); -1 exit % goto mode_bob; }if }ifelse % ENDIF #endif /* CFG_FMT_ZLIB_ONLY */ }loop % ENDWHILE /* outermost WHILE(NE(tY,FMT_STOP)) */ % Stack: retval }{-1}ifelse % mode==MODE_BOS % Stack: retval }loop % big-big MODE_MOB||MODE_BOB||MODE_BOS loop % Stack: retval }BIND_DEF % ENDFUN % Stdin already set #if 0 % /fvInitAll{ #define fvInitAll \ fxInit \ /tY FMT_NONE def \ /mode MODE_BOS def \ /Tvar 0 def /* make the round buffer empty */ \ TE_init % }BIND_DEF #else /fvMain{ % /XXX % STDIN read % STDIN C readhexstring % pop 0 get true_action % TE_read(===) TE_init % must be called _before_ fxInit fxInit /tY FMT_NONE def /mode MODE_BOS def /Tvar 0 def % /Tvar 0 def Tvar === quit { Sbuf 0 fvWork getinterval } /G load exec TE_read_eod % make sure that mEOD has been read }BIND_DEF #endif } /* We close the brace of declared functions */ % % %%BeginData: exec `S %%EndData end restore showpage %%Trailer %%EOF % %%EOF sam2p-0.49.2/l1lzw.psm0000644000175100017510000004140312211371426012623 0ustar ptspts/* l1lzw.psm * by pts@fazekas.hu at Sun Sep 22 01:23:57 CEST 2002 * formerly lzwdecode.psm -- a real, effective implementation of PostScript * LanguageLevel2 and PDF /LZWDecode filters (same as the LZW * compression used in TIFF raster image files), in PostScript Level1 * derived from lzwdecode.c by pts@fazekas.hu (at Wed Sep 4 11:11:45 CEST 2002) * by pts@fazekas.hu at Wed Sep 4 11:30:18 CEST 2002 * first run at Wed Sep 4 14:18:43 CEST 2002 * linux-2.2.8 fine at Wed Sep 4 14:46:05 CEST 2002 * rets linux-2.2.8 fine at Wed Sep 4 15:58:24 CEST 2002 * works at Wed Sep 4 16:41:29 CEST 2002 * linux-2.2.8 58388480 uncompressed: * lzwdecode.c: 17s user time (*1) * lzw_codec.c: 6s user time (*0.353) * lzwdecode.psm: 1080s user time (*63.53) * stack-reorg works at Thu Sep 5 12:31:23 CEST 2002 * lzwdecode.psm: 980s user time (*57.65) * lzwdecode.eps works at Thu Sep 5 14:31:23 CEST 2002 * last non-` at Sat Sep 21 23:40:03 CEST 2002 * * Note that the LZW compression (but not uncompression) is patented by * Unisys (patent number #4,558,302), so use this program at your own legal * risk! * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ % OK: test with aaaaaaaaaaaa (stack overflow) #include "psmlib.psm" #if USE_A85D #else #if USE_HEXD #else #define USE_BINARY 1 #endif #endif #if USE_NO_BIND #define BIND_DEF def #else #define BIND_DEF bind def #endif #if USE_PIN /* --- .pin begins */ % %!PS-Adobe-3.0`E %%Inflater: pts@fazekas.hu l1lzw.psm %%Pages: 1 `X%%DocumentData: `B %%LanguageLevel: 1 `I%%EndComments %%Page: 1 1 % % save`s `R % % vvv 50 % begin % % % best to make it first % % best to make it second % K: .toksubs. % % % % % % % % % % % % %C! %D! % % % % %S! % % % % %d! % % % % % % % % % % -- not needed, long enough % #if USE_SHORT_NAMES % % % % % % % % % % % % % % % #endif #if USE_A85D % % % % #endif #if USE_HEXD % % % % #endif #if USE_BINARY % #if USE_PALETTE % #endif % % #endif % % #if USE_BINARY /F /filter where {pop false}{true} ifelse def #else #if USE_A85D {mark currentfile/ASCII85Decode filter/T exch def}stopped #endif #if USE_HEXD {mark currentfile/ASCIIHexDecode filter/T exch def}stopped #endif /F exch def cleartomark #endif `w `h `b[1 0 0 -1 0 `h] #if USE_TRUE true #else F #endif % % 4096 string % #if USE_SHORT_NAMES_OLD #define a85_getc d #define Flzwdecode_init e #define Flzwdecode_do f #define Fclear I #endif #if USE_CURRENTFILE #define STDIN currentfile #endif % % Fmain % ^^^ must call it here, because _now_ `currentfile fileposition` is at the real image data % vvv avoid Fmain here because of the substituted constant 4717 (and also size increase!) Flzwdecode_init % !! Imp: less code here, init as a macro /Fmain 4096 string def { Fmain Flzwdecode_do } `i Fmain Flzwdecode_do pop % make sure that mEOD has been read TE_read_eod % % #if USE_BINARY /F currentfile/LZWDecode filter def #else /F T/LZWDecode filter def #endif F `i F closefile #if !USE_BINARY T closefile #endif % % #else 40 dict begin % LZWDict #endif #if 0 % (a) () 0 1 % DumpStack % TYPE_STACK(-str -int) % ZZZZZZZZZ % (a) 3 % ASSERT_STACK(-str -int,(1)) % pop pop #endif % Defaults: /EarlyChange 1 /UnitLength 8 /LowBitFirst false #if !USE_EARLYCHANGE_1 /EarlyChange 1 def #endif #if !USE_UNITLENGTH_8 /UnitLength 8 def #endif #if !USE_LOWBITFIRST_FALSE /LowBitFirst false def #endif /* OK: test with aaaaaaaaaaaa (stack overflow) */ #define STACKSIZE 4096 #define STACKSIZE_M1 4095 #if USE_SHORT_NAMES_OLD #endif % Uninitialized const-vars /prefix 4096 array def % array[0..4095] of 0..4095 /suffix 4096 string def /stack STACKSIZE string def #if USE_CURRENTFILE #else /STDIN (%stdin) (r) file def /STDOUT (%stdout) (w) file def % Fmain #endif #if USE_HEXD /C(.)def #endif % Uninitialized vars #if USE_UNITLENGTH_8 #define mClear 256 #define mEOD 257 #endif #if !USE_NO_NULLDEF /preread null def /past null def /nentry null def /had_eof null def % 0..2 #if !USE_UNITLENGTH_8 /mEOD null def /mClear null def #endif /nentrybig null def /nentryb null def /gcode null def % Flzwdecode_do /stackslice null def % Flzwdecode_do #if USE_A85D /S null def /D null def /C null def #endif #endif #if USE_PIN { #endif #if USE_A85D /a85_getc{ % Simple getchar() of ASCII85Decode filter :-)), formerly /d PSM_A85_GETC }BIND_DEF #endif %** - Fclear - /Fclear { #if USE_UNITLENGTH_8 /nentry 258 def /nentryb 9 def #if USE_EARLYCHANGE_1 /nentrybig 512 def #else /nentrybig 513 EarlyChange sub def #endif #else /nentry 1 UnitLength bitshift 2 add def /nentryb UnitLength 1 add def /nentrybig 1 nentryb bitshift #if !USE_EARLYCHANGE_1 1 EarlyChange sub add #endif def #endif 0 1 nentry 3 sub { % Stack: code(0..255) dup prefix exch dup % Stack: code prefix code code put suffix exch dup put } for } BIND_DEF %** - Flzwdecode_init - %** The caller should have modified /EarlyChange, /UnitLength and /LowBitFirst /Flzwdecode_init { TE_init /past 8 def /preread 0 def /had_eof 0 def #if !USE_EARLYCHANGE_1 ASSERT_TRUE(EarlyChange 0 INT_EQ EarlyChange 1 INT_EQ BOOL_BIN(or,(ora1)), (lsp->EarlyChange==0 || lsp->EarlyChange==1)) #endif #if USE_UNITLENGTH_8 Fclear #else ASSERT_TRUE(3 UnitLength INT_LE UnitLength 8 INT_LE and, (3<=lsp->UnitLength && lsp->UnitLength<=8)) Fclear /mClear 1 UnitLength bitshift def /mEOD 1 UnitLength bitshift 1 add def #endif /stackslice stack 0 0 getinterval def /gcode {} def } BIND_DEF %** Flzwdecode_do %** The caller should have called Flzwdecode_init. Flzwdecode_do fills the %** entire str.pre unless EOF on input prevents this. str.pre can have any %** length. Doesn`t depend of str.pre passed to it on the previous invocation. /Flzwdecode_do { ASSERT_TRUE(10 nentry INT_LE,(lsp->nentry>=10)) dup % Silently leave on stack stackslice had_eof % Stack: reto rets==reto stackslice had_eof { % W2:WHILE(1) % Stack: len++ stackslice had_eof* dup 0 INT_NE { /had_eof exch def pop /stackslice stack 0 0 getinterval def exit % exit(W2) }if % return(len) ASSERT_STACK(-str -str -str -int,(W2.in)) pop % Stack: len++ stackslice % Stack: reto rets stackslice ASSERT_STACK(-str -str -str,(3)) /* Flush stack. */ 2 copy length exch length ge { % return from the stack (rets.length<=stackslice.length % Stack: reto rets stackslice dup 0 3 index length getinterval % Stack: reto rets stackslice stackslice[0.. rets.length] 2 index copy pop % Stack: reto rets stackslice /stackslice exch 2 index length dup % Stack: reto rets /stackslice stackslice rets.length rets.length 2 index length exch sub % Stack: reto rets /stackslice stackslice rets.length stackslice.length-rets.length getinterval def 0 0 getinterval % Stack: reto rets[0,0] ASSERT_STACK(-str -str,(4)) exit % exit(W2) }if % vvv flush the whole stack into rets 2 copy exch copy pop % stackslice -> rets length dup % Stack: reto rets stackslice.length stackslice.length 2 index length exch sub % Stack: reto rets stackslice.length rets.length-stackslice.length getinterval % Stack: reto rets ASSERT_STACK(-str -str,(5)) ASSERT_TRUE(dup length 1 exch INT_LE,(len>=1)) % Stack: len++ /* Read next code (0..4095) from input to `code` */ nentry nentrybig INT_EQ { /nentryb nentryb 1 add def /nentrybig 1 nentryb bitshift #if !USE_EARLYCHANGE_1 1 EarlyChange sub add #endif def }if ASSERT_TRUE(4 nentryb INT_LE nentryb 12 INT_LE and, (4<=nentryb && nentryb<=12)) ASSERT_STACK(-str -str,(6)) { % W1:WHILE(1) ASSERT_STACK(-str -str,(7)) % Stack: len++ % assert(had_eof==0); -- cannot check this right here... ASSERT_TRUE(1 past INT_LE past 8 INT_LE and,(1<=past && past<=8)) ASSERT_TRUE(1 nentryb INT_LE nentryb 13 INT_LE and,(1<=nentryb && nentryb<=13)) #if !USE_LOWBITFIRST_FALSE LowBitFirst { % Dat: this is untested, even the stack /code 0 def 0 1 netryb 1 sub { % Stack: len++ i past 8 INT_EQ { /preread TE_read(def /past 0 def) #if !USE_NO_EOF { TE_read_pop pop /had_eof 2 def exit % exit from inner `for` }ifelse #endif }if preread 1 and 0 INT_NE { 1 exch bitshift code INT_BIN(add,(ora2)) /code exch def }{pop}ifelse % Stack: len++ /preread preread -1 bitshift def /past past 1 add def }for had_eof 0 INT_NE {0 had_eof exit}if % exit(W1) code }{ % else: !LowBitFirst #endif past nentryb add % Stack: len++ past* ASSERT_STACK(-str -str -int,(8)) dup 7 INT_GT { dup 16 INT_GT { 16 sub preread 8 bitshift % Stack: len++ past* code /preread TE_read(def) #if !USE_NO_EOF { TE_read_pop pop % Stack: len++ past* code pop /past exch def 0 2 % Stack: len++ garbage had_eof* exit % exit(W1) }ifelse #endif }{ 8 sub 0 % /code }ifelse % Stack: len++ past* code ASSERT_STACK(-str -str -int -int,(9)) ASSERT_TRUE(1 index 1 exch INT_LE 2 index 8 INT_LE and,(1<=lsp->past && lsp->past<=8)) preread INT_BIN(add,(or1)) % Stack: len++ past* code|preread 1 index bitshift % Stack: len++ past* code*==(code|preread)<preread&=(1<<(8-lsp->past))-1; /* do PCLEAR */ % Stack: len++ code preread0 past* dup /past exch def 8 sub bitshift INT_BIN(add,(or2)) % Stack: len++ code*==code|(preread>>(8-past)) ASSERT_STACK(-str -str -int,(12)) #if !USE_LOWBITFIRST_FALSE }ifelse % if: /LowBitFirst #endif % Stack: len++ code ASSERT_STACK(-str -str -int,(13)) dup mClear INT_LT{ /* Speed-up: process normal literal data code in `code` */ % Stack: len++ code ASSERT_STACK(-str -str -int,(15b)) ASSERT_TRUE(dup 1 add mClear INT_LE,(code too high2)) /* /ioerror */ ASSERT_TRUE(nentry 4095 INT_LE,(table full2)) /* /ioerror */ prefix nentry 2 index put suffix nentry 1 sub 2 index put stack exch STACKSIZE_M1 exch put % Stack: len++ ASSERT_STACK(-str -str,(15c)) /nentry nentry 1 add def stack STACKSIZE_M1 1 getinterval % Stack: len++ stackslice 0 % /had_eof ASSERT_STACK(-str -str -str -int,(20b)) exit % exit(W1) }if dup mEOD INT_GT{ /* Process normal data code (either literal or above-mEOD) in `code` */ % Stack: len++ code ASSERT_STACK(-str -str -int,(15)) ASSERT_TRUE(dup 1 add nentry INT_LE,(code too high)) /* /ioerror */ ASSERT_TRUE(nentry 4095 INT_LE,(table full)) /* /ioerror */ prefix nentry 2 index put % ASSERT_TRUE(0 stacklen INT_EQ,(lsp->stacklen==0)) % Stack: len++ code stack exch dup STACKSIZE_M1 exch nentry 1 sub % Stack: len++ stack code STACKSIZE_M1 code nentry-1 ASSERT_STACK(-str -str -aryb -int -int -int -int,(16)) INT_EQ { % the rightmost char of this entry will be equal to the leftmost % side, as soon as we calculate the leftmost side /gcode { stack STACKSIZE_M1 2 index put /gcode {} def } def }if %{ % ASSERT_TRUE(1 index nentry 2 sub INT_LE,(codenentry-1)) % % /gcode { } def %}ifelse -1 0 % Stack: len++ -{...} stack code STACKSIZE-1|STACKSIZE-2 -1 0 { % 1 index (code=) print === % Stack: len -{...} stack code putidx ASSERT_STACK(-str -str -aryb -int -int,(17)) exch dup prefix exch get 2 copy % Stack: len -{...} stack putidx code prefix[code] code prefix[code] INT_EQ{pop exit}if % exit from inner for % Stack: len -{...} stack putidx code prefix[code] 4 copy pop suffix exch get % Stack: len -{...} stack putidx code prefix[code] stack putidx suffix[code] put exch pop exch pop % Stack: len -{...} stack prefix[code] }for % Stack: len stack unused_putidx code ASSERT_STACK(-str -str -aryb -int -int,(18)) dup suffix exch get % dup (sufcode=) print === gcode suffix nentry 1 sub 2 index put pop % Stack: len stack unused_putidx suffix[code] 3 copy put pop % Stack: len stack unused_putidx dup STACKSIZE exch sub % Stack: len stack putidx STACKSIZE-putidx ASSERT_STACK(-str -str -aryb -int -int,(19)) getinterval ASSERT_TRUE(1 index length 0 INT_NE,(len!=0)) /nentry nentry 1 add def % Stack: len++ stackslice 0 % /had_eof ASSERT_STACK(-str -str -str -int,(20)) exit % exit(W1) }if dup mEOD INT_EQ{ % Stack: len++ code==mEOD pop 0 1 % Stack: len++ garbage had_eof* ASSERT_STACK(-str -str -int -int,(14)) exit % exit(W1) }if ASSERT_TRUE(dup mClear INT_EQ,(code==mClear)) pop Fclear % Stack: len++ ASSERT_STACK(-str -str,(21)) }loop % /W1:WHILE(1) % Stack: len++ stackslice|garbage had_eof* ASSERT_TRUE(TYPE_STACK(-str -str -str -int) TYPE_STACK(-str -str -int -int -bool) BOOL_BIN(or,(ora4)),(stack leaving W2)) } loop % /W2:WHILE(1) % Stack: len++ % Stack: reto rets(buffer-not-read) ASSERT_STACK(-str -str,(22)) length 1 index length exch sub % Stack: reto reto.length-rets.length 0 exch getinterval % Stack: reto.pre(return-value) } BIND_DEF % Flzwdecode_do #if USE_PIN %/Fmain { %} BIND_DEF } % close the function defs section % % %%BeginData: exec `S %%EndData end restore showpage %%Trailer %%EOF % #else #if !USE_CURRENTFILE % --- Main %** - Fmain - /Fmain { /mys 8192 string def Flzwdecode_init { mys Flzwdecode_do % Stack: mys.pre dup length 0 INT_EQ{exit}if STDOUT exch writestring } loop had_eof 1 INT_EQ { { STDIN read {pop}{exit}ifelse }loop }if } BIND_DEF Fmain #endif end % LZWDict #endif %%EOF sam2p-0.49.2/psmlib.psm0000644000175100017510000001456612211371426013052 0ustar ptspts/* psmlib.psm -- utilites for writing PostScript code with the help of * cpp, the C preprocessor * compiled by pts@fazekas.hu at Fri Sep 20 23:38:32 CEST 2002 */ #if USE_A85D #else #if USE_HEXD #else #define USE_BINARY 1 #endif #endif #if USE_INDEXED2 #define USE_PALETTE 1 #else #if USE_TRANSPARENT8 #define USE_PALETTE 1 #endif #endif #if USE_NO_BIND #define BIND_DEF def #else #define BIND_DEF bind def #endif #if NDEBUG #define DEBUG(msg) #define ASSERT_TRUE_POP(str) pop #define ASSERT_FALSE_POP(str) pop #define ASSERT_TRUE(what,str) #define ASSERT_INT() #define INT_EQ eq #define INT_NE ne #define INT_LE le #define INT_GT gt #define INT_LT lt #define BOOL_BIN(op,message) op #define INT_BIN(op,message) op #define DEBUGFORCE(msg) #define ASSERT_STACK(list,message) #else /-str /stringtype def /-aryb /stringtype def % byte array /-ary /arraytype def /-int /integertype def /-bool /booleantype def /-dict /dicttype def /handleerror.orig /handleerror load def /handleerror { (%stderr) (w) file dup (!!!Fatal: GS error: ) writestring dup $error /errorname get write==only dup ( in ) writestring dup $error /command get write==only dup ( at ) writestring dup $error /position get write==only dup (.\n) writestring flushfile flush handleerror.orig quit }bind def #define ASSERT_TRUE_POP(str) not{ str InternalError }if #define ASSERT_FALSE_POP(str) { str InternalError }if #define ASSERT_TRUE(what,str) what not{ str InternalError }if #define ASSERT_INT(str) dup type/integertype ne{str InternalError}if #define ASSERT_BOOL(str) dup type/booleantype ne{str InternalError}if /DumpStack { % - DumpStack - (Stack: ) print % from bottom to top count 1 sub -1 0{ index dup type /stringtype eq {pop ()}if ===only ( ) print } for (.\n) print }bind def /TypeStack { % TypeStack dup length count 2 sub eq { true exch count 2 add 1 index length 1 sub 0 exch 1 exch % Stack: ... true ary count(...)+5 0 1 ary.length-1 { % Stack: ... true ary count* i 2 index exch get 2 copy exch % Stack: ... true ary count* ary[i] ary[i] count* index type % Stack: ... true ary count* ary[i] ary[i] stackitem.type ne{ pop pop pop pop % Stack: ... false 0 0 exit }if pop 1 sub % Stack: ... true ary count*-1 } for % Stack: ... true|false ary count* pop pop }{ pop false }ifelse ASSERT_BOOL((TypeStack-bool)) }bind def /InternalError { % FatalError - (%stderr) (w) file dup dup (Internal muZCat Error: ) writestring 2 index writestring dup (.\n) writestring flushfile pop quit }bind def /Stderr (%stderr) (w) file def #ifdef DEBUGMSG #define DEBUG(msg) msg Stderr exch writestring Stderr flushfile #else #define DEBUG(msg) #endif #define DEBUGFORCE(msg) msg Stderr exch writestring Stderr flushfile #define INT_EQ ASSERT_INT((eq2int)) exch ASSERT_INT((eq1int)) exch eq #define INT_NE ASSERT_INT((ne2int)) exch ASSERT_INT((ne1int)) exch ne #define INT_LE ASSERT_INT((le2int)) exch ASSERT_INT((le1int)) exch le #define INT_GT ASSERT_INT((gt2int)) exch ASSERT_INT((gt1int)) exch gt #define INT_LT ASSERT_INT((lt2int)) exch ASSERT_INT((lt1int)) exch lt #define BOOL_BIN(op,message) ASSERT_BOOL(message) exch ASSERT_BOOL(message) exch op #define INT_BIN(op,message) ASSERT_INT(message) exch ASSERT_INT(message) exch op #define ASSERT_STACK(list,message) TYPE_STACK(list) not{ DumpStack (assert stack: ) message concatstrings InternalError }if #define TYPE_STACK(list) [ list ] TypeStack #endif /* at Sat Sep 21 19:07:59 CEST 2002 */ #if USE_DEBUG2 #define DEBUG2(x) x #else #define DEBUG2(x) #endif /* revised, A85D/read_eod at Sun Sep 22 00:27:13 CEST 2002 */ /* Sample usage: * { TE_read(===) % action to do with normal char * #if !USE_NO_EOF * { TE_read_pop exit } ifelse % action to do on EOF * #endif * } loop */ #if USE_A85D #define TE_read_eod a85_getc ASSERT_TRUE(dup 511 eq,(EOD expected)) pop #define TE_init /xS 32 def /xD 0 def /xC 0 def #if USE_NO_EOF #define TE_read(true_action) a85_getc true_action #define PSM_A85_GETC \ {27 xS ge{exit}if STDIN read pop \ dup 122 eq{/xS 27 def/xD 0 def/xC 0 def}{dup 117 gt{ \ STDIN read{pop}if/xS 54 xS sub def}{dup 33 ge{xS 32 eq{dup/xC exch def/xD -1670420001 def}{dup 117 sub{1 85 \ 7225 614125}xS 28 sub get mul xD add/xD exch def}ifelse/xS xS 1 sub def}if}ifelse}ifelse pop}loop xS 22 eq{511}{xC \ 1868977 mul xD add xS 24 and neg bitshift 23 xS lt{xC 3 mul add}if 255 and/xS xS 3 eq{32}{xS 7 mod 3 \ eq{22}{xS 8 sub}ifelse}ifelse def}ifelse /** TE_readstring(str) */ #define TE_readstring(str) dup length 1 sub 0 exch 1 exch{a85_getc 3 copy put pop pop}for #else #define TE_read(true_action) a85_getc dup 256 INT_LT { true_action } #define TE_read_pop pop /* #define TE_read_eod TE_read() { ASSERT_TRUE(false,(EOD expected)) } ifelse */ #define PSM_A85_GETC \ {27 xS ge{exit}if STDIN read not{511}if \ dup 122 eq{/xS 27 def/xD 0 def/xC 0 def}{dup 117 gt{ \ STDIN read{pop}if/xS 54 xS sub def}{dup 33 ge{xS 32 eq{dup/xC exch def/xD -1670420001 def}{dup 117 sub{1 85 \ 7225 614125}xS 28 sub get mul xD add/xD exch def}ifelse/xS xS 1 sub def}if}ifelse}ifelse pop}loop xS 22 eq{511}{xC \ 1868977 mul xD add xS 24 and neg bitshift 23 xS lt{xC 3 mul add}if 255 and/xS xS 3 eq{32}{xS 7 mod 3 \ eq{22}{xS 8 sub}ifelse}ifelse def}ifelse #endif #endif #if USE_HEXD #define TE_init #if USE_NO_EOF #define TE_read(true_action) STDIN C readhexstring pop 0 get true_action #define TE_read_eod STDIN read pop pop /* read '>' */ #define TE_readstring(str) STDIN str readhexstring pop #else #error PostScript op readhexstring cannot detect EOD! #define TE_read(true_action) STDIN C readhexstring { 0 get true_action } #define TE_read_pop #define TE_read_eod #endif #endif #if USE_BINARY #define TE_init #define TE_read_eod #if USE_NO_EOF #define TE_read(true_action) STDIN read pop true_action #define TE_readstring(str) STDIN str readstring pop #else #define TE_read(true_action) STDIN read { true_action } #define TE_read_pop #endif #endif sam2p-0.49.2/ps_tiny.c0000644000175100017510000006161412212351433012665 0ustar ptspts#define DUMMY \ set -ex; \ gcc -O3 -s -DNDEBUG=1 -DNO_CONFIG=1 -ansi -pedantic -Wunused \ -Wall -W -Wstrict-prototypes -Wtraditional -Wnested-externs -Winline \ -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \ -Wmissing-declarations ps_tiny.c -o ps_tiny; \ exit /* ps_tiny.c -- read .pin files, write short PostScript code * by pts@fazekas.hu at Sat Aug 24 12:46:14 CEST 2002 * -- Sat Aug 24 18:23:08 CEST 2002 * -- Sat Aug 24 23:47:02 CEST 2002 * -- Mon Sep 2 11:28:19 CEST 2002 * % #include #include /* exit() */ #if NO_CONFIG #include #if SIZEOF_INT>=4 typedef unsigned slen_t; typedef int slendiff_t; # define SLEN_P "" #else typedef unsigned long slen_t; typedef long slendiff_t; # define SLEN_P "l" #endif typedef char sbool; #if ';'!=59 || 'a'!=97 # error ASCII system is required to compile this program #endif #else #include "config2.h" /* by sam2p... */ typedef bool sbool; #endif #if OBJDEP # warning PROVIDES: ps_tiny_main #endif #define ULE(a,b) (((a)+0U)<=((b)+0U)) #define ISWSPACEE(i) ((i)==32 || ULE(i-9,13-9) || i==0) #define ISWSPACE(i,j) ((i j)==32 || ULE(i-9,13-9) || i==0) #define PROGNAME "ps_tiny" #define VERSION "0.02" /* --- Data */ #define SBUFSIZE 4096 /** Data area holding strings; */ char sbuf[SBUFSIZE], *sbufb; #define WORDSSIZE 127 /** Pointers inside sbuf, indexed by chars, [0..31] are special */ char const* words[WORDSSIZE]; static void sbuff(void) { unsigned i; sbuf[0]='\0'; sbufb=sbuf+1; for (i=0;i=0) { c=ilast; ilast=-1; } else if (iitem[0]!='\0') c=*iitem++; else if (ifmt[0]=='$') { iitem=*ilist++; ifmt++; goto nextitem; } else if (ifmt[0]=='\0') c=-1; /* EOF forever */ else c=*ifmt++; /* fprintf(stderr, "igetcc()='%c'\n", c); */ } else { if ((c=getchar())=='\n') { leftofs=curofs; curline++; } curofs++; } return c; } static void ungetcc(int c) { if (ifmt!=0) { assert(ilast<0); ilast=c; } else { if (c=='\n') curline--; if (c>=0) { curofs--; ungetc(c,stdin); } } } static void erri(char const*msg1, char const*msg2) { fprintf(stderr, "%s: error at %"SLEN_P"u.%"SLEN_P"u.%"SLEN_P"u: %s%s\n", PROGNAME, curline, curofs-leftofs+1, curofs, msg1, msg2?msg2:""); exit(3); } static void setword(int c, char const*word, int slash) { slen_t len; assert(slash==0 || slash==1); if (words[c][0]!='\0') erri("abbr letter already used",0); if (sbuf+SBUFSIZE-sbufb+(slen_t)0<(len=strlen(word))+slash+1U) erri("words overflow",0); /* fprintf(stderr,"setword(%d,\"%s\");\n", c, word); */ words[c]=sbufb; if (slash) *sbufb++='/'; strcpy(sbufb, word); sbufb+=len+1; /* assert(c<3 || findword(word)==c); */ } /** So a long string from ps_tiny --copy ='!' && c<='~' && c!='/' && c!='%' && c!='{' && c!='}' && c!='<' && c!='>' && c!='[' && c!=']' && c!='(' && c!=')'; /* Dat: PS avoids: /{}<>()[]% \n\r\t\000\f\040 */ } /** Definition chosen rather arbitrarily by pts */ static sbool is_wordx(char const *s) { if (!ULE(*s-'A','Z'-'A') && !ULE(*s-'a','z'-'a') && *s!='.') return 0; /* && !ULE(*s-'0','9'-'0') && *s!='-') return 0; */ while (*++s!='\0') if (!is_ps_name(*s)) return 0; return 1; } /** @param b: assume null-terminated @return true on error */ static /*inline*/ sbool toInteger(char *s, psint_t *ret) { int n=0; /* BUGFIX?? found by __CHECKER__ */ return sscanf(s, "%"SLEN_P"i%n", ret, &n)<1 || s[n]!='\0'; } /** @param b: assume null-terminated @return true on error */ static /*inline*/ sbool toReal(char *s, double *ret) { int n; char c; /* Dat: glibc accepts "12e", "12E", "12e+" and "12E-" */ return sscanf(s, "%lf%n", ret, &n)<1 || (c=s[n-1])=='e' || c=='E' || c=='+' || c=='-' || s[n]!='\0'; } /** Returns a PostScript token ID, puts token into buf */ static char gettok(void) { /* Derived from MiniPS::Tokenizer::yylex() of sam2p-0.37 */ int c=0; /* dummy initialization */ sbool hi; unsigned hv=0; /* =0: pacify G++ 2.91 */ slen_t nest; char *ibufend=ibuf+IBUFSIZE; ibufb=ibuf; #if 0 if (ungot==EOFF) return EOFF; if (ungot!=NO_UNGOT) { c=ungot; ungot=NO_UNGOT; goto again; } #endif again_getcc: c=getcc(); /* again: */ switch (c) { case -1: eof: return 0; /*ungot=EOFF */; case '\n': case '\r': case '\t': case ' ': case '\f': case '\0': goto again_getcc; case '%': /* one-line comment */ if ((c=getcc())=='<') { /* XMLish tag */ char ret='<'; if ((c=getcc())=='/') { ret='>'; c=getcc(); } /* close tag */ if (!ULE(c-'A','Z'-'A')) erri("invalid tag",0); /* catch EOF */ (ibufb=ibuf)[0]=c; ibufb++; while (ULE((c=getcc())-'A','Z'-'A') || ULE(c-'a','z'-'a')) { if (ibufb==ibufend-1) erri("tag too long",0); *ibufb++=c; } if (c<0) erri("unfinished tag",0); *ibufb='\0'; ungetcc(c); return ret; } while (c!='\n' && c!='\r' && c!=-1) c=getcc(); if (c==-1) goto eof; goto again_getcc; case '{': case '[': *ibufb++=c; return '['; case '}': case ']': *ibufb++=c; return ']'; case '>': if (getcc()!='>') goto err; *ibufb++='>'; *ibufb++='>'; return ']'; case '<': if ((c=getcc())==-1) { uf_hex: erri("unfinished hexstr",0); } if (c=='<') { *ibufb++='<'; *ibufb++='<'; return '['; } if (c=='~') erri("a85str unsupported",0); hi=1; while (c!='>') { if (ULE(c-'0','9'-'0')) hv=c-'0'; else if (ULE(c-'a','f'-'a')) hv=c-'a'+10; else if (ULE(c-'A','F'-'A')) hv=c-'A'+10; else if (is_ps_white(c)) hv=16; else erri("syntax error in hexstr",0); if (hv==16) ; else if (!hi) { ibufb[-1]|=hv; hi=1; } else if (ibufb==ibufend) erri("hexstr literal too long",0); else { *ibufb++=(char)(hv<<4); hi=0; } if ((c=getcc())==-1) goto uf_hex; } /* This is correct even if an odd number of hex digits have arrived */ return '('; case '(': nest=1; while ((c=getcc())!=-1) { if (c==')' && --nest==0) return '('; if (c!='\\') { if (c=='(') nest++; } else switch (c=getcc()) { /* read a backslash escape */ case -1: goto uf_str; case 'n': c='\n'; break; case 'r': c='\r'; break; case 't': c='\t'; break; case 'b': c='\010'; break; /* \b and \a conflict between -ansi and -traditional */ case 'f': c='\f'; break; default: if (!ULE(c-'0','7'-'0')) break; hv=c-'0'; /* read at most 3 octal chars */ if ((c=getcc())==-1) goto uf_str; if (c<'0' || c>'7') { ungetcc(c); c=hv; } hv=8*hv+(c-'0'); if ((c=getcc())==-1) goto uf_str; if (c<'0' || c>'7') { ungetcc(c); c=hv; } c=(char)(8*hv+(c-'0')); } /* SWITCH */ if (ibufb==ibufend) erri("str literal too long",0); /* putchar(c); */ *ibufb++=c; } /* WHILE */ /* if (c==')') return '('; */ uf_str: erri("unfinished str",0); case ')': goto err; case '/': *ibufb++='/'; while (ISWSPACE(c,=getcc())) ; /* ^^^ `/ x' are two token in PostScript, but here we overcome the C * preprocessor's feature of including whitespace. */ /* fall-through, b will begin with '/' */ default: /* /nametype, /integertype or /realtype */ *ibufb++=c; while ((c=getcc())!=-1 && is_ps_name(c)) { if (ibufb==ibufend) erri("token too long",0); *ibufb++=c; } ungetcc(c); if (ibuf[0]=='/') return '/'; /* Imp: optimise numbers?? */ if (ibufb!=ibufend) { psint_t l; double d; *ibufb='\0'; /* Dat: we don't support base-n number such as `16#100' == 256 in real PostScript */ if (!toInteger(ibufb, &l)) return '1'; /* throw away integer value */ /* Dat: call toInteger _before_ toReal */ if (!toReal(ibufb, &d)) return '.'; } return 'E'; /* executable /nametype */ } err: erri("syntax error, token expected",0); goto again_getcc; /* notreached */ } static void getotag(char const*tag) { #if 0 /* This code segment cannot ignore comments */ char const *p=tag; int c; while (ISWSPACE(c,=getcc())) ; if (c!='%' || (c=getcc())!='<') erri("tag expected: ", tag); while (ISWSPACE(c,=getcc())) ; while (p[0]!='\0') { if (c!=*p++) erri("this tag expected: ", tag); c=getcc(); } ungetcc(c); #else if (gettok()!='<' || 0!=strcmp(ibuf,tag)) erri("tag expected: ", tag); #endif } static void gettagbeg(void) { int c; while (ISWSPACE(c,=getcc())) ; if (c!='>') erri("`>' expected",0); } static void gettagend(void) { int c; while (ISWSPACE(c,=getcc())) ; if (c!='/') erri("`/>' expected",0); while (ISWSPACE(c,=getcc())) ; if (c!='>') erri("`/>' expected",0); } static void getkey(char const *key) { char const *p=key; int c; while (ISWSPACE(c,=getcc())) ; while (p[0]!='\0') { if (c!=*p++) erri("this key expected: ", key); c=getcc(); } while (ISWSPACEE(c)) c=getcc(); if (c!='=') erri("key `=' expected", 0); } /** Loads a value into ibuf, '\0'-terminated. */ static void getval(void) { sbool g=1; char *ibufend1=ibuf+IBUFSIZE-1, c; ibufb=ibuf; while (ISWSPACE(c,=getcc())) ; while (1) { if (c=='"') g=!g; else if (g && (ISWSPACEE(c) || c=='/' || c=='>')) { ungetcc(c); break; } else if (c<0) erri("unfinished tag val",0); else if (c==0) erri("\\0 disallowed in tag val",0); else if (ibufb==ibufend1) erri("tag val too long",0); else *ibufb++=c; c=getcc(); } /* WHILE */ *ibufb='\0'; } static psint_t getuintval(void) { psint_t ret; getval(); /* fprintf(stderr, "[%s]\n", ibuf); */ if (toInteger(ibuf, &ret) || ret<0) erri("tag val must be nonnegative integer",0); return ret; } /* --- Writing */ /** Maximum number of characters in a line. */ #define MAXLINE 78 /** Number of characters already written into this line. (from 0) */ slen_t wcolc; /** Last token was a self-closing one */ sbool wlastclosed; static void prepare(void) { wcolc=0; wlastclosed=1; } static void newline(void) { if (wcolc!=0) { putchar('\n'); wcolc=0; wlastclosed=1; } else assert(wlastclosed); } /** 2: "\\n"; 1: "\n" */ static int pstrq_litn_pp=2; /** @return the byte length of a string as a quoted PostScript ASCII string * literal */ static slen_t pstrqlen(register char const* p, char const* pend) { slen_t olen=2; /* '(' and ')' */ char c; p=ibuf; pend=ibufb; while (p!=pend) { if ((c=*(unsigned char const*)p++)=='\r' || c=='\t' || c=='\010' || c=='\f' || c=='(' || c==')') olen+=2; else if (c=='\n') olen+=pstrq_litn_pp; else if (c>=32 && c<=126) olen++; else if (c>=64 || p==pend || ULE(*p-'0','7'-'0')) olen+=4; else if (c>=8) olen+=3; else olen+=2; } return olen; } /** Prints the specified string as a quoted PostScript ASCII string literal. * Does not modify wcolc etc. */ static void pstrqput(register char const* p, char const* pend) { char c; putchar('('); p=ibuf; pend=ibufb; while (p!=pend) { if ((ULE((c=*(unsigned char const*)p++)-32, 126-32) && c!='(' && c!=')') || (c=='\n' && pstrq_litn_pp==1) ) { putchar(c); continue; } putchar('\\'); if (c=='\n') putchar('n'); else if (c=='\r') putchar('r'); else if (c=='\t') putchar('t'); else if (c=='\010') putchar('b'); else if (c=='\f') putchar('f'); else if (c=='(') putchar('('); /* BUGFIX at Tue Feb 22 00:22:19 CET 2005 */ else if (c==')') putchar(')'); else if (c>=64 || p==pend || ULE(*p-'0','7'-'0')) { putchar((c>>6&7)+'0'); putchar((c>>3&7)+'0'); putchar(( c&7)+'0'); } else if (c>=8) { putchar((c>>3) +'0'); putchar(( c&7)+'0'); } else putchar(c+'0'); } putchar(')'); } static int copy_longstr_warn_p=1; /** Copies PostScript code from input to output. Strips comments, superfluous * whitespace etc., substitutes words etc. * @param tag may be NULL, this signals: copy till EOF, doesn't substitute * words */ static void copy(char const*tag) { int c; slen_t len, olen; while (1) switch (gettok()) { case 0: if (tag) erri("eof before close tag: ", tag); return; case '[': case ']': if (wcolc+(len=ibufb-ibuf)>MAXLINE) newline(); wlastclosed=1; write: if (len>MAXLINE) fprintf(stderr, "%s: warning: output line too long\n", PROGNAME); fwrite(ibuf, 1, len, stdout); wcolc+=len; break; case '/': if ((len=ibufb-ibuf)=0) { ibuf[0]='/'; ibuf[1]=c; ibufb=ibuf+2; len=2; } if (wcolc+len>MAXLINE) newline(); wlastclosed=0; goto write; case '<': erri("tag unexpected",0); case '>': if (!tag) erri("close tag unexpected",0); if (strlen(tag)!=(len=ibufb-ibuf) || 0!=memcmp(ibuf,tag,len)) erri("this close tag expected: ", tag); /* wlastclosed is left unmodified */ gettagbeg(); return; case '(': olen=pstrqlen(ibuf,ibufb); if (wcolc+olen>MAXLINE) newline(); if (olen>MAXLINE && copy_longstr_warn_p) fprintf(stderr, "%s: warning: output string too long\n", PROGNAME); /* putchar(ibuf[1]); */ wcolc+=olen; pstrqput(ibuf,ibufb); wlastclosed=1; break; default: /* case '1': case '.': case 'E': */ /* fprintf(stderr,"fw(%s) %c\n", ibuf, findword("32768")); */ if ((len=ibufb-ibuf)=0) { ibuf[0]=c; ibufb=ibuf+1; len=1; } if (wcolc+len+!wlastclosed>MAXLINE) newline(); else if (!wlastclosed) { putchar(' '); wcolc++; } wlastclosed=0; goto write; } } /** Prefix chars: 32..41 ' '..')' */ static void cprefix(slen_t olen) { slen_t plen; if (0==olen) erri("empty token",""); if (olen>11) erri("compressed token too long (>11)",""); plen=olen+(olen>1)+(olen==7); if (wcolc+(wcolc==0)+plen>MAXLINE) newline(); if (wcolc==0) { putchar('%'); wcolc=1; } if (plen>=MAXLINE) fprintf(stderr, "%s: warning: output line too long\n", PROGNAME); if (olen==7) { putchar(8+30); putchar(' '); wcolc+=2; } /* Dat: ASCII 37=='%' */ else if (olen>1) { putchar(olen+30); wcolc++; } } /** Copies PostScript code from input to output. Strips comments, superfluous * whitespace etc., substitutes words etc. Output is not valid PostScript code, * but it needs decompression (i.e adding spaces to words). Ignores var * `wlastclosed' (sets it to 1 by calling newline()). */ static void compress0(char const*tag) { int c; slen_t len, olen; newline(); while (1) switch (gettok()) { case 0: erri("eof before close tag: ", tag); case '[': case ']': len=ibufb-ibuf; write: cprefix(len); fwrite(ibuf, 1, len, stdout); wcolc+=len; break; case '/': if ((len=ibufb-ibuf)=0) { /* erri("possibly stupid redef: ", ibuf); */ ibuf[0]='/'; ibuf[1]=c; ibufb=ibuf+2; len=2; } goto write; case '<': erri("tag unexpected",0); case '>': if (strlen(tag)!=(len=ibufb-ibuf) || 0!=memcmp(ibuf,tag,len)) erri("this close tag expected: ", tag); /* wlastclosed is left unmodified */ fputs((wcolc+2>MAXLINE) ? "\n% %%" : "%%", stdout); newline(); gettagbeg(); return; case '(': cprefix(olen=pstrqlen(ibuf,ibufb)); wcolc+=olen; pstrqput(ibuf,ibufb); break; default: /* case '1': case '.': case 'E': */ if ((len=ibufb-ibuf)=0) { ibuf[0]=c; ibufb=ibuf+1; len=1; } goto write; } } /** by pts@fazekas.hu at Fri Sep 6 11:34:57 CEST 2002. Copies data from stdin * to stdout till close tag %. (Note that it isn't safe to copy data of * the ASCII85Encode filter this way */ static void copydata(char const*tag) { int c; while (ISWSPACE(c,=getcc())) ; /* ungetcc(c); */ while (1) { if (c<0) erri("missing close tag: ", tag); if (c!='%') { putchar(c); c=getcc(); continue; } if ((c=getcc())=='<') { if ((c=getcc())=='/') { while (tag[0]!='\0') { if ((c=getcc())!=*tag++) erri("this close tag expected: ", tag); } while (ISWSPACE(c,=getcc())) ; if (c!='>') erri("`>' expected", 0); break; } else { putchar('%'); putchar('<'); } } else { putchar('%'); } } } /* --- Main */ int main(int argc, char**argv) { slen_t acount, xcount, inlining; char tmp[40]; (void)argc; /* freopen("t.pin","rb",stdin); */ sbuff(); rewindd(); prepare(); if (argv[0] && argv[1] && 0==strcmp(argv[1],"--copy")) { copy_longstr_warn_p=0; pstrq_litn_pp=1; copy((char const*)0); return 0; } { char tok=gettok(); slen_t len; len=ibufb-ibuf; if (tok=='<' && len==4 && 0==memcmp(ibuf, "Head", 4)) { gettagbeg(); copydata("Head"); getotag("Open"); } else if (tok=='<' && len==4 && 0==memcmp(ibuf, "Open", 4)) { } else erri("tag %", acount+xcount); setifmt(tmp,0); copy("I"); noifmt(); gettagbeg(); #define E_RANGE 3 #define E_SYNTAX 4 #define E_COMPRESS 5 copy("Abbr"); setword(E_RANGE, ")range", 0); setword(E_SYNTAX, ")syntax", 0); setword(E_COMPRESS, ")compress", 0); { int c; for (c=7;c<32;c++) words[c]=words[E_RANGE]; for (c=32;c<42;c++) words[c]=words[E_COMPRESS]; for (c=47;c<58;c++) words[c]=words[E_SYNTAX]; /* Name:'/', Number:'0'..'9' */ words[0U+'<']=words[0U+'>']= /* Hex */ words[0U+'[']=words[0U+']']= /* Bracket */ words[0U+'{']=words[0U+'}']= /* Brace */ words[E_SYNTAX]; for (c=127;c=WORDSSIZE) erri("invalid %", ilist_); if (words[1][0]=='\0' && 0==strcmp(ibuf,"def")) setword(1, ct, 0); } else { g=toInteger(ibuf, &i); /* need braces? */ if (g) { words[2]=sbuf; c=2; } setword(c, ibuf, 0); /* temp save */ ilist_[1]=words[c]; words[c]=sbuf; /* temp hide */ ilist_[2]=words[1][0]=='\0' ? "def" : words[1]; setifmt(g ? "/$ { $\n} $%" : "/$ $\n $%", ilist_); if (words[0][0]=='\0' && 0==strcmp(ibuf,"load def")) setword(0, ct, 0); } copy("I"); noifmt(); words[c]=ilist_[1]; } else if (tok=='<' && len==1 && 0==memcmp(ibuf, "D", 1)) { /* define both /x and x */ while (ISWSPACE(c,=getcc())) ; if (c<32 || c>=WORDSSIZE) erri("invalid %" :"/$ {\n" "mark exch{\n" "dup xcheck{\n" "dup type/arraytype eq{$}{\n" "dup type/nametype eq{\n" "dup currentdict exch known {load}if\n" "}if\n" "}ifelse\n" "}if\n" "}forall\n" "counttomark array astore exch pop cvx\n" "} bind def%", ilist_); copy("I"); noifmt(); } getotag("Test"); gettagbeg(); copy("Test"); getotag("S"); getkey("len"); (void)getuintval(); /* Imp: verify slen for overruns */ gettagbeg(); setifmt("{%",0); copy("I"); noifmt(); /*}*/ copy("S"); { char const* ilist_[2]; ilist_[0]=ilist_[1]=words[2]; setifmt( "0\n" "{ % Stack: \n" " currentfile read pop\n" " dup 37 eq{% '%'\n" " pop currentfile read pop\n" " dup 37 eq{pop pop exit}if % exit when '%%'\n" " }if\n" " % Stack: \n" " dup 42 lt{\n" " 30 sub\n" " % Stack: \n" " dup 0 gt{\n" " 3 copy getinterval\n" " % Stack: \n" " currentfile exch readstring pop pop\n" " % Stack: \n" " add 1 add\n" " }{pop}ifelse % skip newlines, tabs etc.\n" " }{\n" " 3 copy put\n" " pop 2 add % \\0 as space\n" " }ifelse\n" " % Stack: \n" "}$ bind loop\n" "% Stack: \n" "cvx exec $ bind exec\n" /* CONST, VAR s CODE futtatsa */ "currentfile token pop pop\n" /* A %%BeginData utni exec beolvassa */ "%\n", ilist_); copy("I"); noifmt(); } getotag("True"); gettagbeg(); copy("True"); setifmt("}{currentfile token pop pop%",0); copy("I"); noifmt(); getotag("False"); gettagbeg(); copy("False"); setifmt("}ifelse%",0); copy("I"); noifmt(); getotag("Defs"); gettagbeg(); compress0("Defs"); { char tok=gettok(); slen_t len; len=ibufb-ibuf; if (tok=='<' && len==4 && 0==memcmp(ibuf, "Data", 4)) { gettagbeg(); copydata("Data"); } else if (tok=='<' && len==4 && 0==memcmp(ibuf, "Fini", 4)) { fputs("%%BeginData:\nexec\n`S\n%%EndData\n",stdout); getotag("Fini"); gettagbeg(); copy("Fini"); newline(); fputs("%%Trailer\n%%EOF\n", stdout); } else erri("tag %, Fri, 7 Feb 2003 12:16:40 +0100 sam2p-0.49.2/debian/changelog0000644000175100017510000002012612212352017014120 0ustar ptsptssam2p (0.49.2) lucid; urgency=low * Fixed GCC 4.8 incompatibilities in ccdep.pl (the dependency generator of the build system) and elsewhere. * Fixed GCC gcc 4.6 and 4.8 warnings. * Fixed some harmless memory leaks. * Fixed integer-pointer sign bug with `gcc -fPIC' (so it works with the defaults of https://wiki.debian.org/Hardening, see https://code.google.com/p/sam2p/issues/detail?id=11). -- Peter Szabo Fri, 06 Sep 2013 15:06:32 +0200 sam2p (0.49.1) lucid; urgency=low * Fixed GCC 4.6 incompatibilities in ccdep.pl (the dependency generator of the build system). -- Peter Szabo Wed, 14 Dec 2011 17:44:47 +0100 sam2p (0.49-2) karmic; urgency=low * Fixed error reporting at cleanup time. * Fixed file closing for temporary file removal on Windows. -- Peter Szabo Thu, 30 Jun 2011 01:24:59 +0200 sam2p (0.49-1) karmic; urgency=low * Fixed version reporting in `sam2p --version'. -- Peter Szabo Wed, 29 Jun 2011 19:17:45 +0200 sam2p (0.48-1) karmic; urgency=low * Added sam2p_pdf_scale.pl to the files list. * Added examples/sam2p.spec for Fedora. -- Peter Szabo Tue, 22 Mar 2011 19:23:07 +0100 sam2p (0.47-1) unstable; urgency=low * Fixed some bugs. * Added some missing example files. * Clarified the documentation a bit. -- Szab Pter Sun, 8 Aug 2009 01:50:53 +0200 sam2p (0.46-2) unstable; urgency=low * image.cpp: added sortPal(), so now sam2p converts source images to canonical form. * encoder.cpp, sam2p_main.cpp: Fixed predictor autodetection ultimately. * Small compliation and documentation improvements. -- Szab Pter Sun, 5 Apr 2009 01:50:53 +0200 sam2p (0.46-1) unstable; urgency=low * Small bugfixes. * encoder.cpp: Fixed ``/Predictor 15'' so it produces an efficient predictor, similar to what libpng does. * sam2p_main.cpp: Made ``/Predictor 15'' automatic for ZIP or LZW compression if no `-c' command line flag was specified. -- Szab Pter Sun, 5 Apr 2009 01:50:53 +0200 sam2p (0.45-3) unstable; urgency=low * in_ps.c: improved PostScript EPS load support, forcing `showpage'. -- Szab Pter Thu, 10 Aug 2006 13:07:47 +0200 sam2p (0.45-2) unstable; urgency=low * cgif.c is indicated to be free software. -- Szab Pter Sun, 2 Jul 2006 23:04:21 +0200 sam2p (0.45-1) unstable; urgency=low * Small docs changes. * Little bugfixes. -- Szab Pter Sun, 2 Jul 2006 17:19:29 +0200 sam2p (0.44-14) unstable; urgency=low * assertion BUGFIX in image.cpp:1480 Image::SampledInfo::setSampleFormat() -- Szabo Peter Thu, 6 Apr 2006 15:13:11 +0200 sam2p (0.44-13) unstable; urgency=low * Added -j:quiet * No >/dev/null on png22pnm and tif22pnm -- Szab Pter Fri, 26 Aug 2005 08:29:56 +0200 sam2p (0.44-12) unstable; urgency=low * Fixed non-(0,0)-based EPS loading by putting `translate' after `setpagedevice' in in_ps.cpp -- Szab Pter Fri, 12 Aug 2005 23:13:38 +0200 sam2p (0.44-11) unstable; urgency=low * %%BeginData:; hack for GSView, as reported by Zoltn Petres -- Szab Pter Tue, 17 May 2005 14:39:20 +0200 sam2p (0.44-10) unstable; urgency=low * encoder.cpp slen_t -> int fixes for 64-bit. Thanks to Stefan Fritsch. -- Szab Pter Thu, 14 Apr 2005 09:23:01 +0200 sam2p (0.44-9) unstable; urgency=low * 64-bit fix (slen_t and slendiff_t), in reply to the report by Stefan Fritsch. -- Szab Pter Tue, 12 Apr 2005 20:51:40 +0200 sam2p (0.44-8) unstable; urgency=low * Added /ImageDPI and -m:dpi:, see README. * Fixed a couple of bugs. -- Szab Pter Mon, 21 Feb 2005 23:53:51 +0100 sam2p (0.44-7) unstable; urgency=low * Updated copyright of pts_fax.c * Updated copyright of cgif.c * BUGFIX of JPEG -> EPS `delete tp' buf in appliers.cpp -- Szab Pter Thu, 20 Jan 2005 15:11:23 +0100 sam2p (0.44-6) unstable; urgency=low * Re-ripped pts_defl.c from linux-2.6.8.1 (ZLIB 1.1.3), formerly it was Info-ZIP 2.2 * BUGFIX in image.cpp * Documentation fixes -- Szab Pter Tue, 18 Jan 2005 17:04:28 +0100 sam2p (0.44-5) unstable; urgency=low * Added -pdf:x (generate PDF with /XObject{}s). * Changed PDF output so elements of /Kids are indirect references (see the PDF Reference 1.5 for details). * Added option: -transparent "#abcdef" -- Szab Pter Sat, 8 Jan 2005 12:29:10 +0100 sam2p (0.44-4) unstable; urgency=low * Some glitches of g++-3.4 avoided. Now sam2p compiles fine. * -l:gs=-r216 support for PDF. -- Szab Pter Thu, 6 Jan 2005 10:59:50 +0100 sam2p (0.44-3) unstable; urgency=low * minor fixes, documentation addons -- Szab Pter Tue, 1 Jun 2004 18:50:15 +0200 sam2p (0.44-2) unstable; urgency=low * Added answers to FAQ in README. -- Szab Pter Fri, 5 Mar 2004 19:54:44 +0100 sam2p (0.44-1) unstable; urgency=low * bugfixes * PDF, PS and EPS import * compressed bts2.ttt, so target sam2p is smaller (ps_tiny --copy) * printf("%.16g") in configure -- Szab Pter Wed, 1 Oct 2003 19:49:32 +0200 sam2p (0.43-4) unstable; urgency=low * Allow to read stdin from a pipe * Recognize SOF2 (progressive) JPEG and other non-baseline types * Fixed SimBuffer::Flat::copyRange -- Szab Pter Tue, 11 Mar 2003 14:10:37 +0100 sam2p (0.43-3) unstable; urgency=low * Merged with CVS, created Debian source packages. -- Szab Pter Wed, 12 Feb 2003 20:51:58 +0100 sam2p (0.43-2) unstable; urgency=low * Added proper Description:, Depends: and Build-Depends: to debian/changelog, modified the Makefile to respect $(DESTDIR) etc. -- Szab Pter Fri, 7 Feb 2003 14:16:56 +0100 sam2p (0.43-1) unstable; urgency=low * Initial Debian release. * PDF generation bugfixes * PDF /MediaBox is output into a separate line near the beginning of file (graphicP compatibility) sam2p (0.41) unstable; urgency=low * vcsam2p.exe (graphic .exe with Visual Studio 6.0), merged * added Below feature -m:lower:5 * png22pnm support * Debian Slink pdfTeX integration -- Szab Pter Wed, 5 Feb 2003 18:40:12 +0100 sam2p (0.41) unstable; urgency=low * All earlier versions listed here: * 0.29 Apr 4 2002 sam2p_article.tex preliminary version * 0.30 Sat Apr 6 09:19:23 CEST 2002 * 0.31 -- Fri Apr 12 23:54:57 CEST 2002 not working TCL/TK GUI, sam2p_article corrected * 0.32 Sat Apr 13 12:55:09 CEST 2002 -- PCX input, class Encoder, class Decoder * 0.33 JPEG, TIFF, PNG input. JPEG output. * 0.34 PDF output, PNG output. * 0.35 Fri Apr 26 08:28:41 CEST 2002 transparency, gui, sam2p_talk, EuroBachoTeX 2002 * 0.36 Sat May 26 14:06:09 CEST 2002 Blanca bugfixes * 0.37 Sat Jun 1 14:06:43 CEST 2002 ccdep.pl, --enable-debug, XPM output, opaque TIFF output, more PS output, BMP output, transparent PNM output, one-liner mode, XWD output, PS output with margins, autoconf consts, built-in CCITTFaxEncode * 0.38 Tue Sep 3 20:16:59 CEST 2002 Many portability bugfixes. Now more versions of GNU C++ compilers and more achitectures are tested and supported. gcc-3.1 or gcc-3.2 compliance (AC_C_CONST working const; with autoconf 2.53) * 0.39 -j:warn, allow /OutputFile(-) (stdout) in one-liner mode, one-liner mode with src == dst filename `--', EPS margins, PDF margins, -m, scaling PS output command line, PSL1 Gray ZIP&LZW in all TransferEncodings * 0.40 Wed Dec 11 19:24:31 CET 2002 builds out-of-the box (./configure ...; make -> sam2p.exe) on Win32 with MinGW32 + Perl * 0.41 GIF and XPM load bugfixes synchronized to GIMP tif22pnm transparent(+?) TIFF output, really better tif22pnm support -- Szab Pter Wed, 5 Feb 2003 11:40:12 +0100 Local variables: mode: debian-changelog End: sam2p-0.49.2/debian/control0000644000175100017510000000212712211371426013656 0ustar ptsptsSource: sam2p Section: unknown Priority: optional Maintainer: Szab Pter Standards-Version: 3.2.1 Build-Depends: g++, perl Package: sam2p Architecture: any Depends: ${shlibs:Depends} Recommends: tif22pnm | netpbm, png22pnm | netpbm, libjpeg-progs Description: convert raster images to EPS and PDF and others sam2p is a UNIX command line utility written in ANSI C++ that converts many raster (bitmap) image formats into Adobe PostScript or PDF files. The images are not vectorized. sam2p gives full control to the user to specify standards-compliance, compression, and bit depths. In some cases sam2p can compress an image 100 times smaller than the PostScript output of many other common image converters. sam2p provides ZIP, RLE and LZW (de)compression filters even on Level1 devices. . Recommendations: package netpbm provides the tifftopnm and pngtopnm utilities. Please use tif22pnm and png22pnm (by the author of sam2p) instead of these, because *22* provides a much richer functionality with less bugs. package libjpeg-prog provides the excellent cjpeg and djpeg utilities. sam2p-0.49.2/debian/copyright0000644000175100017510000000021512211371426014202 0ustar ptsptsThis package was written by Szab Pter pts@winter on Fri, 7 Feb 2003 12:16:40 +0100. Copyright: GPL (see /usr/share/common-licenses/GPL) sam2p-0.49.2/debian/dirs0000644000175100017510000000004412211371426013133 0ustar ptsptsusr/bin usr/sbin usr/share/man/man1 sam2p-0.49.2/debian/rules0000755000175100017510000000377612211371426013346 0ustar ptspts#!/usr/bin/make -f # Made with the aid of debmake, by Christoph Lameter, # based on the sample debian/rules file for GNU hello by Ian Jackson. package=sam2p build: $(checkdir) ./configure --enable-gif --enable-lzw --prefix=/usr $(MAKE) touch build clean: $(checkdir) -rm -f build -$(MAKE) MAKE_DIST=1 clean -rm -f `find . -name "*~"` -rm -rf debian/tmp debian/files* core debian/substvars # Dat: make distclean would remove the `configure' script binary-indep: checkroot build $(checkdir) # There are no architecture-independent files to be uploaded # generated by this package. If there were any they would be # made here. binary-arch: checkroot build $(checkdir) -rm -rf debian/tmp install -d debian/tmp cd debian/tmp && install -d `cat ../dirs` $(MAKE) install prefix=`pwd`/debian/tmp/usr DESTDIR=`pwd`/debian/tmp/usr # Must have debmake installed for this to work. Otherwise please copy # /usr/bin/debstd into the debian directory and change debstd to debian/debstd debstd README README.1 README.2 README.3 README.4 README.5 README.6 README~ dpkg-gencontrol -isp chown -R root.root debian/tmp chmod -R go=rX debian/tmp dpkg --build debian/tmp .. define checkdir test -f debian/rules endef binary: $(checkdir) if test root = "`whoami`"; then $(MAKE) -f debian/rules binary-indep binary-arch; \ else fakeroot $(MAKE) -f debian/rules binary-indep binary-arch; fi checkroot: $(checkdir) test root = "`whoami`" .PHONY: binary binary-arch binary-indep clean checkroot .PHONY: source source-here source-here: rm -rf debsrc mkdir -p debsrc/debian cp -a $(wildcard $(addprefix debian/,README.debian docs changelog control copyright dirs rules prerm postrm postinst preinst)) debsrc/debian $(MAKEF) install-debsrc DIR="` []\n". "This program reads a PDF generated by sam2p, ". "and scales it to page size.\n" if @ARGV != 3 and @ARGV != 4; die "page-width not a nonnegative number\n" if $ARGV[0] !~ m@\A[\d.]+\Z(?!\n)@; die "page-height not a nonnegative number\n" if $ARGV[1] !~ m@\A[\d.]+\Z(?!\n)@; sub float2str($) { no integer; my $F = $_[0] + 0; $F = "$F"; if (index($F, 'e') >= 0) { $F = sprintf("%.20f", $F); $F =~ s@[.]?0+\Z@@; } $F } #** Desired page size dimensions. Must be integers, measured in bp (inch/72). my $dwidth = float2str($ARGV[0]); my $dheight = float2str($ARGV[1]); my $outfn = @ARGV == 4 ? $ARGV[3] : $ARGV[2]; my $F; die "cannot open input PDF: $ARGV[2]: $!\n" if !open($F, '<', $ARGV[2]); my $S = join('', <$F>); die if !close($F); die "sam2p PDF syntax error (no cm)\n" if $S!~m@\n((\d+) 0 0 (\d+) 0 0 cm\b)@g; my $cm_at = pos($S) - length($1); my $cm_size = length($1); my $iwidth = $2 + 0; my $iheight = $3 + 0; die "sam2p PDF image error (empty image)\n" if $iwidth < 0 or $iheight < 0; my $rest_at = rindex($S, "\nendstream\n") + 1; die "sam2p PDF syntax error (no endstream)\n" if $rest_at <= $cm_at; pos($S) = $rest_at; die "sam2p PDF syntax error (boxes not found)\n" if $S!~m@(/MediaBox\s*\[0 0 (\d+) (\d+)\]\s*/CropBox\s*\[0 0 (\d+) (\d+)\])@g; my $boxes_at = pos($S) - length($1); my $boxes_size = length($1); die "sam2p PDF syntax error (image size mismatch)\n" if $2 ne $iwidth or $3 ne $iheight or $4 ne $iwidth or $5 ne $iheight; my $boxes_new = "/MediaBox[0 0 $dwidth $dheight]\n/CropBox[0 0 $dwidth $dheight]"; substr($S, $boxes_at, $boxes_size) = $boxes_new; my($cwidth, $cheight); my($xshift, $yshift); { no integer; my $aheight = $iheight * $dwidth / $iwidth; my $bwidth = $iwidth * $dheight / $iheight; if ($aheight <= $dheight) { ($cwidth, $cheight) = ($dwidth, $aheight) } else { ($cwidth, $cheight) = ($bwidth, $dheight) } $xshift = ($dwidth - $cwidth) / 2; $yshift = ($dheight - $cheight) / 2; } my $cm_new = float2str($cwidth)." 0 0 ".float2str($cheight)." ". float2str($xshift)." ".float2str($yshift)." cm"; substr($S, $cm_at, $cm_size) = $cm_new; pos($S) = 0; if ($S =~ m@\n<>\nstream\nq\n)@g and pos($S) == $cm_at) { substr($S, pos($S) - length($1), length($2)) = sprintf("%".length($2)."d", $2 + length($cm_new) - $cm_size); } pos($S) = $boxes_at + length($boxes_new) + length($cm_new) - $cm_size; die "sam2p PDF syntax error (xref not found)\n" if $S!~m@\sendobj\n(xref\n0 (\d+)\n0000000000 65535 f \n)@g; my $xref_at = pos($S) - length($1); my $obj_count = $2 - 1; my $ofss_at = pos($S); for (my $I = 1; $I <= $obj_count; ++$I) { my $xrefe_at = $ofss_at + ($I - 1) * 20; my $xrefe = substr($S, $xrefe_at, 20); die "sam2p PDF syntax error (xref entry $I bad)\n" if $xrefe!~m@\A(\d{10}) 00000 n \n\Z(?!\n)@; my $ofs = $1 + 0; $ofs += ( ($ofs >= $boxes_at) ? length($boxes_new) - $boxes_size + length($cm_new) - $cm_size : ($ofs >= $cm_at) ? length($cm_new) - $cm_size : 0); substr($S, $xrefe_at, 20) = sprintf("%010d 00000 n \n", $ofs); } pos($S) = $ofss_at + $obj_count * 20; die "sam2p PDF syntax error (startxref not found)\n" if $S!~s@\nstartxref\n(\d+)\n@\nstartxref\n$xref_at\n@; die "cannot open output PDF: $outfn: $!\n" if !open($F, '>', $outfn); die if !print($F $S); die if !close($F);