void cmd_print_stats(void) { int ci, cj; dlprintf3("[l]counts: reset = %lu, found = %lu, added = %lu\n", stats_cmd.tile_reset, stats_cmd.tile_found, stats_cmd.tile_added); dlprintf5(" diff 2.5 = %lu, 3 = %lu, 4 = %lu, 2 = %lu, >4 = %lu\n", stats_cmd_diffs[0], stats_cmd_diffs[1], stats_cmd_diffs[2], stats_cmd_diffs[3], stats_cmd_diffs[4]); dlprintf2(" same_band = %lu, other_band = %lu\n", stats_cmd.same_band, stats_cmd.other_band); for (ci = 0; ci < 0x100; ci += 0x10) { const char *const *sub = cmd_sub_op_names[ci >> 4]; if (sub != 0) { dlprintf1("[l] %s =", cmd_op_names[ci >> 4]); for (cj = ci; cj < ci + 0x10; cj += 2) dprintf6("\n\t%s = %lu(%lu), %s = %lu(%lu)", sub[cj - ci], stats_cmd.op_counts[cj], stats_cmd.op_sizes[cj], sub[cj - ci + 1], stats_cmd.op_counts[cj + 1], stats_cmd.op_sizes[cj + 1]); } else {
int gs_image_next_planes(gs_image_enum * penum, gs_const_string *plane_data /*[num_planes]*/, uint *used /*[num_planes]*/) { const int num_planes = penum->num_planes; int i; int code = 0; #ifdef DEBUG vd_get_dc('i'); vd_set_shift(0, 0); vd_set_scale(0.01); vd_set_origin(0, 0); if (gs_debug_c('b')) { int pi; for (pi = 0; pi < num_planes; ++pi) dprintf6("[b]plane %d source=0x%lx,%u pos=%u data=0x%lx,%u\n", pi, (ulong)penum->planes[pi].source.data, penum->planes[pi].source.size, penum->planes[pi].pos, (ulong)plane_data[pi].data, plane_data[pi].size); } #endif for (i = 0; i < num_planes; ++i) { used[i] = 0; if (penum->wanted[i] && plane_data[i].size != 0) { penum->planes[i].source.size = plane_data[i].size; penum->planes[i].source.data = plane_data[i].data; } } for (;;) { /* If wanted can vary, only transfer 1 row at a time. */ int h = (penum->wanted_varies ? 1 : max_int); /* Move partial rows from source[] to row[]. */ for (i = 0; i < num_planes; ++i) { int pos, size; uint raster; if (!penum->wanted[i]) continue; /* skip unwanted planes */ pos = penum->planes[i].pos; size = penum->planes[i].source.size; raster = penum->image_planes[i].raster; if (size > 0) { if (pos < raster && (pos != 0 || size < raster)) { /* Buffer a partial row. */ int copy = min(size, raster - pos); uint old_size = penum->planes[i].row.size; /* Make sure the row buffer is fully allocated. */ if (raster > old_size) { gs_memory_t *mem = gs_image_row_memory(penum); byte *old_data = penum->planes[i].row.data; byte *row = (old_data == 0 ? gs_alloc_string(mem, raster, "gs_image_next(row)") : gs_resize_string(mem, old_data, old_size, raster, "gs_image_next(row)")); if_debug5('b', "[b]plane %d row (0x%lx,%u) => (0x%lx,%u)\n", i, (ulong)old_data, old_size, (ulong)row, raster); if (row == 0) { code = gs_note_error(gs_error_VMerror); free_row_buffers(penum, i, "gs_image_next(row)"); break; } penum->planes[i].row.data = row; penum->planes[i].row.size = raster; } memcpy(penum->planes[i].row.data + pos, penum->planes[i].source.data, copy); penum->planes[i].source.data += copy; penum->planes[i].source.size = size -= copy; penum->planes[i].pos = pos += copy; used[i] += copy; } } if (h == 0) continue; /* can't transfer any data this cycle */ if (pos == raster) { /* * This plane will be transferred from the row buffer, * so we can only transfer one row. */ h = min(h, 1); penum->image_planes[i].data = penum->planes[i].row.data; } else if (pos == 0 && size >= raster) { /* We can transfer 1 or more planes from the source. */ h = min(h, size / raster); penum->image_planes[i].data = penum->planes[i].source.data; } else h = 0; /* not enough data in this plane */ } if (h == 0 || code != 0) break; /* Pass rows to the device. */ if (penum->dev == 0) { /* * ****** NOTE: THE FOLLOWING IS NOT CORRECT FOR ImageType 3 * ****** InterleaveType 2, SINCE MASK HEIGHT AND IMAGE HEIGHT * ****** MAY DIFFER (BY AN INTEGER FACTOR). ALSO, plane_depths[0] * ****** AND plane_widths[0] ARE NOT UPDATED. */ if (penum->y + h < penum->height) code = 0; else h = penum->height - penum->y, code = 1; } else { code = gx_image_plane_data_rows(penum->info, penum->image_planes, h, &h); if_debug2('b', "[b]used %d, code=%d\n", h, code); penum->error = code < 0; } penum->y += h; /* Update positions and sizes. */ if (h == 0) break; for (i = 0; i < num_planes; ++i) { int count; if (!penum->wanted[i]) continue; count = penum->image_planes[i].raster * h; if (penum->planes[i].pos) { /* We transferred the row from the row buffer. */ penum->planes[i].pos = 0; } else { /* We transferred the row(s) from the source. */ penum->planes[i].source.data += count; penum->planes[i].source.size -= count; used[i] += count; } } cache_planes(penum); if (code > 0) break; } /* Return the retained data pointers. */ for (i = 0; i < num_planes; ++i) plane_data[i] = penum->planes[i].source; vd_release_dc; return code; }
/* Default implementation of tile_rectangle */ int gx_default_tile_rectangle(gx_device *dev, register const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int px, int py) { /* Fill the rectangle in chunks */ int width = tile->size.x; int height = tile->size.y; int raster = tile->raster; int rwidth = tile->rep_width; int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */ (x + px) & (rwidth - 1) : (x + px) % rwidth); int ry = (y + py) % tile->rep_height; int icw = width - irx; int ch = height - ry; byte *row = tile->data + ry * raster; #define d_proc_mono (dev->procs->copy_mono) dev_proc_copy_mono((*proc_mono)); #define d_proc_color (dev->procs->copy_color) dev_proc_copy_color((*proc_color)); #define d_color_halftone\ (color0 == gx_no_color_index && color1 == gx_no_color_index) int color_halftone; #define get_color_info()\ if ( (color_halftone = d_color_halftone) ) proc_color = d_proc_color;\ else proc_mono = d_proc_mono int code; #ifdef DEBUG if ( gs_debug['t'] ) { int ptx, pty; const byte *ptp = tile->data; dprintf3("[t]tile %dx%d raster=%d;", tile->size.x, tile->size.y, tile->raster); dprintf6(" x,y=%d,%d w,h=%d,%d p=%d,%d\n", x, y, w, h, px, py); for ( pty = 0; pty < tile->size.y; pty++ ) { dprintf(" "); for ( ptx = 0; ptx < tile->raster; ptx++ ) dprintf1("%3x", *ptp++); } dputc('\n'); } #endif #define real_copy_tile(srcx, tx, ty, tw, th)\ code =\ (color_halftone ?\ (*proc_color)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th) :\ (*proc_mono)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th, color0, color1));\ gp_check_interrupts();\ if ( code < 0 ) return_error(code) #ifdef DEBUG #define copy_tile(sx, tx, ty, tw, th)\ if ( gs_debug['t'] )\ dprintf5(" copy sx=%d x=%d y=%d w=%d h=%d\n",\ sx, tx, ty, tw, th);\ real_copy_tile(sx, tx, ty, tw, th) #else #define copy_tile(sx, tx, ty, tw, th)\ real_copy_tile(sx, tx, ty, tw, th) #endif if ( icw >= w ) { /* Narrow operation */ int ey, fey, cy; if ( ch >= h ) { /* Just one (partial) tile to transfer. */ #define color_halftone d_color_halftone #define proc_color d_proc_color #define proc_mono d_proc_mono copy_tile(irx, x, y, w, h); #undef proc_mono #undef proc_color #undef color_halftone return 0; } get_color_info(); ey = y + h; fey = ey - height; copy_tile(irx, x, y, w, ch); cy = y + ch; row = tile->data; do { ch = (cy > fey ? ey - cy : height); copy_tile(irx, x, cy, w, ch); } while ( (cy += ch) < ey ); return 0; } get_color_info(); if ( ch >= h ) { /* Shallow operation */ int ex = x + w; int fex = ex - width; int cx = x + icw; copy_tile(irx, x, y, icw, h); while ( cx <= fex ) { copy_tile(0, cx, y, width, h); cx += width; } if ( cx < ex ) { copy_tile(0, cx, y, ex - cx, h); } } else { /* Full operation */ int ex = x + w, ey = y + h; int fex = ex - width, fey = ey - height; int cx, cy; for ( cy = y; ; ) { copy_tile(irx, x, cy, icw, ch); cx = x + icw; while ( cx <= fex ) { copy_tile(0, cx, cy, width, ch); cx += width; } if ( cx < ex ) { copy_tile(0, cx, cy, ex - cx, ch); } if ( (cy += ch) >= ey ) break; ch = (cy > fey ? ey - cy : height); row = tile->data; } } #undef copy_tile #undef real_copy_tile return 0; }
/* makefont */ int gs_makefont(gs_font_dir *pdir, const gs_font *pfont, const gs_matrix *pmat, gs_font **ppfont, gs_font **pdfont) { int code; gs_font *prev = 0, *pf_out = pdir->scaled_fonts; gs_matrix newmat; *pdfont = 0; gs_make_identity(&newmat); /* fill in tags */ if ( (code = gs_matrix_multiply(&pfont->FontMatrix, pmat, &newmat)) < 0 ) return code; /* Check for the font already being in the scaled font cache. */ /* Only attempt to share fonts if the current font has */ /* a real UniqueID (i.e., not -1). */ #ifdef DEBUG if ( gs_debug['m'] ) { dprintf2("[m]UniqueID=%ld, FontType=%d,\n", pfont->data.base.UniqueID, pfont->FontType); dprintf6("[m] new FontMatrix=[%g %g %g %g %g %g]\n", pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty); } #endif if ( pfont->data.base.UniqueID != -1 ) for ( ; pf_out != 0; prev = pf_out, pf_out = pf_out->next ) if ( pf_out->data.base.UniqueID == pfont->data.base.UniqueID && pf_out->FontType == pfont->FontType && pf_out->FontMatrix.xx == newmat.xx && pf_out->FontMatrix.xy == newmat.xy && pf_out->FontMatrix.yx == newmat.yx && pf_out->FontMatrix.yy == newmat.yy && pf_out->FontMatrix.tx == newmat.tx && pf_out->FontMatrix.ty == newmat.ty ) { *ppfont = pf_out; if_debug1('m', "[m]found font=%lx\n", (ulong)pf_out); return 0; } pf_out = (gs_font *)(*pdir->alloc)(1, sizeof(gs_font), "gs_makefont"); if ( !pf_out ) return_error(gs_error_VMerror); *pf_out = *pfont; pf_out->FontMatrix = newmat; if ( pdir->ssize == pdir->smax ) { /* Must discard a cached scaled font. */ /* Scan for the oldest font if we didn't already. */ if ( !prev ) for ( prev = pdir->scaled_fonts; prev->next != 0; prev = prev->next ) ; if_debug1('m', "[m]discarding font %lx\n", (ulong)prev); *pdfont = prev; prev->prev->next = 0; } else pdir->ssize++; link_first(pdir->scaled_fonts, pf_out); pf_out->base = pfont->base; pf_out->dir = pdir; *ppfont = pf_out; if_debug1('m', "[m]new font=%lx\n", (ulong)pf_out); return 1; }