mirror of
https://git.FreeBSD.org/ports.git
synced 2024-11-17 00:00:40 +00:00
696 lines
20 KiB
Plaintext
696 lines
20 KiB
Plaintext
--- gui.c.orig Thu Jul 28 05:53:01 1994
|
|
+++ gui.c Thu Sep 26 03:42:22 1996
|
|
@@ -12,10 +12,17 @@
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
+#ifdef JPEG
|
|
+#include <jpeglib.h>
|
|
+#include <setjmp.h>
|
|
+typedef unsigned char uint8;
|
|
+#endif
|
|
+
|
|
#include <X11/Xlib.h>
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/Shell.h>
|
|
+#include <X11/Xaw/Simple.h>
|
|
#include <X11/Xaw/Command.h>
|
|
#include <X11/Xaw/Label.h>
|
|
#include <X11/Xaw/Form.h>
|
|
@@ -24,16 +31,24 @@
|
|
#include <X11/Xaw/SimpleMenu.h>
|
|
#include <X11/Xaw/SmeBSB.h>
|
|
#include <X11/Xaw/SmeLine.h>
|
|
+#include <X11/Xaw/Scrollbar.h>
|
|
#include "Plain.h"
|
|
|
|
#include "gui.h"
|
|
#include "colour.h"
|
|
#include "scl.h"
|
|
|
|
+#include "hpscan.icon"
|
|
+
|
|
static Widget shell, form, controlform, canvas;
|
|
static Widget previewb, zoomb, scanb, quitb;
|
|
static Widget resolutionl, resolutionb, resolutionm, messagel;
|
|
static Widget filenamel, filenamet;
|
|
+static Widget intensitylabel, intensityscr, intensityval;
|
|
+static Widget contrastlabel, contrastscr, contrastval;
|
|
+#ifdef JPEG
|
|
+static Widget qualitylabel, qualityscr, qualityval;
|
|
+#endif
|
|
|
|
static XtAppContext app;
|
|
Display *display;
|
|
@@ -43,18 +58,57 @@
|
|
int screendepth;
|
|
static GC image_gc;
|
|
static Colormap cmap;
|
|
+static Atom delwin; /* the delete window atom */
|
|
|
|
-static int canvas_width = 300;
|
|
+static int canvas_width;
|
|
static int canvas_height;
|
|
|
|
static int resolution_list[] = {75, 100, 150, 200, 300, 400, 600};
|
|
|
|
+static int min_intensity, max_intensity, min_contrast, max_contrast;
|
|
+static int intensity, contrast;
|
|
+
|
|
static char *fallback[] = {
|
|
"*.canvas.translations: #override\\n\
|
|
<Key>: input() \\n\
|
|
<Motion>: input() \\n\
|
|
<BtnDown>: input() \\n\
|
|
- <BtnUp>: input() \\n",
|
|
+ <BtnUp>: input() ",
|
|
+ "*.preview.label: Preview",
|
|
+ "*.zoom.label: Zoom",
|
|
+ "*.scan.label: Scan",
|
|
+ "*.quit.label: Quit",
|
|
+ "*.resolution.label: Resolution",
|
|
+ "*.resolutionVal.borderWidth: 0",
|
|
+ "*.message.horizDistance: 40",
|
|
+ "*.message.borderWidth: 0",
|
|
+ "*.filenamelabel.label: Filename:",
|
|
+ "*.filenamelabel.borderWidth: 0",
|
|
+ "*.filename.width: 210",
|
|
+ "*.canvas.width: 300",
|
|
+ "*.intensityLabel.label: Intensity:",
|
|
+ "*.intensityLabel.borderWidth: 0",
|
|
+ "*.intensityVal.borderWidth: 0",
|
|
+ "*.intensityScrollbar.width: 120",
|
|
+ "*.intensityScrollbar.height: 15",
|
|
+ "*.intensityScrollbar.minimumThumb: 8",
|
|
+ "*.intensityScrollbar.topOfThumb: 0.5",
|
|
+ "*.contrastLabel.label: Contrast: ",
|
|
+ "*.contrastLabel.borderWidth: 0",
|
|
+ "*.contrastVal.borderWidth: 0",
|
|
+ "*.contrastScrollbar.width: 120",
|
|
+ "*.contrastScrollbar.height: 15",
|
|
+ "*.contrastScrollbar.minimumThumb: 8",
|
|
+ "*.contrastScrollbar.topOfThumb: 0.5",
|
|
+#ifdef JPEG
|
|
+ "*.qualityLabel.label: Quality: ",
|
|
+ "*.qualityLabel.borderWidth: 0",
|
|
+ "*.qualityVal.borderWidth: 0",
|
|
+ "*.qualityScrollbar.width: 120",
|
|
+ "*.qualityScrollbar.height: 15",
|
|
+ "*.qualityScrollbar.minimumThumb: 8",
|
|
+ "*.qualityScrollbar.topOfThumb: 0.75",
|
|
+#endif
|
|
(char *)0
|
|
};
|
|
|
|
@@ -71,8 +125,16 @@
|
|
static void scan(Widget w, XtPointer client, XtPointer call);
|
|
static void quit(Widget w, XtPointer client, XtPointer call);
|
|
static void resolution(Widget w, XtPointer client, XtPointer call);
|
|
+static void movethumb(Widget w, XtPointer client, XtPointer call);
|
|
+static void scrollthumb(Widget w, XtPointer client, XtPointer call);
|
|
+#ifdef JPEG
|
|
+static int writejpg(FILE *outfile, int quality, int height, int width,
|
|
+ uint8 *src);
|
|
+static int quality;
|
|
+#endif
|
|
|
|
-static struct raw_image *do_scan(int l, int t, int w, int h, int res,int type);
|
|
+static struct raw_image *do_scan(int l, int t, int w, int h, int res,
|
|
+ int intensity, int contrast, int type);
|
|
static XImage *make_image(struct raw_image *raw);
|
|
static int gamma_correct(int input);
|
|
static void find_box(struct raw_image *raw);
|
|
@@ -82,6 +144,14 @@
|
|
static void adjust_box(int edge, int x, int y);
|
|
static void set_message(char *message);
|
|
|
|
+static void actionHook(Widget w, XtPointer cld, String name, XEvent *xev,
|
|
+ String *params, Cardinal *num_params);
|
|
+static void GlobalProtoHandler(Widget w, XEvent *xev, String *p, Cardinal *n);
|
|
+
|
|
+static XtActionsRec actions[] = { {"GlobalProtoHandler", GlobalProtoHandler}};
|
|
+
|
|
+#define TransTableMessage "<Message>WM_PROTOCOLS : GlobalProtoHandler()"
|
|
+
|
|
static int scanner_to_canvas_x(int x);
|
|
static int scanner_to_canvas_y(int y);
|
|
static int canvas_to_scanner_x(int x);
|
|
@@ -118,19 +188,39 @@
|
|
{
|
|
Widget w;
|
|
Widget colourmap_widgets[2];
|
|
- int i;
|
|
+ int i, lo, hi;
|
|
char buf[20];
|
|
+ XtActionHookId ahid;
|
|
+ XWMHints *wmhints;
|
|
|
|
scanner_fd = fd;
|
|
|
|
shell =
|
|
- XtVaAppInitialize(&app, "Scanner", 0, 0, &argc, argv, fallback,
|
|
+ XtVaAppInitialize(&app, "HPscan", 0, 0, &argc, argv, fallback,
|
|
(String)0);
|
|
|
|
+ ahid = XtAppAddActionHook(app, actionHook, NULL);
|
|
+
|
|
display = XtDisplay(shell);
|
|
screen = XtScreen(shell);
|
|
+ screendepth = DefaultDepthOfScreen(screen);
|
|
root = RootWindowOfScreen(screen);
|
|
-
|
|
+
|
|
+ /* Get various values from the scanner for later processing. */
|
|
+ GetMinIntensity(scanner_fd, &min_intensity);
|
|
+ GetMaxIntensity(scanner_fd, &max_intensity);
|
|
+ intensity = (max_intensity - min_intensity) / 2 + min_intensity;
|
|
+ GetMinContrast(scanner_fd, &min_contrast);
|
|
+ GetMaxContrast(scanner_fd, &max_contrast);
|
|
+ contrast = (max_contrast - min_contrast) / 2 + min_contrast;
|
|
+ GetMaxXExtentDecipoints(scanner_fd, &scanner_width);
|
|
+ GetMaxYExtentDecipoints(scanner_fd, &scanner_height);
|
|
+
|
|
+#ifdef JPEG
|
|
+ /* Set initial JPEG quality */
|
|
+ quality = 75;
|
|
+#endif
|
|
+
|
|
form =
|
|
XtVaCreateManagedWidget("form", formWidgetClass, shell,
|
|
(String)0);
|
|
@@ -143,14 +233,12 @@
|
|
|
|
previewb =
|
|
XtVaCreateManagedWidget("preview", commandWidgetClass, controlform,
|
|
- XtNlabel, "Preview",
|
|
(String)0);
|
|
XtAddCallback(previewb, XtNcallback, preview, (XtPointer)False);
|
|
|
|
zoomb =
|
|
XtVaCreateManagedWidget("zoom", commandWidgetClass, controlform,
|
|
XtNfromHoriz, previewb,
|
|
- XtNlabel, "Zoom",
|
|
XtNsensitive, False,
|
|
(String)0);
|
|
XtAddCallback(zoomb, XtNcallback, preview, (XtPointer)True);
|
|
@@ -158,7 +246,6 @@
|
|
scanb =
|
|
XtVaCreateManagedWidget("scan", commandWidgetClass, controlform,
|
|
XtNfromHoriz, zoomb,
|
|
- XtNlabel, "Scan",
|
|
XtNsensitive, False,
|
|
(String)0);
|
|
XtAddCallback(scanb, XtNcallback, scan, (XtPointer)0);
|
|
@@ -166,7 +253,6 @@
|
|
quitb =
|
|
XtVaCreateManagedWidget("quit", commandWidgetClass, controlform,
|
|
XtNfromHoriz, scanb,
|
|
- XtNlabel, "Quit",
|
|
(String)0);
|
|
XtAddCallback(quitb, XtNcallback, quit, (XtPointer)0);
|
|
|
|
@@ -175,7 +261,6 @@
|
|
controlform,
|
|
XtNfromVert, previewb,
|
|
XtNmenuName, "resolutionmenu",
|
|
- XtNlabel, "Resolution",
|
|
(String)0);
|
|
resolutionm =
|
|
XtVaCreatePopupShell("resolutionmenu", simpleMenuWidgetClass,
|
|
@@ -196,7 +281,7 @@
|
|
|
|
sprintf(buf, "%d dpi", final_resolution);
|
|
resolutionl =
|
|
- XtVaCreateManagedWidget("resolution", labelWidgetClass, controlform,
|
|
+ XtVaCreateManagedWidget("resolutionVal", labelWidgetClass, controlform,
|
|
XtNfromHoriz, resolutionb,
|
|
XtNfromVert, previewb,
|
|
XtNlabel, buf,
|
|
@@ -205,46 +290,130 @@
|
|
messagel =
|
|
XtVaCreateManagedWidget("message", labelWidgetClass, controlform,
|
|
XtNfromHoriz, resolutionl,
|
|
- XtNhorizDistance, 40,
|
|
XtNfromVert, previewb,
|
|
- /* Scan failed fits in the space */
|
|
- XtNlabel, " ",
|
|
+ /* Out of memory! fits in the space */
|
|
+ XtNlabel, " ",
|
|
(String)0);
|
|
|
|
filenamel =
|
|
XtVaCreateManagedWidget("filenamelabel", labelWidgetClass, controlform,
|
|
XtNfromVert, resolutionb,
|
|
- XtNlabel, "Filename:",
|
|
(String)0);
|
|
|
|
filenamet =
|
|
XtVaCreateManagedWidget("filename", asciiTextWidgetClass, controlform,
|
|
XtNfromHoriz, filenamel,
|
|
XtNfromVert, resolutionb,
|
|
- XtNwidth, canvas_width - 90, /* XXX */
|
|
+#ifdef JPEG
|
|
+ XtNstring, "image.jpg",
|
|
+#else
|
|
XtNstring, "image.ppm",
|
|
+#endif
|
|
XtNeditType, XawtextEdit,
|
|
(String)0);
|
|
|
|
- /* Create the preview area */
|
|
+ intensitylabel =
|
|
+ XtVaCreateManagedWidget("intensityLabel", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromVert, filenamel,
|
|
+ (String)0);
|
|
|
|
- GetMaxXExtentDecipoints(scanner_fd, &scanner_width);
|
|
- GetMaxYExtentDecipoints(scanner_fd, &scanner_height);
|
|
+ sprintf(buf, "%5d", intensity);
|
|
+ intensityval =
|
|
+ XtVaCreateManagedWidget("intensityVal", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, intensitylabel,
|
|
+ XtNfromVert, filenamel,
|
|
+ XtNlabel, buf,
|
|
+ (String)0);
|
|
|
|
- canvas_height = canvas_width * ((double)scanner_height / scanner_width);
|
|
+ intensityscr =
|
|
+ XtVaCreateManagedWidget("intensityScrollbar", scrollbarWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, intensityval,
|
|
+ XtNfromVert, filenamel,
|
|
+ XtNorientation, XtorientHorizontal,
|
|
+ (String)0);
|
|
+
|
|
+ XtAddCallback(intensityscr, "jumpProc", movethumb, (XtPointer)&intensity);
|
|
+ XtAddCallback(intensityscr, "scrollProc", scrollthumb, (XtPointer)&intensity);
|
|
+
|
|
+ contrastlabel =
|
|
+ XtVaCreateManagedWidget("contrastLabel", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromVert, intensitylabel,
|
|
+ (String)0);
|
|
+
|
|
+ sprintf(buf, "%5d", contrast);
|
|
+ contrastval =
|
|
+ XtVaCreateManagedWidget("contrastVal", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, contrastlabel,
|
|
+ XtNfromVert, intensitylabel,
|
|
+ XtNlabel, buf,
|
|
+ (String)0);
|
|
+
|
|
+ contrastscr =
|
|
+ XtVaCreateManagedWidget("contrastScrollbar", scrollbarWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, contrastval,
|
|
+ XtNfromVert, intensitylabel,
|
|
+ XtNorientation, XtorientHorizontal,
|
|
+ (String)0);
|
|
+
|
|
+ XtAddCallback(contrastscr, "jumpProc", movethumb, (XtPointer)&contrast);
|
|
+ XtAddCallback(contrastscr, "scrollProc", scrollthumb, (XtPointer)&contrast);
|
|
+
|
|
+#ifdef JPEG
|
|
+ qualitylabel =
|
|
+ XtVaCreateManagedWidget("qualityLabel", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromVert, contrastlabel,
|
|
+ (String)0);
|
|
+
|
|
+ sprintf(buf, "%5d", quality);
|
|
+ qualityval =
|
|
+ XtVaCreateManagedWidget("qualityVal", labelWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, qualitylabel,
|
|
+ XtNfromVert, contrastlabel,
|
|
+ XtNlabel, buf,
|
|
+ (String)0);
|
|
+
|
|
+ qualityscr =
|
|
+ XtVaCreateManagedWidget("qualityScrollbar", scrollbarWidgetClass,
|
|
+ controlform,
|
|
+ XtNfromHoriz, qualityval,
|
|
+ XtNfromVert, contrastlabel,
|
|
+ XtNorientation, XtorientHorizontal,
|
|
+ (String)0);
|
|
+
|
|
+ XtAddCallback(qualityscr, "jumpProc", movethumb, (XtPointer)&quality);
|
|
+ XtAddCallback(qualityscr, "scrollProc", scrollthumb, (XtPointer)&quality);
|
|
+#endif /* JPEG */
|
|
+
|
|
+ /* Create the preview area */
|
|
|
|
canvas =
|
|
XtVaCreateManagedWidget("canvas", plainWidgetClass, form,
|
|
- XtNwidth, canvas_width,
|
|
- XtNheight, canvas_height,
|
|
XtNfromVert, controlform,
|
|
+ XtNheight, 1,
|
|
(String)0);
|
|
+ XtVaGetValues(canvas, XtNwidth, &canvas_width, (String)0);
|
|
+
|
|
+ /*
|
|
+ * The width value is settable via a resource, the height value is
|
|
+ * derived from it according to the scanner's aspect ratio.
|
|
+ */
|
|
+ canvas_height = canvas_width * ((double)scanner_height / scanner_width);
|
|
+ XtVaSetValues(canvas, XtNheight, canvas_height, (String)0);
|
|
+
|
|
XtAddCallback(canvas, "exposeCallback", redraw, (XtPointer)0);
|
|
XtAddCallback(canvas, "inputCallback", input, (XtPointer)0);
|
|
XtVaGetValues(canvas, XtNvisual, &visual, (String)0);
|
|
|
|
XtRealizeWidget(shell);
|
|
-
|
|
+
|
|
/* Set up colour map etc */
|
|
|
|
colourmap_widgets[0] = canvas;
|
|
@@ -258,6 +427,25 @@
|
|
XSetForeground(display, image_gc, colour_match(0, 0, 0, 0, 0, 0));
|
|
XSetBackground(display, image_gc, colour_match(255, 255, 255, 0, 0, 0));
|
|
|
|
+ /* Make the `delete' window manager function happy. */
|
|
+ delwin = XInternAtom(display, "WM_DELETE_WINDOW", False);
|
|
+ XSetWMProtocols(display, XtWindow(shell), &delwin, 1);
|
|
+ XtAppAddActions(app, actions, 1);
|
|
+ XtOverrideTranslations(shell, XtParseTranslationTable(TransTableMessage));
|
|
+
|
|
+ /* Now finally, tell the WM about our icon wishes. */
|
|
+ if((wmhints = XAllocWMHints()) == NULL)
|
|
+ XtError("Out of memory.");
|
|
+ wmhints->flags = IconPixmapHint;
|
|
+ wmhints->icon_pixmap = XCreateBitmapFromData(display, XtWindow(shell),
|
|
+ hpscan_bits,
|
|
+ hpscan_width, hpscan_height);
|
|
+ XmbSetWMProperties(display, XtWindow(shell),
|
|
+ "HPscan", "HPscan",
|
|
+ argv, argc,
|
|
+ NULL, wmhints, NULL);
|
|
+ XFree(wmhints);
|
|
+
|
|
XtAppMainLoop(app);
|
|
}
|
|
|
|
@@ -419,7 +607,13 @@
|
|
prev_resolution = (canvas_width * 720) / prev_width;
|
|
|
|
raw = do_scan(prev_left, prev_top, prev_width, prev_height,
|
|
- prev_resolution, 5);
|
|
+ prev_resolution, intensity, contrast, 5);
|
|
+ if (raw == 0)
|
|
+ {
|
|
+ set_message("Out of memory!");
|
|
+ return;
|
|
+ }
|
|
+
|
|
prev_pixwidth = raw->width;
|
|
prev_pixheight = raw->height;
|
|
|
|
@@ -440,6 +634,8 @@
|
|
XtSetSensitive(zoomb, image != 0);
|
|
XtSetSensitive(scanb, image != 0);
|
|
|
|
+ free(raw->data);
|
|
+
|
|
redraw(canvas, 0, 0);
|
|
}
|
|
|
|
@@ -455,28 +651,35 @@
|
|
|
|
XtVaGetValues(filenamet, XtNstring, &filename, (String)0);
|
|
|
|
- raw =
|
|
- do_scan(box_left, box_top, box_right-box_left+1, box_bottom-box_top+1,
|
|
- final_resolution, 5);
|
|
-
|
|
- /* Write it out as a ppm file (nice and easy!) */
|
|
+ raw = do_scan(box_left, box_top, box_right - box_left + 1,
|
|
+ box_bottom-box_top + 1, final_resolution,
|
|
+ intensity, contrast, 5);
|
|
|
|
if(raw)
|
|
{
|
|
f = fopen(filename, "w");
|
|
- if(!f)
|
|
+ if (!f)
|
|
{
|
|
XBell(display, 0);
|
|
fprintf(stderr, "can't open %s for writing\n", filename);
|
|
return;
|
|
}
|
|
|
|
+#ifdef JPEG
|
|
+ set_message("JPEGing...");
|
|
+ writejpg(f, quality, raw->height, raw->width, raw->data);
|
|
+#else
|
|
+ set_message("PPMing...");
|
|
+ /* Write it out as a ppm file (nice and easy!) */
|
|
fprintf(f, "P6\n%d %d\n255\n", raw->width, raw->height);
|
|
fwrite(raw->data, 1, raw->linebytes * raw->height, f);
|
|
-
|
|
+#endif
|
|
fclose(f);
|
|
+ free(raw->data);
|
|
+ set_message("Done!");
|
|
}
|
|
-
|
|
+ else
|
|
+ set_message("Out of memory!");
|
|
}
|
|
|
|
/*
|
|
@@ -502,17 +705,85 @@
|
|
XtVaSetValues(resolutionl, XtNlabel, buf, (String)0);
|
|
}
|
|
|
|
+/*
|
|
+ * Move the thumb of a scrollbar, update the according value as we go.
|
|
+ */
|
|
+
|
|
+static void movethumb(Widget w, XtPointer client, XtPointer call)
|
|
+{
|
|
+ char buf[20];
|
|
+ float percent = *(float *)call;
|
|
+ int *val_p = (int *)client;
|
|
+
|
|
+ if (percent > 1.0)
|
|
+ percent = 1.0;
|
|
+ else if (percent < 0.0)
|
|
+ percent = 0.0;
|
|
+
|
|
+ if (val_p == &intensity) {
|
|
+ *val_p = (max_intensity - min_intensity) * percent + min_intensity;
|
|
+ sprintf(buf, "%5d", *val_p);
|
|
+ XtVaSetValues(intensityval, XtNlabel, buf, (String)0);
|
|
+ } else if (val_p == &contrast) {
|
|
+ *val_p = (max_contrast - min_contrast) * percent + min_contrast;
|
|
+ sprintf(buf, "%5d", *val_p);
|
|
+ XtVaSetValues(contrastval, XtNlabel, buf, (String)0);
|
|
+#ifdef JPEG
|
|
+ } else if (val_p == &quality) {
|
|
+ *val_p = (int)(100 * percent);
|
|
+ sprintf(buf, "%5d", *val_p);
|
|
+ XtVaSetValues(qualityval, XtNlabel, buf, (String)0);
|
|
+#endif
|
|
+ } else
|
|
+ XtAppError(app, "unknown client in movethumb()");
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Almost the same as above, but called by the scrollProc callback.
|
|
+ */
|
|
+
|
|
+static void scrollthumb(Widget w, XtPointer client, XtPointer call)
|
|
+{
|
|
+ char buf[20];
|
|
+ int position = (int)call;
|
|
+ int *val_p = (int *)client;
|
|
+ float shown, topofthumb;
|
|
+
|
|
+ XtVaGetValues(w,
|
|
+ XtNshown, &shown,
|
|
+ XtNtopOfThumb, &topofthumb,
|
|
+ (String)0);
|
|
+ topofthumb -= 0.0001 * (float)position;
|
|
+ if (topofthumb < 0.0) topofthumb = 0.0;
|
|
+ else if (topofthumb > 1.0) topofthumb = 1.0;
|
|
+ XawScrollbarSetThumb(w, topofthumb, shown);
|
|
+
|
|
+ if (val_p == &intensity) {
|
|
+ *val_p = (max_intensity - min_intensity) * topofthumb + min_intensity;
|
|
+ sprintf(buf, "%5d", *val_p);
|
|
+ XtVaSetValues(intensityval,
|
|
+ XtNlabel, buf,
|
|
+ (String)0);
|
|
+ } else if (val_p = &contrast) {
|
|
+ *val_p = (max_contrast - min_contrast) * topofthumb + min_contrast;
|
|
+ sprintf(buf, "%5d", *val_p);
|
|
+ XtVaSetValues(contrastval,
|
|
+ XtNlabel, buf,
|
|
+ (String)0);
|
|
+ } else
|
|
+ XtAppError(app, "unknown client in movethumb()");
|
|
+}
|
|
+
|
|
/*
|
|
* Perform a scan, returning an XImage (return struct is statically allocated).
|
|
*/
|
|
|
|
-static struct raw_image *do_scan(int l, int t, int w, int h, int res, int type)
|
|
+static struct raw_image *
|
|
+do_scan(int l, int t, int w, int h, int res, int intensity,
|
|
+ int contrast, int type)
|
|
{
|
|
static struct raw_image raw;
|
|
|
|
- if(raw.data)
|
|
- free(raw.data);
|
|
-
|
|
SetXPositionDecipoints(scanner_fd, l);
|
|
SetYPositionDecipoints(scanner_fd, t);
|
|
SetXExtentDecipoints(scanner_fd, w);
|
|
@@ -524,14 +795,17 @@
|
|
SetXResolution(scanner_fd, res);
|
|
SetYResolution(scanner_fd, res);
|
|
|
|
+ SetIntensity(scanner_fd, intensity);
|
|
+ SetContrast(scanner_fd, contrast);
|
|
+
|
|
GetPixelsPerLine(scanner_fd, &raw.width);
|
|
GetLinesPerScan(scanner_fd, &raw.height);
|
|
GetBytesPerLine(scanner_fd, &raw.linebytes);
|
|
raw.type = type;
|
|
- raw.data = malloc(raw.height * raw.linebytes);
|
|
+ raw.data = malloc(raw.height * raw.width * 4);
|
|
if(!raw.data)
|
|
{
|
|
- fprintf(stderr, "Can't malloc %d bytes\n", raw.height * raw.linebytes);
|
|
+ fprintf(stderr, "Can't malloc %d bytes\n", raw.height * raw.width * 4);
|
|
return 0;
|
|
}
|
|
|
|
@@ -555,26 +829,44 @@
|
|
XImage *im;
|
|
unsigned char *newdata, *p;
|
|
int x, y;
|
|
+ int pad;
|
|
|
|
+ switch(screendepth)
|
|
+ {
|
|
+ case 1:
|
|
+ case 8:
|
|
+ pad = 8; break;
|
|
+ case 15:
|
|
+ case 16:
|
|
+ pad = 16; break;
|
|
+ case 24:
|
|
+ case 32:
|
|
+ pad = 32; break;
|
|
+ default:
|
|
+ fprintf(stderr, "Don't know how to handle depth %d\n", screendepth);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
if(!raw)
|
|
return 0;
|
|
|
|
switch(raw->type)
|
|
{
|
|
case 5: /* 24 bit colour */
|
|
- newdata = malloc(raw->width * raw->height);
|
|
+ newdata = malloc(raw->width * raw->height * (pad / 8));
|
|
if(!newdata)
|
|
{
|
|
fprintf(stderr, "Can't malloc %d bytes\n", raw->width*raw->height);
|
|
return 0;
|
|
}
|
|
- im = XCreateImage(display, visual, 8, ZPixmap, 0, newdata,
|
|
- raw->width, raw->height, 8, raw->width);
|
|
+ im = XCreateImage(display, visual, screendepth, ZPixmap, 0, newdata,
|
|
+ raw->width, raw->height, pad,
|
|
+ raw->width * (pad / 8));
|
|
|
|
/* Convert to fixed colour map using simple error propagation */
|
|
|
|
p = raw->data;
|
|
- for(y=0; y<raw->height; y++)
|
|
+ for (y = 0; y < raw->height; y++)
|
|
{
|
|
int r, g, b, r_err = 0, g_err = 0, b_err = 0;
|
|
|
|
@@ -646,7 +938,7 @@
|
|
|
|
for(y=MARGIN; y<raw->height-MARGIN; y++)
|
|
{
|
|
- p = raw->data + (y * raw->width + MARGIN) * 3;
|
|
+ p = raw->data + y * raw->width + MARGIN * 3;
|
|
|
|
for(x=MARGIN; x<raw->width-MARGIN; x++)
|
|
{
|
|
@@ -741,6 +1033,24 @@
|
|
XFlush(display);
|
|
}
|
|
|
|
+
|
|
+/*
|
|
+ * Window manager legacy.
|
|
+ */
|
|
+
|
|
+static void
|
|
+actionHook(Widget w, XtPointer cld, String name, XEvent *xev,
|
|
+ String *params, Cardinal *num_params)
|
|
+{
|
|
+}
|
|
+
|
|
+static void GlobalProtoHandler(Widget w, XEvent *xev, String *p, Cardinal *n)
|
|
+{
|
|
+ if (xev->xclient.data.l[0] == delwin) {
|
|
+ if (w == shell) exit(EXIT_SUCCESS); else XtPopdown(w);
|
|
+ }
|
|
+}
|
|
+
|
|
/*
|
|
* Functions for converting between a pixel position in the canvas
|
|
* and a decipoint position on the scanner.
|
|
@@ -766,3 +1076,35 @@
|
|
return prev_top + (y * 720 + prev_resolution/2) / prev_resolution;
|
|
}
|
|
|
|
+#ifdef JPEG
|
|
+static int
|
|
+writejpg(FILE *outfile, int quality, int height, int width, uint8 *src)
|
|
+{
|
|
+ char *copybuf = NULL;
|
|
+ struct jpeg_compress_struct cinfo;
|
|
+ struct jpeg_error_mgr jerr;
|
|
+ JSAMPROW row_pointer[1];
|
|
+ int i;
|
|
+ uint8 *p;
|
|
+
|
|
+ cinfo.err = jpeg_std_error(&jerr);
|
|
+ jpeg_create_compress(&cinfo);
|
|
+ jpeg_stdio_dest(&cinfo, outfile);
|
|
+
|
|
+ cinfo.image_width = width;
|
|
+ cinfo.image_height = height;
|
|
+ cinfo.input_components = 3;
|
|
+ cinfo.in_color_space = JCS_RGB;
|
|
+ jpeg_set_defaults(&cinfo);
|
|
+ jpeg_set_quality(&cinfo, quality, TRUE);
|
|
+
|
|
+ jpeg_start_compress(&cinfo, TRUE);
|
|
+ while (cinfo.next_scanline < cinfo.image_height) {
|
|
+ row_pointer[0] = src;
|
|
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
|
+ src += (width * 3);
|
|
+ }
|
|
+ jpeg_finish_compress(&cinfo);
|
|
+ jpeg_destroy_compress(&cinfo);
|
|
+}
|
|
+#endif
|