/* * Set up a file stream on an OS file. The caller has allocated the * stream and buffer. */ void file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer, uint buffer_size) { switch (fmode[0]) { case 'a': sappend_file(s, file, buffer, buffer_size); break; case 'r': /* Defeat buffering for terminals. */ { struct stat rstat; fstat(fileno(file), &rstat); sread_file(s, file, buffer, (S_ISCHR(rstat.st_mode) ? 1 : buffer_size)); } break; case 'w': swrite_file(s, file, buffer, buffer_size); } if (fmode[1] == '+') s->file_modes |= s_mode_read | s_mode_write; s->save_close = s->procs.close; s->procs.close = file_close_file; }
static int stderr_open(gx_io_device * iodev, const char *access, stream ** ps, gs_memory_t * mem) { i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */ stream *s; if (!streq1(access, 'w')) return_error(e_invalidfileaccess); if (file_is_invalid(s, &ref_stderr)) { gs_memory_t *mem = imemory_system; byte *buf; s = file_alloc_stream(mem, "stderr_open(stream)"); buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)"); if (s == 0 || buf == 0) return_error(e_VMerror); swrite_file(s, gs_stderr, buf, STDERR_BUF_SIZE); s->save_close = s->procs.flush; s->procs.close = file_close_file; make_file(&ref_stderr, a_write | avm_system, s->write_id, s); *ps = s; return 1; } *ps = s; return 0; }
/* Write the file (if necessary) and page headers. */ private void ps_image_write_headers(FILE *f, gx_device_printer *pdev, const char *const setup[], gx_device_pswrite_common_t *pdpc) { if (gdev_prn_file_is_new(pdev)) { gs_rect bbox; bbox.p.x = 0; bbox.p.y = 0; bbox.q.x = pdev->width / pdev->HWResolution[0] * 72.0; bbox.q.y = pdev->height / pdev->HWResolution[1] * 72.0; psw_begin_file_header(f, (gx_device *)pdev, &bbox, pdpc, false); psw_print_lines(f, setup); psw_end_file_header(f); } { byte buf[100]; /* arbitrary */ stream s; s_init(&s, pdev->memory); swrite_file(&s, f, buf, sizeof(buf)); psw_write_page_header(&s, (gx_device *)pdev, pdpc, true, pdev->PageCount + 1, 10); sflush(&s); } }
/* Write a buffer to stdout, potentially writing to callback */ static int s_stdout_write_process(stream_state * st, stream_cursor_read * ignore_pr, stream_cursor_write * pw, bool last) { uint count = pr->limit - pr->ptr; int written; if (count == 0) return 0; written = outwrite(st->memory, pr->ptr + 1, count); if (written < count) { return ERRC; pr->ptr += written; return 0; } static int stdout_open(gx_io_device * iodev, const char *access, stream ** ps, gs_memory_t * mem) { i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */ stream *s; if (!streq1(access, 'w')) return_error(e_invalidfileaccess); if (file_is_invalid(s, &ref_stdout)) { gs_memory_t *mem = imemory_system; byte *buf; s = file_alloc_stream(mem, "stdout_open(stream)"); buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)"); if (s == 0 || buf == 0) return_error(e_VMerror); swrite_file(s, gs_stdout, buf, STDOUT_BUF_SIZE); s->save_close = s->procs.flush; s->procs.close = file_close_file; s->procs.process = s_stdout_write_process; make_file(&ref_stdout, a_write | avm_system, s->write_id, s); *ps = s; return 1; } *ps = s; return 0; }
/* Open the printer, writing the stream header. */ static int ljet5_open(gx_device * pdev) { int code = gdev_prn_open(pdev); if (code < 0) return code; code = gdev_prn_open_printer(pdev, true); if (code < 0) return code; { gx_device_printer *const ppdev = (gx_device_printer *)pdev; stream fs; stream *const s = &fs; byte buf[50]; /* arbitrary */ s_init(s, pdev->memory); swrite_file(s, ppdev->file, buf, sizeof(buf)); px_write_file_header(s, pdev); sflush(s); /* don't close */ } return 0; }
/* Switch a file stream to reading or writing. */ static int s_fileno_switch(stream * s, bool writing) { uint modes = s->file_modes; int fd = sfileno(s); long pos; if (writing) { if (!(s->file_modes & s_mode_write)) return ERRC; pos = stell(s); if_debug2('s', "[s]switch 0x%lx to write at %ld\n", (ulong) s, pos); lseek(fd, pos, SEEK_SET); /* pacify OS */ if (modes & s_mode_append) { sappend_file(s, s->file, s->cbuf, s->cbsize); /* sets position */ } else { swrite_file(s, s->file, s->cbuf, s->cbsize); s->position = pos; } s->modes = modes; } else { if (!(s->file_modes & s_mode_read)) return ERRC; pos = stell(s); if_debug2('s', "[s]switch 0x%lx to read at %ld\n", (ulong) s, pos); if (sflush(s) < 0) return ERRC; lseek(fd, 0L, SEEK_CUR); /* pacify OS */ sread_file(s, s->file, s->cbuf, s->cbsize); s->modes |= modes & s_mode_append; /* don't lose append info */ s->position = pos; } s->file_modes = modes; return 0; }
/* Send the page to the printer. For now, just send the whole image. */ static int ljet5_print_page(gx_device_printer * pdev, FILE * prn_stream) { gs_memory_t *mem = pdev->memory; uint line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); uint line_size_words = (line_size + W - 1) / W; uint out_size = line_size + (line_size / 127) + 1; word *line = (word *)gs_alloc_byte_array(mem, line_size_words, W, "ljet5(line)"); byte *out = gs_alloc_bytes(mem, out_size, "ljet5(out)"); int code = 0; int lnum; stream fs; stream *const s = &fs; byte buf[200]; /* arbitrary */ if (line == 0 || out == 0) { code = gs_note_error(gs_error_VMerror); goto done; } s_init(s, mem); swrite_file(s, prn_stream, buf, sizeof(buf)); /* Write the page header. */ { static const byte page_header[] = { pxtBeginPage, DUSP(0, 0), DA(pxaPoint), pxtSetCursor }; static const byte mono_header[] = { DUB(eGray), DA(pxaColorSpace), DUB(e8Bit), DA(pxaPaletteDepth), pxt_ubyte_array, pxt_ubyte, 2, 0xff, 0x00, DA(pxaPaletteData), pxtSetColorSpace }; static const byte gray_header[] = { DUB(eGray), DA(pxaColorSpace), pxtSetColorSpace }; px_write_page_header(s, (gx_device *)pdev); px_write_select_media(s, (gx_device *)pdev, NULL, NULL, 0, false, false); PX_PUT_LIT(s, page_header); if (pdev->color_info.depth == 1) PX_PUT_LIT(s, mono_header); else PX_PUT_LIT(s, gray_header); } /* Write the image header. */ { static const byte mono_image_header[] = { DA(pxaDestinationSize), DUB(eIndexedPixel), DA(pxaColorMapping), DUB(e1Bit), DA(pxaColorDepth), pxtBeginImage }; static const byte gray_image_header[] = { DA(pxaDestinationSize), DUB(eDirectPixel), DA(pxaColorMapping), DUB(e8Bit), DA(pxaColorDepth), pxtBeginImage }; px_put_us(s, pdev->width); px_put_a(s, pxaSourceWidth); px_put_us(s, pdev->height); px_put_a(s, pxaSourceHeight); px_put_usp(s, pdev->width, pdev->height); if (pdev->color_info.depth == 1) PX_PUT_LIT(s, mono_image_header); else PX_PUT_LIT(s, gray_image_header); } /* Write the image data, compressing each line. */ for (lnum = 0; lnum < pdev->height; ++lnum) { int ncompr; static const byte line_header[] = { DA(pxaStartLine), DUS(1), DA(pxaBlockHeight), DUB(eRLECompression), DA(pxaCompressMode), pxtReadImage }; code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) line, line_size); if (code < 0) goto fin; px_put_us(s, lnum); PX_PUT_LIT(s, line_header); ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words, out, true); px_put_data_length(s, ncompr); px_put_bytes(s, out, ncompr); } /* Finish up. */ fin: spputc(s, pxtEndImage); spputc(s, pxtEndPage); sflush(s); done: gs_free_object(mem, out, "ljet5(out)"); gs_free_object(mem, line, "ljet5(line)"); return code; }
/* Open the output file and stream. */ int gdev_vector_open_file_options(gx_device_vector * vdev, uint strmbuf_size, int open_options) { bool binary = !(open_options & VECTOR_OPEN_FILE_ASCII); int code = -1; /* (only for testing, never returned) */ cmm_dev_profile_t *icc_struct; /* Open the file as seekable or sequential, as requested. */ if (!(open_options & VECTOR_OPEN_FILE_SEQUENTIAL)) { /* Try to open as seekable. */ code = gx_device_open_output_file((gx_device *)vdev, vdev->fname, binary, true, &vdev->file); } if (code < 0 && (open_options & (VECTOR_OPEN_FILE_SEQUENTIAL | VECTOR_OPEN_FILE_SEQUENTIAL_OK))) { /* Try to open as sequential. */ code = gx_device_open_output_file((gx_device *)vdev, vdev->fname, binary, false, &vdev->file); } if ((code >= 0) && (dev_proc(vdev, get_profile) != NULL)) { code = dev_proc(vdev, get_profile)((gx_device *)vdev, &icc_struct); } if (code < 0) return code; if ((vdev->strmbuf = gs_alloc_bytes(vdev->v_memory, strmbuf_size, "vector_open(strmbuf)")) == 0 || (vdev->strm = s_alloc(vdev->v_memory, "vector_open(strm)")) == 0 || ((open_options & VECTOR_OPEN_FILE_BBOX) && (vdev->bbox_device = gs_alloc_struct_immovable(vdev->v_memory, gx_device_bbox, &st_device_bbox, "vector_open(bbox_device)")) == 0) ) { if (vdev->bbox_device) gs_free_object(vdev->v_memory, vdev->bbox_device, "vector_open(bbox_device)"); vdev->bbox_device = 0; if (vdev->strm) gs_free_object(vdev->v_memory, vdev->strm, "vector_open(strm)"); vdev->strm = 0; if (vdev->strmbuf) gs_free_object(vdev->v_memory, vdev->strmbuf, "vector_open(strmbuf)"); vdev->strmbuf = 0; gx_device_close_output_file((gx_device *)vdev, vdev->fname, vdev->file); vdev->file = 0; return_error(gs_error_VMerror); } vdev->strmbuf_size = strmbuf_size; swrite_file(vdev->strm, vdev->file, vdev->strmbuf, strmbuf_size); vdev->open_options = open_options; /* * We don't want finalization to close the file, but we do want it * to flush the stream buffer. */ vdev->strm->procs.close = vdev->strm->procs.flush; if (vdev->bbox_device) { gx_device_bbox_init(vdev->bbox_device, NULL, vdev->v_memory); rc_increment(vdev->bbox_device); vdev->bbox_device->icc_struct = icc_struct; rc_increment(vdev->bbox_device->icc_struct); gx_device_set_resolution((gx_device *) vdev->bbox_device, vdev->HWResolution[0], vdev->HWResolution[1]); /* Do the right thing about upright vs. inverted. */ /* (This is dangerous in general, since the procedure */ /* might reference non-standard elements.) */ set_dev_proc(vdev->bbox_device, get_initial_matrix, dev_proc(vdev, get_initial_matrix)); (*dev_proc(vdev->bbox_device, open_device)) ((gx_device *) vdev->bbox_device); } return 0; }
/* Send the page to the file. */ static int jbig2_print_page(gx_device_printer * pdev, FILE * prn_stream) { gx_device_jbig2 *jdev = (gx_device_jbig2 *) pdev; gs_memory_t *mem = jdev->memory; int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); byte *in = gs_alloc_bytes(mem, line_size, "jbig2_print_page(in)"); byte *fbuf = 0; uint fbuf_size; byte *jbuf = 0; uint jbuf_size; int lnum; int code = 0; stream_jbig2encode_state state; stream fstrm, cstrm; if (in == 0) { code = gs_note_error(gs_error_VMerror); goto fail; } /* Create the jbig2encode state. */ s_init_state((stream_state *)&state, &s_jbig2encode_template, 0); if (state.templat->set_defaults) (*state.templat->set_defaults) ((stream_state *) & state); state.width = jdev->width; state.height = jdev->height; /* Set up the streams. */ fbuf_size = max(512 /* arbitrary */ , state.templat->min_out_size); jbuf_size = state.templat->min_in_size; if ((fbuf = gs_alloc_bytes(mem, fbuf_size, "jbig2_print_page(fbuf)")) == 0 || (jbuf = gs_alloc_bytes(mem, jbuf_size, "jbig2_print_page(jbuf)")) == 0 ) { code = gs_note_error(gs_error_VMerror); goto done; } s_init(&fstrm, mem); swrite_file(&fstrm, prn_stream, fbuf, fbuf_size); s_init(&cstrm, mem); s_std_init(&cstrm, jbuf, jbuf_size, &s_filter_write_procs, s_mode_write); cstrm.state = (stream_state *) & state; cstrm.procs.process = state.templat->process; cstrm.strm = &fstrm; if (state.templat->init) (*state.templat->init) (cstrm.state); /* Copy the data to the output. */ for (lnum = 0; lnum < jdev->height; ++lnum) { byte *data; uint ignore_used; if (cstrm.end_status) { code = gs_note_error(gs_error_ioerror); goto done; } gdev_prn_get_bits(pdev, lnum, in, &data); sputs(&cstrm, data, state.stride, &ignore_used); } /* Wrap up. */ sclose(&cstrm); sflush(&fstrm); done: gs_free_object(mem, jbuf, "jbig2_print_page(jbuf)"); gs_free_object(mem, fbuf, "jbig2_print_page(fbuf)"); gs_free_object(mem, in, "jbig2_print_page(in)"); return code; fail: gs_free_object(mem, in, "jbig2_print_page(in)"); return code; }