From 8ab38aba60d29aa23b470dc1cb50e9c3e6e9b8da Mon Sep 17 00:00:00 2001 From: Panayotis Skordos Date: Wed, 10 Aug 1988 05:45:38 +0000 Subject: [PATCH] added halftoning routines: psam, ht-od, ht-bn, ht-ibn added image-laplacian, image-double-by-interpolation, write-image-2bint --- v7/src/microcode/sgraph_a.c | 1130 +++++++++++++++++++++++------------ 1 file changed, 748 insertions(+), 382 deletions(-) diff --git a/v7/src/microcode/sgraph_a.c b/v7/src/microcode/sgraph_a.c index 0a06301fb..1c301f70b 100644 --- a/v7/src/microcode/sgraph_a.c +++ b/v7/src/microcode/sgraph_a.c @@ -30,7 +30,7 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ -/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/sgraph_a.c,v 1.3 1988/07/15 09:03:54 cph Exp $ */ +/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/sgraph_a.c,v 1.4 1988/08/10 05:45:38 pas Exp $ */ #include "scheme.h" #include "primitive.h" @@ -320,46 +320,53 @@ Define_Primitive(Prim_Box_Rotate_Move, 2, "BOX-ROTATE-MOVE") block_read(screen_handle, x_source, y_source, ((int) x_length), ((int) y_length), x_dest, y_dest); - #if false Char_Array_90clw(); #else fprintf(stderr, "\nPrim_Box_Rotate_Move: Char_Array_90clw undefined.\n"); Primitive_Error(ERR_EXTERNAL_RETURN); #endif - + block_read(screen_handle, x_source, y_source, ((int) x_length), ((int) y_length), x_dest, y_dest); PRIMITIVE_RETURN(NIL); } - -/* START image drawing... */ -/* color_table entries 0 and 1 are not used */ -/* Just like in array-plotting, - find Min,Max and Offset Scale s.t. values fit in [2,15] intensity values */ + +/*_________________________________ image drawing ___________________________ */ -#define SCREEN_BACKGROUND_COLOR 0 -#define MINIMUM_INTENSITY_INDEX 2 -#define MAXIMUM_INTENSITY_INDEX 15 +/* + ;; Image Drawing (halftoning) + ;; HG = Hard Grey levels (i.e. output device greys) + ;; SG = Soft Grey levels (i.e. simulated grey levels) + ;; There are 3 methods: PSAM, OD, BN (see below) + There are also the old 16-color drawing routines. +*/ -/* ARGS = (image x_at y_at magnification) magnification can be 1, 2, or 3 - */ +/* + ;; PSAM (Pulse-Surface-Area Modulation) works only for 2 HG grey levels. + ;; It maps 1 pxl to a square of 16 pxls. + ;; The distribution of on/off pxls in the square gives 16 grey levels. + ;; It's the most efficient for B&W monitors, but see below for better quality drawing using OD and BN. + ;; Halftoning using OD and BN works for any number of grey levels, and there are many methods available (see below). + + IMAGE-PSAM-ATXY-WMM fixed magnification 1pxl->16pxls + Draw line (width 4) by line. Pdata space needed = (4*ncols*16) . + ;; The following 2 primitives simply take in arguments, and allocate space, + ;; They call C_image_psam_atxy_wmm to do the actual drawing. + */ -Define_Primitive(Prim_Draw_Magnify_Image_At_XY, 4, "DRAW-MAGNIFY-IMAGE-AT-XY") -{ - REAL x_at, y_at; - Pointer Pnrows, Pncols, Prest, Parray, Answer; +Define_Primitive(Prim_image_psam_atxy_wmm, 5, "IMAGE-PSAM-ATXY-WMM") +{ REAL x_at, y_at; + Pointer Pnrows, Pncols, Prest, Parray; Pointer *Orig_Free; long nrows, ncols, Length; - REAL *Array; + REAL *Array, Min,Max; unsigned char *pdata; int Error_Number; - long Magnification; - REAL Offset, Scale; /* To make intensities fit in [2,15] */ - Primitive_4_Args(); - - Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ + + Primitive_5_Args(); + Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); Pncols = Vector_Ref(Prest, CONS_CAR); @@ -376,54 +383,78 @@ Define_Primitive(Prim_Draw_Magnify_Image_At_XY, 4, "DRAW-MAGNIFY-IMAGE-AT-XY") Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ if (Error_Number == 1) Primitive_Error(ERR_ARG_3_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_3_WRONG_TYPE); - Arg_4_Type(TC_FIXNUM); - Range_Check(Magnification, Arg4, 1, 100, ERR_ARG_4_BAD_RANGE); - + + Error_Number = Scheme_Number_To_REAL(Arg4, &Min); + if (Error_Number == 1) Primitive_Error(ERR_ARG_4_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_4_WRONG_TYPE); + Error_Number = Scheme_Number_To_REAL(Arg5, &Max); + if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); Length = nrows*ncols; + + Primitive_GC_If_Needed( (16*4*ncols) * sizeof(unsigned char) ); + pdata = ((unsigned char *) Free); + /* the following draws the picture, clipping values outside Min,Max */ + C_image_psam_atxy_wmm(Array, pdata, nrows, ncols, + ((float) x_at), ((float) y_at), + Min, Max); + PRIMITIVE_RETURN(TRUTH); +} - { - REAL Array_Min, Array_Max; - long nmin, nmax; +Define_Primitive(Prim_image_psam_atxy_womm, 5, "IMAGE-PSAM-ATXY-WOMM") +{ REAL x_at, y_at; + Pointer Pnrows, Pncols, Prest, Parray; + Pointer *Orig_Free; + long nrows, ncols, Length; + REAL *Array, Min,Max; + unsigned char *pdata; + int Error_Number; + Primitive_5_Args(); - C_Array_Find_Min_Max(Array, Length, &nmin, &nmax); - Array_Min = Array[nmin]; Array_Max = Array[nmax]; - Find_Offset_Scale_For_Linear_Map(Array_Min, Array_Max, - 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ - - Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); - pdata = ((unsigned char *) Free); - Image_Draw_Magnify_N_Times_With_Offset_Scale(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale, - Magnification); - - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free+1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); - } + Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ + Pnrows = Vector_Ref(Arg1, CONS_CAR); + Prest = Vector_Ref(Arg1, CONS_CDR); + Pncols = Vector_Ref(Prest, CONS_CAR); + Prest = Vector_Ref(Prest, CONS_CDR); + Parray = Vector_Ref(Prest, CONS_CAR); + if (Vector_Ref(Prest, CONS_CDR) != NIL) Primitive_Error(ERR_ARG_1_WRONG_TYPE); + if (Type_Code(Parray) != TC_ARRAY) Primitive_Error(ERR_ARG_1_WRONG_TYPE); + Array = Scheme_Array_To_C_Array(Parray); /* ARRAY */ + Range_Check(nrows, Pnrows, 0, 512, ERR_ARG_1_BAD_RANGE); /* NROWS */ + Range_Check(ncols, Pncols, 0, 512, ERR_ARG_1_BAD_RANGE); /* NCOLS */ + Error_Number = Scheme_Number_To_REAL(Arg2, &x_at); /* X_AT */ + if (Error_Number == 1) Primitive_Error(ERR_ARG_2_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_2_WRONG_TYPE); + Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ + if (Error_Number == 1) Primitive_Error(ERR_ARG_3_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_3_WRONG_TYPE); + + Error_Number = Scheme_Number_To_REAL(Arg4, &Min); + if (Error_Number == 1) Primitive_Error(ERR_ARG_4_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_4_WRONG_TYPE); + Error_Number = Scheme_Number_To_REAL(Arg5, &Max); + if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); + Length = nrows*ncols; + + Primitive_GC_If_Needed( (16*4*ncols) * sizeof(unsigned char) ); + pdata = ((unsigned char *) Free); + C_image_psam_atxy_womm(Array, pdata, nrows, ncols, + ((float) x_at), ((float) y_at), + Min, Max); + PRIMITIVE_RETURN(TRUTH); } - -Define_Primitive(Prim_Draw_Magnify_Image_At_XY_With_Min_Max, 6, "DRAW-MAGNIFY-IMAGE-AT-XY-WITH-MIN-MAX") -{ - REAL x_at, y_at; - Pointer Pnrows, Pncols, Prest, Parray, Answer; + +Define_Primitive(Prim_image_ht_od_atxy_wmm, 7, "IMAGE-HT-OD-ATXY-WMM") +{ REAL x_at, y_at; + Pointer Pnrows, Pncols, Prest, Parray; Pointer *Orig_Free; - long nrows, ncols, Length; - REAL *Array, Offset, Scale, Min,Max; + long nrows, ncols, Length, HG, ODmethod; + REAL *Array, Min,Max; unsigned char *pdata; int Error_Number; - long Magnification; - Primitive_6_Args(); + Primitive_7_Args(); Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); @@ -448,47 +479,90 @@ Define_Primitive(Prim_Draw_Magnify_Image_At_XY_With_Min_Max, 6, "DRAW-MAGNIFY-IM Error_Number = Scheme_Number_To_REAL(Arg5, &Max); if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); + Length = nrows*ncols; Arg_6_Type(TC_FIXNUM); - Range_Check(Magnification, Arg6, 1, 100, ERR_ARG_6_BAD_RANGE); + Range_Check(HG, Arg6, 1, 256, ERR_ARG_6_BAD_RANGE); /* don't expect more color levels than this */ + Arg_7_Type(TC_FIXNUM); + Range_Check(ODmethod, Arg7, 0, 7, ERR_ARG_7_BAD_RANGE); /* see below HT_OD_TABLE_MAX_INDEX */ + Primitive_GC_If_Needed( ncols * sizeof(unsigned char) ); + pdata = ((unsigned char *) Free); + /* the following draws the picture, clipping values outside Min,Max */ + C_image_ht_od_atxy_wmm(Array, pdata, nrows,ncols, + ((float) x_at), ((float) y_at), Min,Max, + HG,ODmethod); + PRIMITIVE_RETURN(TRUTH); +} + +Define_Primitive(Prim_image_ht_bn_atxy_wmm, 7, "IMAGE-HT-BN-ATXY-WMM") +{ REAL x_at, y_at; + Pointer Pnrows, Pncols, Prest, Parray; + Pointer *Orig_Free; + long nrows, ncols, Length, HG, BNmethod; + REAL *Array, Min,Max; + unsigned char *pdata; + int Error_Number; + float **er_rows; + + Primitive_7_Args(); + Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ + Pnrows = Vector_Ref(Arg1, CONS_CAR); + Prest = Vector_Ref(Arg1, CONS_CDR); + Pncols = Vector_Ref(Prest, CONS_CAR); + Prest = Vector_Ref(Prest, CONS_CDR); + Parray = Vector_Ref(Prest, CONS_CAR); + if (Vector_Ref(Prest, CONS_CDR) != NIL) Primitive_Error(ERR_ARG_1_WRONG_TYPE); + if (Type_Code(Parray) != TC_ARRAY) Primitive_Error(ERR_ARG_1_WRONG_TYPE); + Array = Scheme_Array_To_C_Array(Parray); /* ARRAY */ + Range_Check(nrows, Pnrows, 0, 512, ERR_ARG_1_BAD_RANGE); /* NROWS */ + Range_Check(ncols, Pncols, 0, 512, ERR_ARG_1_BAD_RANGE); /* NCOLS */ + Error_Number = Scheme_Number_To_REAL(Arg2, &x_at); /* X_AT */ + if (Error_Number == 1) Primitive_Error(ERR_ARG_2_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_2_WRONG_TYPE); + Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ + if (Error_Number == 1) Primitive_Error(ERR_ARG_3_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_3_WRONG_TYPE); + + Error_Number = Scheme_Number_To_REAL(Arg4, &Min); + if (Error_Number == 1) Primitive_Error(ERR_ARG_4_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_4_WRONG_TYPE); + Error_Number = Scheme_Number_To_REAL(Arg5, &Max); + if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); + if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); Length = nrows*ncols; + Arg_6_Type(TC_FIXNUM); + Range_Check(HG, Arg6, 1, 256, ERR_ARG_6_BAD_RANGE); /* don't expect more color levels than this */ + Arg_7_Type(TC_FIXNUM); + Range_Check(BNmethod, Arg7, 0, 2, ERR_ARG_7_BAD_RANGE); /* 3 masks (methods) available, see below */ - /* NOW MAKE THE PICTURE, CLIPPING MIN, MAX */ - Find_Offset_Scale_For_Linear_Map(Min, Max, - 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ - - Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); + Primitive_GC_If_Needed( (ncols*sizeof(unsigned char)) + (3*(ncols+4) * sizeof(float)) ); + /* 1-row for pdata, and 3 rows of 2+ncols+2 length for er_rows */ + /* Primitive_GC_If_Needed takes either number of bytes, or number of scheme pointers,it works either way. */ pdata = ((unsigned char *) Free); - Image_Draw_Magnify_N_Times_With_Offset_Scale(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale, - Magnification); - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free+1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); + er_rows = ((float **) (pdata+ncols)); + er_rows[0] = ((float *) (er_rows+3)); + er_rows[1] = er_rows[0] + (ncols+4); + er_rows[2] = er_rows[1] + (ncols+4); + + C_image_ht_bn_atxy_wmm(Array, pdata, nrows,ncols, + ((float) x_at), ((float) y_at), Min,Max, + HG,BNmethod, er_rows); + PRIMITIVE_RETURN(TRUTH); } - -Define_Primitive(Prim_Draw_Magnify_Image_At_XY_Only_Between_Min_Max, 6, "DRAW-MAGNIFY-IMAGE-AT-XY-ONLY-BETWEEN-MIN-MAX") -{ - REAL x_at, y_at; - Pointer Pnrows, Pncols, Prest, Parray, Answer; + +#define MINTEGER long + +Define_Primitive(Prim_image_ht_ibn_atxy_wmm, 8, "IMAGE-HT-IBN-ATXY-WMM") +{ REAL x_at, y_at; + Pointer Pnrows, Pncols, Prest, Parray; Pointer *Orig_Free; - long nrows, ncols, Length; - REAL *Array, Offset, Scale, Min,Max; + long nrows, ncols, Length, HG, BNmethod; + REAL *Array, Min,Max; unsigned char *pdata; int Error_Number; - long Magnification; + MINTEGER **er_rows, PREC_SCALE; - Primitive_6_Args(); + Primitive_8_Args(); Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); @@ -513,73 +587,47 @@ Define_Primitive(Prim_Draw_Magnify_Image_At_XY_Only_Between_Min_Max, 6, "DRAW-MA Error_Number = Scheme_Number_To_REAL(Arg5, &Max); if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); - Arg_6_Type(TC_FIXNUM); - Range_Check(Magnification, Arg6, 1, 100, ERR_ARG_6_BAD_RANGE); - Length = nrows*ncols; + Arg_6_Type(TC_FIXNUM); + Range_Check(HG, Arg6, 1, 256, ERR_ARG_6_BAD_RANGE); /* don't expect more color levels than this */ + Arg_7_Type(TC_FIXNUM); + Range_Check(BNmethod, Arg7, 0, 2, ERR_ARG_7_BAD_RANGE); /* 3 masks (methods) available, see below */ + Arg_8_Type(TC_FIXNUM); + Range_Check(PREC_SCALE, Arg8, 1, (1<<(8*sizeof(MINTEGER)-2))/64, + ERR_ARG_8_BAD_RANGE); /* avoid overflow, BN~64, see below */ - /* NOW MAKE THE PICTURE, CLIPPING MIN, MAX */ - Find_Offset_Scale_For_Linear_Map(Min, Max, - 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ - - Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); + Primitive_GC_If_Needed( (ncols*sizeof(unsigned char)) + (3*(ncols+4) * sizeof(MINTEGER)) ); + /* 1-row for pdata, and 3 rows of 2+ncols+2 length for er_rows */ + /* Primitive_GC_If_Needed takes either number of bytes, or number of scheme pointers,it works either way. */ pdata = ((unsigned char *) Free); - Image_Draw_Magnify_N_Times_With_Offset_Scale_Only(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale, - Magnification); - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free + 1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); -} - -/* This is a very tricky procedure, But it's all geometry... -*/ -void -Find_Offset_Scale_For_Linear_Map(Min,Max, New_Min, New_Max, Offset, Scale) - REAL Min,Max, New_Min, New_Max, *Offset, *Scale; -{ - if ((Min == Max) && (Max == 0.0)) - { - *Scale = 0.0; - *Offset = (New_Max + New_Min) / 2.0; - } - else if (Min == Max) - { - *Scale = 0.25 * (mabs( (New_Max - New_Min) / Max ) ); - *Offset = (New_Max + New_Min) / 2.0; - } - else - { - *Scale = (New_Max - New_Min) / (Max - Min); - *Offset = New_Min- ((*Scale) * Min); - } + er_rows = ((MINTEGER **) (pdata+ncols)); + er_rows[0] = ((MINTEGER *) (er_rows+3)); + er_rows[1] = er_rows[0] + (ncols+4); + er_rows[2] = er_rows[1] + (ncols+4); + + C_image_ht_ibn_atxy_wmm(Array, pdata, nrows,ncols, + ((float) x_at), ((float) y_at), Min,Max, + HG,BNmethod, er_rows, PREC_SCALE); + PRIMITIVE_RETURN(TRUTH); } + -/* For B&W monitors there are 3 drawing-primitives similar to the previous 3 - above. BUT, these have a FIXED MAGNIFICATION 4times, and the code - is rather specialized, hacked especially for the 6003-jupiter-probset. - It's USE-AND-DON'T-ASK-QUESTIONS. - I could have used starbase (gescape, fill-color, rectangle, etc) but these - would have been too slow. So for the sake of efficiency, I hacked the screen bits - and I am doing my own dithering-algorithm (a 4x4 dither square is drawn for each - point in the image, giving a total of 16 colors). Draw line (width 4) by line. - Pdata space needed = (4*ncols*16) . +/* THE FOLLOWING 3 ROUTINES ARE THE OLD 16-color drawing routines + they also do magnification. */ -/* ARGS = (image x_at y_at) +/* color_table entries 0 and 1 are not used */ +/* Just like in array-plotting, + Use Min,Max and Offset,Scale s.t. values map into [2,15] */ + +#define SCREEN_BACKGROUND_COLOR 0 +#define MINIMUM_INTENSITY_INDEX 2 +#define MAXIMUM_INTENSITY_INDEX 15 + +/* ARGS = (image x_at y_at magnification) magnification can be 1, 2, or 3 */ -Define_Primitive(Prim_Draw_BW_Image_At_XY, 3, "DRAW-BW-IMAGE-AT-XY") +Define_Primitive(Prim_Draw_Magnify_Image_At_XY, 4, "DRAW-MAGNIFY-IMAGE-AT-XY") { REAL x_at, y_at; Pointer Pnrows, Pncols, Prest, Parray, Answer; @@ -588,10 +636,11 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY, 3, "DRAW-BW-IMAGE-AT-XY") REAL *Array; unsigned char *pdata; int Error_Number; - REAL Offset, Scale; /* To make intensities fit in [0,15] */ - Primitive_3_Args(); + long Magnification; + REAL Offset, Scale; /* To make intensities fit in [2,15] */ + Primitive_4_Args(); - Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ + Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); Pncols = Vector_Ref(Prest, CONS_CAR); @@ -608,38 +657,30 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY, 3, "DRAW-BW-IMAGE-AT-XY") Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ if (Error_Number == 1) Primitive_Error(ERR_ARG_3_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_3_WRONG_TYPE); - + Arg_4_Type(TC_FIXNUM); + Range_Check(Magnification, Arg4, 1, 100, ERR_ARG_4_BAD_RANGE); + Length = nrows*ncols; - { - REAL Array_Min, Array_Max; + { REAL Array_Min, Array_Max; long nmin, nmax; + C_Array_Find_Min_Max(Array, Length, &nmin, &nmax); Array_Min = Array[nmin]; Array_Max = Array[nmax]; Find_Offset_Scale_For_Linear_Map(Array_Min, Array_Max, - 0.0, 15.0, &Offset, &Scale); /* USE COLORS from 0 to 15 */ + 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ - Primitive_GC_If_Needed( (16*4*ncols) * sizeof(unsigned char) ); + Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); pdata = ((unsigned char *) Free); - Image_Draw_BW_With_Offset_Scale(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale); - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free+1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); + Image_Draw_Magnify_N_Times_With_Offset_Scale(Array, pdata, nrows, ncols, + ((float) x_at), ((float) y_at), + Offset, Scale, + Magnification); + PRIMITIVE_RETURN(TRUTH); } } -Define_Primitive(Prim_Draw_BW_Image_At_XY_With_Min_Max, 5, "DRAW-BW-IMAGE-AT-XY-WITH-MIN-MAX") +Define_Primitive(Prim_Draw_Magnify_Image_At_XY_With_Min_Max, 6, "DRAW-MAGNIFY-IMAGE-AT-XY-WITH-MIN-MAX") { REAL x_at, y_at; Pointer Pnrows, Pncols, Prest, Parray, Answer; @@ -648,9 +689,10 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY_With_Min_Max, 5, "DRAW-BW-IMAGE-AT-XY- REAL *Array, Offset, Scale, Min,Max; unsigned char *pdata; int Error_Number; + long Magnification; - Primitive_5_Args(); - Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ + Primitive_6_Args(); + Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); Pncols = Vector_Ref(Prest, CONS_CAR); @@ -658,13 +700,13 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY_With_Min_Max, 5, "DRAW-BW-IMAGE-AT-XY- Parray = Vector_Ref(Prest, CONS_CAR); if (Vector_Ref(Prest, CONS_CDR) != NIL) Primitive_Error(ERR_ARG_1_WRONG_TYPE); if (Type_Code(Parray) != TC_ARRAY) Primitive_Error(ERR_ARG_1_WRONG_TYPE); - Array = Scheme_Array_To_C_Array(Parray); /* ARRAY */ - Range_Check(nrows, Pnrows, 0, 512, ERR_ARG_1_BAD_RANGE); /* NROWS */ - Range_Check(ncols, Pncols, 0, 512, ERR_ARG_1_BAD_RANGE); /* NCOLS */ - Error_Number = Scheme_Number_To_REAL(Arg2, &x_at); /* X_AT */ + Array = Scheme_Array_To_C_Array(Parray); /* ARRAY */ + Range_Check(nrows, Pnrows, 0, 512, ERR_ARG_1_BAD_RANGE); /* NROWS */ + Range_Check(ncols, Pncols, 0, 512, ERR_ARG_1_BAD_RANGE); /* NCOLS */ + Error_Number = Scheme_Number_To_REAL(Arg2, &x_at); /* X_AT */ if (Error_Number == 1) Primitive_Error(ERR_ARG_2_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_2_WRONG_TYPE); - Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ + Error_Number = Scheme_Number_To_REAL(Arg3, &y_at); /* Y_AT */ if (Error_Number == 1) Primitive_Error(ERR_ARG_3_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_3_WRONG_TYPE); @@ -674,33 +716,25 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY_With_Min_Max, 5, "DRAW-BW-IMAGE-AT-XY- Error_Number = Scheme_Number_To_REAL(Arg5, &Max); if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); + Arg_6_Type(TC_FIXNUM); + Range_Check(Magnification, Arg6, 1, 100, ERR_ARG_6_BAD_RANGE); Length = nrows*ncols; /* NOW MAKE THE PICTURE, CLIPPING MIN, MAX */ Find_Offset_Scale_For_Linear_Map(Min, Max, - 0.0, 15.0, &Offset, &Scale); /* USE COLORS from 0 to 15 */ + 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ - Primitive_GC_If_Needed( (16*4*ncols) * sizeof(unsigned char) ); + Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); pdata = ((unsigned char *) Free); - Image_Draw_BW_With_Offset_Scale(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale); - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free+1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); + Image_Draw_Magnify_N_Times_With_Offset_Scale(Array, pdata, nrows, ncols, + ((float) x_at), ((float) y_at), + Offset, Scale, + Magnification); + PRIMITIVE_RETURN(TRUTH); } -Define_Primitive(Prim_Draw_BW_Image_At_XY_Only_Between_Min_Max, 5, "DRAW-BW-IMAGE-AT-XY-ONLY-BETWEEN-MIN-MAX") +Define_Primitive(Prim_Draw_Magnify_Image_At_XY_Only_Between_Min_Max, 6, "DRAW-MAGNIFY-IMAGE-AT-XY-ONLY-BETWEEN-MIN-MAX") { REAL x_at, y_at; Pointer Pnrows, Pncols, Prest, Parray, Answer; @@ -709,8 +743,9 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY_Only_Between_Min_Max, 5, "DRAW-BW-IMAG REAL *Array, Offset, Scale, Min,Max; unsigned char *pdata; int Error_Number; - Primitive_5_Args(); - + long Magnification; + + Primitive_6_Args(); Arg_1_Type(TC_LIST); /* '(nrows ncols array) */ Pnrows = Vector_Ref(Arg1, CONS_CAR); Prest = Vector_Ref(Arg1, CONS_CDR); @@ -735,247 +770,582 @@ Define_Primitive(Prim_Draw_BW_Image_At_XY_Only_Between_Min_Max, 5, "DRAW-BW-IMAG Error_Number = Scheme_Number_To_REAL(Arg5, &Max); if (Error_Number == 1) Primitive_Error(ERR_ARG_5_BAD_RANGE); if (Error_Number == 2) Primitive_Error(ERR_ARG_5_WRONG_TYPE); + Arg_6_Type(TC_FIXNUM); + Range_Check(Magnification, Arg6, 1, 100, ERR_ARG_6_BAD_RANGE); Length = nrows*ncols; /* NOW MAKE THE PICTURE, CLIPPING MIN, MAX */ Find_Offset_Scale_For_Linear_Map(Min, Max, - 0.0, 15.0, &Offset, &Scale); /* USE COLORS from 0 to 15 */ - Primitive_GC_If_Needed( (16*4*ncols) * sizeof(unsigned char) ); + 2.0, 15.0, &Offset, &Scale); /* Do not use colors 0 and 1 */ + + Primitive_GC_If_Needed( (Magnification*ncols) * sizeof(unsigned char) ); pdata = ((unsigned char *) Free); - Image_Draw_BW_With_Offset_Scale_Only(Array, pdata, nrows, ncols, - ((float) x_at), ((float) y_at), - Offset, Scale); - Primitive_GC_If_Needed(4); - Answer = Make_Pointer(TC_LIST, Free); - Orig_Free = Free; - Free += 4; - My_Store_Reduced_Flonum_Result(Offset, *Orig_Free); - Orig_Free++; - *Orig_Free = Make_Pointer(TC_LIST, Orig_Free+1); - Orig_Free++; - My_Store_Reduced_Flonum_Result(Scale, *Orig_Free); - Orig_Free++; - *Orig_Free = NIL; - PRIMITIVE_RETURN(Answer); + Image_Draw_Magnify_N_Times_With_Offset_Scale_Only(Array, pdata, nrows, ncols, + ((float) x_at), ((float) y_at), + Offset, Scale, + Magnification); + PRIMITIVE_RETURN(TRUTH); } -/******************************************************************************/ -/* THE REAL DRAWING ROUTINES + +/*_______________________________________________________________________________*/ +/* Below are the real drawing routines */ + +/* ht = halftoning + od = ordered-dither (dispersed dot), Ulichney terminology + bn = blue noise (also called: minimized average error) + psam = pulse surface area modulation + Also, there are the old drawing routines for 16 colors, which are basically + fixed threshold ordered dither. + */ + +/* The macro Adjust_Value_Wmm is used by most drawing routines. + The macro Adjust_Value_Womm is used only by psam-atxy-womm. + REAL value, newvalue, ngreys_min, ngreys_max, Vmin,Vmax, offset,scale; + offset, scale must be such as to map (min,max) into (ngreys_min,ngreys_max) + */ +#define Adjust_Value_Wmm(value, newvalue, ngreys_min, ngreys_max, Vmin, Vmax, offset, scale) \ +{ if (value >= Vmax) newvalue = ngreys_max; \ + else if (value <= Vmin) newvalue = ngreys_min; \ + else newvalue = offset + (value * scale); } +#define Adjust_Value_Womm(value, newvalue, ngreys_min, ngreys_max, Vmin, Vmax, offset, scale) \ +{ if (value >= Vmax) newvalue = ngreys_min; \ + else if (value <= Vmin) newvalue = ngreys_min; \ + else newvalue = offset + (value * scale); } + + +/* The following geometrical map is slightly tricky. */ +void Find_Offset_Scale_For_Linear_Map(Min,Max, New_Min, New_Max, Offset, Scale) + REAL Min,Max, New_Min, New_Max, *Offset, *Scale; +{ /* no local variables */ + if ((Min == Max) && (Max == 0.0)) + { *Scale = 0.0; *Offset = (New_Max + New_Min) / 2.0; } + else if (Min == Max) + { *Scale = 0.25 * (mabs( (New_Max - New_Min) / Max ) ); + *Offset = (New_Max + New_Min) / 2.0; } + else + { *Scale = (New_Max - New_Min) / (Max - Min); + *Offset = New_Min- ((*Scale) * Min); } +} + #define Round_REAL(x) ((long) ((x >= 0) ? (x+.5) : (x-.5))) -/* Image_Draw_Magnify_N_Times : N^2 in area +/* Ordered Dither MASKS + A mask is a SQUARE matrix of threshold values, + that is effectively replicated periodically all over the image. + + ht_od_table[][0] ---> int SG; number of soft greys + ht_od_table[][1] ---> int SGarray_nrows; nrows=ncols i.e. square matrix of threshold values + ht_od_table[][2+i] ----> int SGarray[36]; threshold values with range [0,SG). + + ATTENTION: Currently, the LARGEST SGarray is 6X6 MATRIX + */ + +static int ht_od_table[8][2+36] = +{ {2,1, 1}, /* fixed threshold at halfpoint */ + {3,2, 1,2,2,1}, /* this one and following 4 come from Ulichney p.135 */ + {5,3, 2,3,2, 4,1,4, 2,3,2}, + {9,4, 1,8,2,7, 5,3,6,4, 2,7,1,8, 6,4,5,3}, + {17,5, 2,16,3,13,2, 10,6,11,7,10, 4,14,1,15,4, 12,8,9,5,12, 2,16,3,13,2}, + {33,6, 1,30,8,28,2,29, 17,9,24,16,18,10, 5,25,3,32,6,26, 21,13,19,11,22,14, 2,29,7,27,1,30, 18,10,23,15,17,9}, + {4,2, 0,2,3,1}, /* this one and following 1 come from Jarvis,Judice,Ninke: CGIP 5, p.23 */ + {17,4, 0,8,2,10, 12,4,14,6, 3,11,1,9, 15,7,13,5} +}; +#define HT_OD_TABLE_MAX_INDEX 7 + +/* ordered dither + pdata must have length ncols + HG= Hardware Grey levels (output pixel values 0,HG-1) + ODmethod is index for ht_od method + */ + +C_image_ht_od_atxy_wmm(Array, pdata, nrows,ncols, x_at,y_at, Min,Max, HG,ODmethod) + REAL Array[], Min,Max; + unsigned char *pdata; + int nrows,ncols,HG,ODmethod; + float x_at,y_at; +{ int i,j, SG, *SGarray, SGarray_nrows, dither, pixel, array_index; + REAL REAL_pixel, value, offset,scale, HG1_SG; + /* static int ht_od_table[][]; */ + /* void Find_Offset_Scale_For_Linear_Map(); */ + + if (ODmethod>HT_OD_TABLE_MAX_INDEX) {printf("HT_OD methods 0,7 only\n");fflush(stdout);return(0);}; + SG = ht_od_table[ODmethod][0]; + SGarray_nrows = ht_od_table[ODmethod][1]; /* nrows=ncols */ + SGarray = &(ht_od_table[ODmethod][2]); /* square matrix */ + + HG1_SG = ((REAL) ((HG-1)*SG)); + Find_Offset_Scale_For_Linear_Map(Min, Max, + 0.0, HG1_SG, &offset, &scale); /* HG output greys */ + array_index=0; + for (i=0; iR/2 R 0" */ + pdata[j] = ((unsigned char) INT_pixel); /* output pixel to be painted */ + er_rows[ER_R1][ER_C +j] = (pixel/2.0) - ((float) INT_pixel); /* error estimate */ + } + block_write(screen_handle, x_at, (y_at-((float) i)), ncols, 1, pdata, 0); /* paint a row */ + /* */ + temp = er_rows[0]; /* rotate rows */ + er_rows[0] = er_rows[1]; + er_rows[1] = er_rows[2]; + er_rows[2] = temp; + for (m=ER_C;m 15.0) - pixel = MAXIMUM_INTENSITY_INDEX; - else if (REAL_pixel < 2.0) - pixel = MINIMUM_INTENSITY_INDEX; - else - pixel = ((unsigned char) (Round_REAL(REAL_pixel))); - for (m = 0; m < N; m++) - { - pdata[j] = pixel; - j++; - } + for (i=0;iR/2 R 0" */ + pdata[j] = ((unsigned char) INT_pixel); /* output pixel to be painted */ + er_rows[ER_R1][ER_C +j] = (pixel/2.0) - ((float) INT_pixel); /* error estimate */ } - for (m = 0; m < N; m++) - { - block_write(screen_handle, x_origin, y_origin-i, ncolsN, 1, pdata, 0); - i++; + block_write(screen_handle, x_at, (y_at-((float) i)), ncols, 1, pdata, 0); /* paint a row */ + /* */ + temp = er_rows[0]; /* rotate rows */ + er_rows[0] = er_rows[1]; + er_rows[1] = er_rows[2]; + er_rows[2] = temp; + for (m=ER_C;mR/2 R 0" */ + pdata[j] = ((unsigned char) INT_pixel); /* output pixel to be painted */ + er_rows[ER_R1][ER_C +j] = (pixel/2.0) - ((float) INT_pixel); /* error estimate */ } - /* A(i,j) --> Array[i*ncols + j] */ + block_write(screen_handle, x_at, (y_at-((float) i)), ncols, 1, pdata, 0); /* paint a row */ + /* */ + temp = er_rows[0]; /* rotate rows */ + er_rows[0] = er_rows[1]; + er_rows[1] = er_rows[2]; + er_rows[2] = temp; + for (m=ER_C;m int BN; sum of error weights + ht_ibn_table[][1] ---> int BNentries; number of weight entries + ht_ibn_table[][2+i+0,1,2] ----> int row_offset,col_offset,weight; + */ + +static int ht_ibn_table[3][2+(3*12)] = +{ {16,4, -1,-1,1, -1,0,5, -1,1,3, 0,-1,7}, + {48,12, -2,-2,1, -2,-1,3, -2,0,5, -2,1,3, -2,2,1, + -1,-2,3, -1,-1,5, -1,0,7, -1,1,5, -1,2,3, + 0,-2,5, 0,-1,7}, + {42,12, -2,-2,1, -2,-1,2, -2,0,4, -2,1,2, -2,2,1, + -1,-2,2, -1,-1,4, -1,0,8, -1,1,4, -1,2,2, + 0,-2,4, 0,-1,8} +}; + +/* + er_rows[][] should be 3 arrays of integers, of length (ncols+2*ER_C), which store previous errors, (ALLOCATED STORAGE) + ER_R is number of error rows, (currently 3) + ER_C is number of extra columns (to the left and to the right) of each er_row, + they always contain ZEROS and serve to simplify the error summing process, i.e. we don't have + to check for i,j bounds at edges, (no conditionals in the sum loop). + Also, the code handles all cases in a uniform manner. + (for better explanation get pas halftoning notes) + */ +C_image_ht_ibn_atxy_wmm(Array, pdata, nrows,ncols, x_at,y_at, Min,Max, HG,BNmethod, er_rows, PREC_SCALE) + REAL Array[], Min,Max; + unsigned char *pdata; + int nrows,ncols,HG,BNmethod; + MINTEGER **er_rows, PREC_SCALE; + float x_at,y_at; +{ int i,j, m, BNentries, array_index, row_offset, col_offset; + MINTEGER BN, ersum, weight, PREC_2, PREC, *temp, pixel; + /* PREC is a scale factor that varies the precision in ersum -- using integer arithmetic for speed */ + REAL REAL_pixel, value, offset,scale, HG1_2_PREC; + static int ER_R=3, ER_R1=2, ER_C=2, ER_C1=1; - array_index = 0; - for (i = 0; i < nrowsN;) /* note that i is NOT incremented here */ - { - for (j = 0; j < ncolsN;) /* note that j is NOT incremented here */ - { - REAL_pixel = Offset + (Array[array_index++] * Scale); - if (REAL_pixel > 15.0) - pixel = SCREEN_BACKGROUND_COLOR; - else if (REAL_pixel < 2.0) - pixel = SCREEN_BACKGROUND_COLOR; - else - pixel = ((unsigned char) (Round_REAL(REAL_pixel))); - for (m = 0; m < N; m++) - { - pdata[j] = pixel; - j++; - } - } - for (m = 0; m < N; m++) - { - block_write(screen_handle, x_origin, y_origin - i, ncolsN, 1, pdata, 0); - i++; + for (i=0;i Array[i*ncols + j] */ + block_write(screen_handle, x_at, (y_at-((float) i)), ncols, 1, pdata, 0); /* paint a row */ + /* */ + temp = er_rows[0]; /* rotate rows */ + er_rows[0] = er_rows[1]; + er_rows[1] = er_rows[2]; + er_rows[2] = temp; + for (m=0;m<(ncols+(2*ER_C));m++) er_rows[2][m]=0; /* initialize (clean up) the new error row */ } } - -/* Here are 2 routines for BW monitors. */ -/* First, Image_Draw_BW_With_Offset_Scale. + + + +/* PSAM drawing (see scheme primitives above, for description) Pdata must be 4*16*ncols in size. */ - -Image_Draw_BW_With_Offset_Scale(Array, pdata, nrows, ncols, x_origin, y_origin, Offset, Scale) - REAL Array[], Offset, Scale; +C_image_psam_atxy_wmm(Array, pdata, nrows, ncols, x_origin, y_origin, Min,Max) + REAL Array[], Min,Max; unsigned char *pdata; /* pdata should have length 16*4*ncols */ long nrows, ncols; float x_origin, y_origin; -{ - register long i,j, i4; +{ register long i,j, i4; register long array_index, pdata_index; long ncols4 = 4 * ncols; long color_index; - REAL REAL_pixel; + REAL REAL_pixel, value, offset,scale; + + Find_Offset_Scale_For_Linear_Map(Min, Max, + 0.0, 15.0, &offset, &scale); /* 16 grey levels */ - array_index = 0; i4 = 0; - for (i = 0; i < nrows; i++) - { - pdata_index = 0; - for (j = 0; j < ncols; j++) - { - REAL_pixel = Offset + (Array[array_index++] * Scale); - if (REAL_pixel > 15.0) - color_index = 15; - else if (REAL_pixel < 0.0) - color_index = 0; - else color_index = ((long) (REAL_pixel + .5)); + array_index=0; i4=0; + for (i=0; i Array[i*ncols + j] */ } - -/* Image_Draw_BW_With_Offset_Scale_Only. - Pdata must be 4*16*ncols in size. - */ -Image_Draw_BW_With_Offset_Scale_Only(Array, pdata, nrows, ncols, x_origin, y_origin, Offset, Scale) - REAL Array[], Offset, Scale; + +/* Same as above, except use Adjust_Value_Womm. + */ +C_image_psam_atxy_womm(Array, pdata, nrows, ncols, x_origin, y_origin, Min,Max) + REAL Array[], Min,Max; unsigned char *pdata; /* pdata should have length 16*4*ncols */ long nrows, ncols; float x_origin, y_origin; -{ - register long i,j, i4; +{ register long i,j, i4; register long array_index, pdata_index; long ncols4 = 4*ncols; long color_index; - REAL REAL_pixel; + REAL REAL_pixel, value, offset,scale; - array_index = 0; i4 = 0; - for (i = 0;i < nrows;i++) - { - pdata_index = 0; - for (j = 0; j < ncols; j++) - { - REAL_pixel = Offset + (Array[array_index++] * Scale); - if (REAL_pixel > 15.0) - color_index = 0; /* WITH_OFFSET_SCALE_ONLY */ - else if (REAL_pixel < 0.0) - color_index = 0; - else color_index = ((long) (REAL_pixel + .5)); + Find_Offset_Scale_For_Linear_Map(Min, Max, + 0.0, 15.0, &offset, &scale); /* 16 grey levels */ + array_index=0; i4=0; + for (i=0; i Array[i*ncols + j] */ } - -/* dither 11 is left out { 1,1,0,1, 1,1,1,0, 0,1,1,0, 1,0,1,1 } */ + +/* psam dither[11] is left out, { 1,1,0,1, 1,1,1,0, 0,1,1,0, 1,0,1,1 } */ /* The following routine writes a 4x4 dither cell in 4 consecutive rows of pdata. It assumes a lot about pdata and the other args passed to it. READ carefully. - Designed TO BE USED ONLY BY Image_Draw_Bw_With_Offset_Scale. + Designed TO BE USED BY C_image_psam_atxy_wmm */ my_write_dither(pdata, pdata_row_index, ncols , color_index) unsigned char *pdata; long pdata_row_index, ncols; long color_index; /* should be 0 to 15 */ -{ - static unsigned char dither_table[16][16] = {{ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }, - { 0,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,0 }, - { 0,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,0 }, - { 0,0,0,0, 0,1,1,0, 0,0,1,0, 0,0,0,0 }, - { 0,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0 }, - { 1,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0 }, - { 1,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,1 }, - { 1,0,0,1, 0,1,1,0, 0,1,1,0, 0,0,0,1 }, - { 1,0,0,1, 0,1,1,0, 0,1,1,0, 1,0,0,1 }, - { 1,1,0,1, 0,1,1,0, 0,1,1,0, 1,0,0,1 }, - { 1,1,0,1, 1,1,1,0, 0,1,1,0, 1,0,0,1 }, - { 1,1,0,1, 1,1,1,0, 0,1,1,1, 1,0,1,1 }, - { 1,1,0,1, 1,1,1,0, 1,1,1,1, 1,0,1,1 }, - { 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,1,1 }, - { 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,1,1,1 }, - { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 } - }; +{ static unsigned char dither_table[16][16] = {{ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }, + { 0,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,0 }, + { 0,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,0 }, + { 0,0,0,0, 0,1,1,0, 0,0,1,0, 0,0,0,0 }, + { 0,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0 }, + { 1,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0 }, + { 1,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,1 }, + { 1,0,0,1, 0,1,1,0, 0,1,1,0, 0,0,0,1 }, + { 1,0,0,1, 0,1,1,0, 0,1,1,0, 1,0,0,1 }, + { 1,1,0,1, 0,1,1,0, 0,1,1,0, 1,0,0,1 }, + { 1,1,0,1, 1,1,1,0, 0,1,1,0, 1,0,0,1 }, + { 1,1,0,1, 1,1,1,0, 0,1,1,1, 1,0,1,1 }, + { 1,1,0,1, 1,1,1,0, 1,1,1,1, 1,0,1,1 }, + { 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,1,1 }, + { 1,1,1,1, 1,1,1,0, 1,1,1,1, 1,1,1,1 }, + { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 }}; long i, row_start,m; long dither_index; /* do not mix up the counters, indexes */ + dither_index=0; + for (i=0;i<4;i++) { row_start = pdata_row_index + (i*ncols); + for (m=row_start; m 15.0) + pixel = MAXIMUM_INTENSITY_INDEX; + else if (REAL_pixel < 2.0) + pixel = MINIMUM_INTENSITY_INDEX; + else + pixel = ((unsigned char) (Round_REAL(REAL_pixel))); + for (m=0; m Array[i*ncols + j] */ + } +} + +/* Image_Draw_Magnify_N_Times_Only : N^2 in area + This procedure throws away (i.e. maps to SCREEN_BACKGROUND_COLOR) + all values outside the range given by Offset,Scale. + */ +Image_Draw_Magnify_N_Times_With_Offset_Scale_Only(Array, pdata, nrows, ncols, + x_origin, y_origin, Offset, Scale, N) + REAL Array[], Offset, Scale; + unsigned char *pdata; + long nrows, ncols, N; + float x_origin, y_origin; +{ register long i,j,m; + register long array_index; + long ncolsN= N * ncols; + long nrowsN= N * nrows; + register unsigned char pixel; + register REAL REAL_pixel; + + array_index = 0; + for (i=0; i 15.0) pixel = SCREEN_BACKGROUND_COLOR; + else if (REAL_pixel < 2.0) pixel = SCREEN_BACKGROUND_COLOR; + else pixel = ((unsigned char) (Round_REAL(REAL_pixel))); + for (m=0; m Array[i*ncols + j] */ } } + + /* END image drawing */ + -/* COLOR (or B&W INTENSITIES) OPERATIONS - */ +/*_______________________ Grey Level Manipulations _____________________ */ Define_Primitive(Prim_New_Color, 4, "NEW-COLOR") -{ - int i, err; +{ int i, err; long index; float red, green, blue; Primitive_4_Args(); @@ -994,19 +1364,17 @@ Define_Primitive(Prim_New_Color, 4, "NEW-COLOR") } Define_Primitive(Prim_Inquire_Colors, 0, "INQUIRE-COLORS") -{ - int i; +{ int i; Primitive_0_Args(); inquire_color_table(screen_handle, STARBASE_COLOR_TABLE_START, STARBASE_COLOR_TABLE_SIZE, Color_Table); for (i = 0; i < STARBASE_COLOR_TABLE_SIZE; i++) - printf("%d %f %f %f\n", i, Color_Table[i][0], Color_Table[i][1], Color_Table[i][2]); /* implem. dependent */ + printf("%d %f %f %f\n", i, Color_Table[i][0], Color_Table[i][1], Color_Table[i][2]); /* implem. dependent */ PRIMITIVE_RETURN(TRUTH); } Define_Primitive(Prim_Inquire_Color, 1, "INQUIRE-COLOR") -{ - int i; int index; +{ int i; int index; Pointer Answer, *Orig_Free; REAL red, green, blue; Primitive_1_Args(); @@ -1038,8 +1406,7 @@ Define_Primitive(Prim_Inquire_Color, 1, "INQUIRE-COLOR") } Define_Primitive(Prim_Read_Colors_From_File, 1, "READ-COLORS-FROM-FILE") -{ - long i; +{ long i; FILE *fopen(), *fp; char *file_string; Boolean Open_File(); @@ -1056,15 +1423,14 @@ Define_Primitive(Prim_Read_Colors_From_File, 1, "READ-COLORS-FROM-FILE") for (i = 0; i < STARBASE_COLOR_TABLE_SIZE; i++) fscanf(fp,"%f %f %f\n", &Color_Table[i][0], &Color_Table[i][1], &Color_Table[i][2]); - Close_File(fp); /* fflush(stdout); */ + Close_File(fp); /* fflush(stdout); */ define_color_table(screen_handle, STARBASE_COLOR_TABLE_START, STARBASE_COLOR_TABLE_SIZE, Color_Table); PRIMITIVE_RETURN(TRUTH); } Define_Primitive(Prim_Save_Colors_In_File, 1, "SAVE-COLORS-IN-FILE") -{ - long i; +{ long i; FILE *fopen(), *fp; char *file_string; Boolean Open_File(); -- 2.25.1