#ifndef lint static char sccsid[] = "@(#)image.c 9.6 88/02/10 Copyright 1987 Sun Micro"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- PostScript image manipulation routines. image.c, Mon Jul 7 18:31:32 1986 */ #include #ifdef REF #include #endif #include "PostScript.h" #include #include extern unsigned char ReverseBitsInByte[]; static readcanvas(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; char fn[200]; register len; register PSFILE *f; extern struct pixrect *cs_readimage(); register struct body *b; register struct pixrect *pr; if (optop[-1].type == string_type) { len = optop[-1].value.substring.length; strncpy(fn, body_of(optop - 1)->body.string.chars + optop[-1].value.substring.start, len); fn[len] = 0; f = psio_open(fn, "r"); if (f == 0) { ee->error_code = undefinedfilename_error_code; return; } } else if (optop[-1].type == file_type) { f = body_of(optop - 1)->body.file.inbuf; if (f == 0) { ee->error_code = invalidaccess_error_code; return; } } else { ee->error_code = typecheck_error_code; return; } pr = cs_readimage(f); if (optop[-1].type == string_type) psio_close(f); if (pr == 0) { ee->error_code = invalidaccess_error_code; return; } object_decref(optop - 1); create_object_from_image(optop - 1, pr); } static writecanvas(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; char fn[200]; register len; register PSFILE *f; extern struct pixrect *cs_writeimage(); if (optop[-1].type == string_type) { len = optop[-1].value.substring.length; strncpy(fn, body_of(optop - 1)->body.string.chars + optop[-1].value.substring.start, len); fn[len] = 0; f = psio_open(fn, "w"); if (f == 0) { ee->error_code = undefinedfilename_error_code; return; } } else if (optop[-1].type == file_type) { f = body_of(optop - 1)->body.file.outbuf; if (f == 0) { ee->error_code = invalidaccess_error_code; return; } } else { ee->error_code = typecheck_error_code; return; } len = ee->execee.value.def->index; cs_writeimage(&ee->gontext, f, ~(len&1), len&2); if (optop[-1].type == string_type) psio_close(f); object_decref(optop - 1); ee->optop--; } imagecanvas(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; if (optop[-1].type != canvas_type) { ee->error_code = typecheck_error_code; return; } cs_imagecanvas(&ee->gontext, optop[-1].value.canvas, 0); object_decref(optop-1); ee->optop--; } imagemaskcanvas(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; if (optop[-1].type != canvas_type || optop[-2].type != boolean_type) { ee->error_code = typecheck_error_code; return; } cs_imagecanvas(&ee->gontext, optop[-1].value.canvas, optop[-2].value.fixed ? -1 : 1); object_decref(optop-1); ee->optop -= 2; } buildmore(es, obj) register struct execution_stack *es; register struct object *obj; { char *str = body_of(obj)->body.string.chars + obj->value.substring.start; register struct pixrect *pr = es->env.image.image; register struct mpr_data *mprd = mpr_d(pr); if (obj->value.substring.length <= 0) { /* EOF */ es->env.image.remaining = 0; } else if (pr->pr_depth == 8 && (pr->pr_width & 1) == 0 || pr->pr_depth == 1 && ((pr->pr_width + 7) & 0x8) == 0) { /* pixrect padding corresponds to PostScript padding */ register n = obj->value.substring.length; if (n > es->env.image.remaining) n = es->env.image.remaining; bcopy(str, ((char *) mprd->md_image) + es->env.image.pos, n); es->env.image.pos += n; es->env.image.remaining -= n; } else while (1) { register n = obj->value.substring.length; if (n > es->env.image.remrow) n = es->env.image.remrow; bcopy(str, ((char *) mprd->md_image) + es->env.image.pos, n); es->env.image.pos += n; es->env.image.remaining -= n; es->env.image.remrow -= n; str += n; if (es->env.image.remrow <= 0) { if (es->env.image.pos & 1) es->env.image.pos++; switch (pr->pr_depth) { case 24: case 8: es->env.image.remrow = pr->pr_width * (pr->pr_depth >> 3); break; case 4: es->env.image.remrow = (pr->pr_width + 1) >> 1; break; case 1: es->env.image.remrow = (pr->pr_width + 7) >> 3; break; } } if ((obj->value.substring.length -= n) <= 0 || es->env.image.remaining <= 0) break; } object_decref(obj); if (es->env.image.remaining <= 0) { if (pr->pr_depth == 8) { register unsigned char *p = (unsigned char *) mprd->md_image; register n = pr->pr_height * mprd->md_linebytes; while (--n >= 0) { *p = grey_inverse[*p]; p++; } } else if (pr->pr_depth == 1) { register unsigned short *p = (unsigned short *) mprd->md_image; register n = (pr->pr_height * mprd->md_linebytes) / 2; unsigned char *c; while (--n >= 0) { *p = ~*p; #ifdef LITTLEENDIAN /* Note that we only need to bit swap each byte here * to achieve the goal of swapping 16 bits because the * bytes were swapped by being read as shorts. */ c = (unsigned char *)p; *c = ReverseBitsInByte[*c]; c++; *c = ReverseBitsInByte[*c]; #endif p++; } } } return es->env.image.remaining; } create_object_from_image(obj, image) register struct object *obj; register struct pixrect *image; { register struct body *b = new_body(canvas); extern struct canvas *cv_create_canvas(); register struct canvas *cv; cv = cv_create_canvas(0, image->pr_width, image->pr_height); cv->pixrect.pr_depth = image->pr_depth; cv->retained = 1; cv->retained_part.pixrect = image; b->type = canvas_type; b->body.canvas.interest = 0; b->body.canvas.canvas = (struct pixrect *) cv; cs_setcanvasspare(cv, b); set_typed_bodied_object(obj, canvas_type, b); obj->value.canvas = (struct pixrect *) cv; } initialize_image() { define_operator("imagecanvas", imagecanvas, 0, 1, 0); define_operator("imagemaskcanvas", imagemaskcanvas, 0, 2, 0); define_operator("readcanvas", readcanvas, 0, 1, 1); define_operator("writescreen", writecanvas, 0, 1, 1); define_operator("eowritescreen", writecanvas, 1, 1, 1); define_operator("writecanvas", writecanvas, 2, 1, 1); define_operator("eowritecanvas", writecanvas, 3, 1, 1); }