/* reconstruct_kids: * Recursive helper to rebuild any sub-bitmaps to point at their new * parents. */ static void reconstruct_kids(BITMAP *parent, BITMAP_INFORMATION *info) { int x, y, i; while (info) { info->bmp->vtable = parent->vtable; info->bmp->write_bank = parent->write_bank; info->bmp->read_bank = parent->read_bank; info->bmp->seg = parent->seg; info->bmp->id = parent->id | BMP_ID_SUB; x = info->bmp->x_ofs - parent->x_ofs; y = info->bmp->y_ofs - parent->y_ofs; if (is_planar_bitmap(info->bmp)) x /= 4; x *= BYTES_PER_PIXEL(bitmap_color_depth(info->bmp)); for (i=0; i<info->bmp->h; i++) info->bmp->line[i] = parent->line[y+i] + x; reconstruct_kids(info->bmp, info->child); info = info->sibling; } }
void SuperEagle(ALLEGRO_BITMAP * src, ALLEGRO_BITMAP * dest, int s_x, int s_y, int d_x, int d_y, int w, int h) { int sbpp, dbpp; ALLEGRO_BITMAP *dst2 = NULL; if (!src || !dest) return; sbpp = bitmap_color_depth(src); dbpp = bitmap_color_depth(dest); if ((sbpp != xsai_depth) || (sbpp != dbpp)) /* Must be same color depth */ return; BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, 2, 2); if (w < 4 || h < 4) { /* Image is too small to be 2xSaI'ed. */ stretch_blit(src, dest, s_x, s_y, w, h, d_x, d_y, w * 2, h * 2); return; } sbpp = BYTES_PER_PIXEL(sbpp); if (d_x || d_y) dst2 = create_sub_bitmap(dest, d_x, d_y, w * 2, h * 2); SuperEagle_ex(src->line[s_y] + s_x * sbpp, (unsigned int)(src->line[1] - src->line[0]), NULL, dst2 ? dst2 : dest, w, h); if (dst2) destroy_bitmap(dst2); return; }
/* lock_bitmap: * Locks all the memory used by a bitmap structure. */ void lock_bitmap(BITMAP *bmp) { LOCK_DATA(bmp, sizeof(BITMAP) + sizeof(char *) * bmp->h); if (bmp->dat) { LOCK_DATA(bmp->dat, bmp->w * bmp->h * BYTES_PER_PIXEL(bitmap_color_depth(bmp))); } }
/* gfx_gdi_init: */ static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_depth) { /* virtual screen are not supported */ if ((v_w!=0 && v_w!=w) || (v_h!=0 && v_h!=h)) return NULL; _enter_critical(); gfx_gdi.w = w; gfx_gdi.h = h; if (adjust_window(w, h) != 0) { _TRACE(PREFIX_E "window size not supported.\n"); ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported")); goto Error; } /* the last flag serves as an end of loop delimiter */ gdi_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char)); ASSERT(gdi_dirty_lines); memset(gdi_dirty_lines, 0, (h+1) * sizeof(char)); gdi_dirty_lines[h] = 1; /* create the screen surface */ screen_surf = _AL_MALLOC_ATOMIC(w * h * BYTES_PER_PIXEL(color_depth)); gdi_screen = _make_bitmap(w, h, (unsigned long)screen_surf, &gfx_gdi, color_depth, w * BYTES_PER_PIXEL(color_depth)); gdi_screen->write_bank = gfx_gdi_write_bank; _screen_vtable.acquire = gfx_gdi_lock; _screen_vtable.release = gfx_gdi_unlock; _screen_vtable.unwrite_bank = gfx_gdi_unwrite_bank; /* create render timer */ vsync_event = CreateEvent(NULL, FALSE, FALSE, NULL); install_int(render_proc, RENDER_DELAY); /* connect to the system driver */ win_gfx_driver = &win_gfx_driver_gdi; /* set the default switching policy */ set_display_switch_mode(SWITCH_PAUSE); /* grab input devices */ win_grab_input(); _exit_critical(); return gdi_screen; Error: _exit_critical(); gfx_gdi_exit(NULL); return NULL; }
static int _jpeg_get_hdr( wprint_image_info_t *image_info ) { struct jpeg_decompress_struct *cinfo = &(image_info->decoder_data.jpg_info.cinfo); /* initialize the JPEG decompression object and specify source file */ fseek(image_info->imgfile, 0, SEEK_SET); cinfo->err = jpeg_std_error(&image_info->decoder_data.jpg_info.jerr.pub); image_info->decoder_data.jpg_info.jerr.pub.error_exit = _jpeg_error_exit; image_info->decoder_data.jpg_info.jerr.pub.output_message = _jpeg_output_message; if (setjmp(image_info->decoder_data.jpg_info.jerr.env)) { image_info->wprint_ifc->debug(DBG_ERROR, "ERROR: invalid or corrupt JPEG"); return(ERROR); } jpeg_create_decompress(cinfo); cinfo->client_data = (void*)image_info; //cinfo->mem->max_memory_to_use = 30 * 1024 * 1024; jpeg_stdio_src(cinfo, image_info->imgfile); jpeg_read_header(cinfo, true); image_info->width = cinfo->image_width; image_info->height = cinfo->image_height; cinfo->scale_num = 1; cinfo->scale_denom = image_info->scaled_sample_size; jpeg_calc_output_dimensions(cinfo); image_info->wprint_ifc->debug(DBG_VERBOSE, "_jpeg_get_hdr(): jpeg DIM %d x %d => %d x %d, #components = %d", image_info->width, image_info->height, cinfo->output_width, cinfo->output_height, cinfo->output_components); image_info->num_components = cinfo->output_components; cinfo->out_color_space = JCS_RGB; jpeg_start_decompress(cinfo); if (cinfo->output_components == BYTES_PER_PIXEL(1)) { return(OK); } else { image_info->wprint_ifc->debug(DBG_ERROR, "ERROR: JPG format not supported. #components = %d", cinfo->output_components); return(ERROR); } } /* _jpeg_get_hdr */
/* gfx_directx_autolock: * Locks the surface and prepares the lines array of the bitmap. * This version is used directly by the bank switch functions, ie. * it handles the autolocking mode, rather than being called directly. */ void gfx_directx_autolock(BITMAP *bmp) { DDRAW_SURFACE *surf; BITMAP *parent; int pitch; unsigned char *data; int y; if (bmp->id & BMP_ID_SUB) { /* if it's a sub-bitmap, start by locking our parent */ parent = (BITMAP *)bmp->extra; gfx_directx_autolock(parent); bmp->id |= BMP_ID_LOCKED; if (parent->id & BMP_ID_AUTOLOCK) { bmp->id |= BMP_ID_AUTOLOCK; parent->id &= ~BMP_ID_AUTOLOCK; } /* update the line array if our parent has moved */ pitch = (long)parent->line[1] - (long)parent->line[0]; data = parent->line[0] + (bmp->y_ofs - parent->y_ofs) * pitch + (bmp->x_ofs - parent->x_ofs) * BYTES_PER_PIXEL(bitmap_color_depth(bmp)); if (data != bmp->line[0]) { for (y = 0; y < bmp->h; y++) { bmp->line[y] = data; data += pitch; } } } else { /* this is a real bitmap, so can be locked directly */ surf = DDRAW_SURFACE_OF(bmp); if (surf->lock_nesting) { /* re-locking after a hwaccel, so don't change nesting state */ gfx_directx_lock(bmp); surf->lock_nesting--; _exit_gfx_critical(); } else { /* locking for the first time */ gfx_directx_lock(bmp); bmp->id |= BMP_ID_AUTOLOCK; } } }
static int set_mode ( int mode, int w, int h, int depth, int scanline_size, int num_pages, int refresh_rate, int palette, int font, int flags, float aspect, int text_w, int text_h ) { const GFXDRIVER *driver = NULL; FB_GFXCTX *context; int i, j, try_count; char *c, *driver_name; unsigned char *dest; /* normalize flags */ if ((flags >= 0) && (flags & DRIVER_SHAPED_WINDOW)) flags |= DRIVER_SHAPED_WINDOW | DRIVER_NO_FRAME | DRIVER_NO_SWITCH; release_gfx_mem(); if( (mode == 0) || (w == 0) ) { memset(&__fb_ctx.hooks, 0, sizeof(__fb_ctx.hooks)); if (flags != SCREEN_EXIT) { /* set and clear text screen mode or the width and line_len will be wrong */ fb_Width( 80, 25 ); fb_Cls( 0 ); } /* reset viewport to console dimensions */ fb_ConsoleSetTopBotRows(-1, -1); } else { __fb_ctx.hooks.inkeyproc = fb_GfxInkey; __fb_ctx.hooks.getkeyproc = fb_GfxGetkey; __fb_ctx.hooks.keyhitproc = fb_GfxKeyHit; __fb_ctx.hooks.clsproc = fb_GfxClear; __fb_ctx.hooks.colorproc = fb_GfxColor; __fb_ctx.hooks.locateproc = fb_GfxLocate; __fb_ctx.hooks.widthproc = fb_GfxWidth; __fb_ctx.hooks.getxproc = fb_GfxGetX; __fb_ctx.hooks.getyproc = fb_GfxGetY; __fb_ctx.hooks.getxyproc = fb_GfxGetXY; __fb_ctx.hooks.getsizeproc = fb_GfxGetSize; __fb_ctx.hooks.printbuffproc = fb_GfxPrintBufferEx; __fb_ctx.hooks.printbuffwproc = fb_GfxPrintBufferWstrEx; __fb_ctx.hooks.readstrproc = fb_GfxReadStr; __fb_ctx.hooks.multikeyproc = fb_GfxMultikey; __fb_ctx.hooks.getmouseproc = fb_GfxGetMouse; __fb_ctx.hooks.setmouseproc = fb_GfxSetMouse; __fb_ctx.hooks.inproc = fb_GfxIn; __fb_ctx.hooks.outproc = fb_GfxOut; __fb_ctx.hooks.viewupdateproc = fb_GfxViewUpdate; __fb_ctx.hooks.lineinputproc = fb_GfxLineInput; __fb_ctx.hooks.lineinputwproc = fb_GfxLineInputWstr; __fb_ctx.hooks.readxyproc = fb_GfxReadXY; __fb_ctx.hooks.sleepproc = fb_GfxSleep; __fb_ctx.hooks.isredirproc = fb_GfxIsRedir; __fb_ctx.hooks.pagecopyproc = fb_GfxPageCopy; __fb_ctx.hooks.pagesetproc = fb_GfxPageSet; __fb_gfx = (FBGFX *)calloc(1, sizeof(FBGFX)); } if (__fb_gfx) { __fb_gfx->id = screen_id++; __fb_gfx->mode_num = mode; __fb_gfx->w = w; __fb_gfx->h = h; __fb_gfx->depth = depth; if ((flags >= 0) && (flags & DRIVER_OPENGL)) __fb_gfx->depth = MAX(16, __fb_gfx->depth); __fb_gfx->default_palette = (palette >= 0) ? &__fb_palette[palette] : NULL; __fb_gfx->scanline_size = scanline_size; __fb_gfx->font = (font >= 0) ? &__fb_font[font] : NULL; if( aspect != 0.0f ) __fb_gfx->aspect = aspect; else __fb_gfx->aspect = (4.0 / 3.0) * ((float)__fb_gfx->h / (float)__fb_gfx->w); switch (__fb_gfx->depth) { case 15: case 16: __fb_gfx->color_mask = 0xFFFF; __fb_gfx->depth = 16; break; case 24: case 32: __fb_gfx->color_mask = 0xFFFFFFFF; __fb_gfx->depth = 32; break; default: __fb_gfx->color_mask = (1 << __fb_gfx->depth) - 1; } __fb_gfx->bpp = BYTES_PER_PIXEL(__fb_gfx->depth); __fb_gfx->pitch = __fb_gfx->w * __fb_gfx->bpp; __fb_gfx->page = (unsigned char **)malloc(sizeof(unsigned char *) * num_pages); for (i = 0; i < num_pages; i++) { /* 0xF for the para alignment, p_size is sizeof(void *) rounded up to % 16 for the storage for the original pointer */ int p_size = (sizeof(void *) + 0xF) & 0xF; void *tmp = malloc((__fb_gfx->pitch * __fb_gfx->h) + p_size + 0xF); __fb_gfx->page[i] = (unsigned char *)(((intptr_t)tmp + p_size + 0xF) & ~0xF); ((void **)(__fb_gfx->page[i]))[-1] = tmp; } __fb_gfx->num_pages = num_pages; __fb_gfx->framebuffer = __fb_gfx->page[0]; /* dirty lines array may be bigger than needed; this is to please the gfx driver which is not aware of the scanline size */ __fb_gfx->dirty = (char *)calloc(1, __fb_gfx->h * __fb_gfx->scanline_size); __fb_gfx->device_palette = (unsigned int *)calloc(1, sizeof(int) * 256); __fb_gfx->palette = (unsigned int *)calloc(1, sizeof(int) * 256); __fb_gfx->color_association = (unsigned char *)malloc(16); __fb_gfx->key = (char *)calloc(1, 128); __fb_gfx->event_queue = (EVENT *)malloc(sizeof(EVENT) * MAX_EVENTS); __fb_gfx->event_mutex = fb_MutexCreate(); __fb_color_conv_16to32 = (unsigned int *)malloc(sizeof(int) * 512); if (flags != DRIVER_NULL) { if (flags & DRIVER_ALPHA_PRIMITIVES) __fb_gfx->flags |= ALPHA_PRIMITIVES; if (flags & DRIVER_OPENGL) __fb_gfx->flags |= OPENGL_SUPPORT; if (flags & DRIVER_HIGH_PRIORITY) __fb_gfx->flags |= HIGH_PRIORITY; } fb_hSetupFuncs(__fb_gfx->bpp); fb_hSetupData(); if (!__fb_window_title) { __fb_window_title = fb_hGetExeName( window_title_buff, WINDOW_TITLE_SIZE - 1 ); if ((c = strrchr(__fb_window_title, '.'))) *c = '\0'; } driver_name = __fb_gfx_driver_name; if (!driver_name) driver_name = getenv("FBGFX"); if ((flags == DRIVER_NULL) || ((driver_name) && (!strcasecmp(driver_name, "null")))) driver = &__fb_gfxDriverNull; else { for (try_count = (driver_name ? 4 : 2); try_count; try_count--) { for (i = 0; __fb_gfx_drivers_list[i >> 1]; i++) { driver = __fb_gfx_drivers_list[i >> 1]; if ((driver_name) && !(try_count & 0x1) && (strcasecmp(driver_name, driver->name))) { driver = NULL; continue; } if (!driver->init(__fb_window_title, __fb_gfx->w, __fb_gfx->h * __fb_gfx->scanline_size, __fb_gfx->depth, (i & 0x1) ? 0 : refresh_rate, flags)) break; driver->exit(); driver = NULL; } if (driver) break; if (driver_name) { if (try_count == 3) flags ^= DRIVER_FULLSCREEN; } else flags ^= DRIVER_FULLSCREEN; } } if (!driver) { exit_proc(); return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL); } __fb_gfx->driver = driver; fb_GfxPalette(-1, 0, 0, 0); __fb_gfx->text_w = text_w; __fb_gfx->text_h = text_h; context = fb_hGetContext(); fb_hResetCharCells(context, TRUE); for (i = 0; i < num_pages; i++) { dest = __fb_gfx->page[i]; for (j = 0; j < __fb_gfx->h; j++) { context->pixel_set(dest, context->bg_color, context->view_w); dest += __fb_gfx->pitch; } } if( !exit_proc_set ) { exit_proc_set = TRUE; atexit(exit_proc); } } if( flags!=SCREEN_EXIT ) { /* Reset VIEW PRINT * * Normally, resetting VIEW PRINT should also result in setting the cursor * position to Y,X = 1,1 but this doesn't seem to be suitable (at least * on Win32 platforms). I don't believe that this is a problem because * on DOS, the cursor position will automatically be reset when the screen * mode changes and not changing the console cursor position on Win32 * and Linux seem to be more "natural". */ fb_ConsoleViewEx( 0, 0, __fb_gfx!=NULL ); } return fb_ErrorSetNum( FB_RTERROR_OK ); }
/* _xdga2_gfxdrv_init_drv: * Initializes driver and creates screen bitmap. */ static BITMAP *_xdga2_private_gfxdrv_init_drv(GFX_DRIVER *drv, int w, int h, int vw, int vh, int depth, int accel) { int dga_error_base, dga_major_version, dga_minor_version; int mode, mask, red_shift = 0, green_shift = 0, blue_shift = 0; long input_mask; char tmp1[128], tmp2[128]; BITMAP *bmp; /* This is just to test if the system driver has been installed properly */ if (_xwin.window == None) return NULL; /* Test that display is local. */ if (!_xdga2_private_display_is_local()) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("This driver needs local display")); return NULL; } /* Choose convenient size. */ if ((w == 0) && (h == 0)) { w = 640; h = 480; } if ((w < 80) || (h < 80) || (w > 4096) || (h > 4096)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported screen size")); return NULL; } if (vw < w) vw = w; if (vh < h) vh = h; if (1 #ifdef ALLEGRO_COLOR8 && (depth != 8) #endif #ifdef ALLEGRO_COLOR16 && (depth != 15) && (depth != 16) #endif #ifdef ALLEGRO_COLOR24 && (depth != 24) #endif #ifdef ALLEGRO_COLOR32 && (depth != 32) #endif ) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth")); return NULL; } /* Checks presence of DGA extension */ if (!XDGAQueryExtension(_xwin.display, &dga_event_base, &dga_error_base) || !XDGAQueryVersion(_xwin.display, &dga_major_version, &dga_minor_version)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA extension is not supported")); return NULL; } /* Works only with DGA 2.0 or newer */ if (dga_major_version < 2) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA 2.0 or newer is required")); return NULL; } /* Attempts to access the framebuffer */ if (!XDGAOpenFramebuffer(_xwin.display, _xwin.screen)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open framebuffer")); return NULL; } /* Finds suitable video mode number */ mode = _xdga2_find_mode(w, h, vw, vh, depth); if (!mode) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported")); return NULL; } /* Sets DGA video mode */ dga_device = XDGASetMode(_xwin.display, _xwin.screen, mode); if (dga_device == NULL) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not switch to DGA mode")); return NULL; } _xwin.in_dga_mode = 2; _set_current_refresh_rate(dga_device->mode.verticalRefresh); set_display_switch_mode(SWITCH_NONE); /* Installs DGA color map */ if (_dga_cmap) { XFreeColormap(_xwin.display, _dga_cmap); _dga_cmap = 0; } if ((dga_device->mode.visualClass == PseudoColor) || (dga_device->mode.visualClass == GrayScale) || (dga_device->mode.visualClass == DirectColor)) _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocAll); else _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocNone); XDGAInstallColormap(_xwin.display, _xwin.screen, _dga_cmap); /* Sets up direct color shifts */ if (depth != 8) { for (mask = dga_device->mode.redMask, red_shift = 0; (mask & 1) == 0; mask >>= 1, red_shift++); for (mask = dga_device->mode.greenMask, green_shift = 0; (mask & 1) == 0; mask >>= 1, green_shift++); for (mask = dga_device->mode.blueMask, blue_shift = 0; (mask & 1) == 0; mask >>= 1, blue_shift++); } switch (depth) { case 15: _rgb_r_shift_15 = red_shift; _rgb_g_shift_15 = green_shift; _rgb_b_shift_15 = blue_shift; break; case 16: _rgb_r_shift_16 = red_shift; _rgb_g_shift_16 = green_shift; _rgb_b_shift_16 = blue_shift; break; case 24: _rgb_r_shift_24 = red_shift; _rgb_g_shift_24 = green_shift; _rgb_b_shift_24 = blue_shift; break; case 32: _rgb_r_shift_32 = red_shift; _rgb_g_shift_32 = green_shift; _rgb_b_shift_32 = blue_shift; break; } /* Enables input */ XSync(_xwin.display, True); input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; XDGASelectInput(_xwin.display, _xwin.screen, input_mask); if (_xwin_keyboard_focused) { (*_xwin_keyboard_focused)(FALSE, 0); keyboard_got_focus = TRUE; } _mouse_on = TRUE; /* Creates screen bitmap */ drv->linear = TRUE; bmp = _make_bitmap(dga_device->mode.imageWidth, dga_device->mode.imageHeight, (uintptr_t)dga_device->data, drv, depth, dga_device->mode.bytesPerScanline); if (!bmp) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); return NULL; } drv->w = bmp->cr = w; drv->h = bmp->cb = h; drv->vid_mem = dga_device->mode.imageWidth * dga_device->mode.imageHeight * BYTES_PER_PIXEL(depth); if (accel) { /* Hardware acceleration has been requested */ /* Updates line switcher to accommodate framebuffer synchronization */ #ifdef ALLEGRO_NO_ASM bmp->write_bank = _xdga2_write_line; bmp->read_bank = _xdga2_write_line; #else bmp->write_bank = _xdga2_write_line_asm; bmp->read_bank = _xdga2_write_line_asm; #endif _screen_vtable.acquire = _xdga2_acquire; /* Checks for hardware acceleration support */ if (dga_device->mode.flags & XDGASolidFillRect) { /* XDGAFillRectangle is available */ _orig_hline = _screen_vtable.hline; _orig_vline = _screen_vtable.vline; _orig_rectfill = _screen_vtable.rectfill; _screen_vtable.hline = _xaccel_hline; _screen_vtable.vline = _xaccel_vline; _screen_vtable.rectfill = _xaccel_rectfill; _screen_vtable.clear_to_color = _xaccel_clear_to_color; gfx_capabilities |= (GFX_HW_HLINE | GFX_HW_FILL); } if (dga_device->mode.flags & XDGABlitRect) { /* XDGACopyArea is available */ _screen_vtable.blit_to_self = _xaccel_blit_to_self; _screen_vtable.blit_to_self_forward = _xaccel_blit_to_self; _screen_vtable.blit_to_self_backward = _xaccel_blit_to_self; gfx_capabilities |= GFX_HW_VRAM_BLIT; } if (dga_device->mode.flags & XDGABlitTransRect) { /* XDGACopyTransparentArea is available */ _orig_draw_sprite = _screen_vtable.draw_sprite; _orig_masked_blit = _screen_vtable.masked_blit; _screen_vtable.masked_blit = _xaccel_masked_blit; _screen_vtable.draw_sprite = _xaccel_draw_sprite; if (_screen_vtable.color_depth == 8) _screen_vtable.draw_256_sprite = _xaccel_draw_sprite; gfx_capabilities |= GFX_HW_VRAM_BLIT_MASKED; } RESYNC(); } /* Checks for triple buffering */ if (dga_device->mode.viewportFlags & XDGAFlipRetrace) gfx_capabilities |= GFX_CAN_TRIPLE_BUFFER; /* Sets up driver description */ uszprintf(_xdga2_driver_desc, sizeof(_xdga2_driver_desc), uconvert_ascii("X-Windows DGA 2.0 graphics%s", tmp1), uconvert_ascii(accel ? (gfx_capabilities ? " (accelerated)" : "") : " (software only)", tmp2)); drv->desc = _xdga2_driver_desc; return bmp; }
static unsigned char* _jpeg_decode_row( wprint_image_info_t *image_info, int row ) { int i, j, rows; int start_row; int rows_cached; if ((row < 0) || (row >= image_info->sampled_height)) return(NULL); rows_cached = wprint_image_input_rows_cached(image_info); if ((image_info->swath_start == -1) || (row < image_info->swath_start) || (row >= (image_info->swath_start + rows_cached))) { start_row = ((image_info->swath_start < 0) ? 0 : (image_info->swath_start + rows_cached)); if (image_info->decoder_data.jpg_info.buff == NULL) { rows_cached = wprint_image_compute_rows_to_cache(image_info); image_info->decoder_data.jpg_info.buff = (JSAMPARRAY*)malloc(sizeof(JSAMPARRAY) * rows_cached); for(i = 0; i < rows_cached; i++) { image_info->decoder_data.jpg_info.buff[i] = NULL; image_info->decoder_data.jpg_info.buff[i] = (JSAMPARRAY) (*image_info->decoder_data.jpg_info.cinfo.mem->alloc_sarray) ( (j_common_ptr) &image_info->decoder_data.jpg_info.cinfo, JPOOL_IMAGE, BYTES_PER_PIXEL(image_info->decoder_data.jpg_info.cinfo.output_width), 1); if (image_info->decoder_data.jpg_info.buff[i] == NULL) break; } rows_cached = MIN(i, rows_cached); } else if ((image_info->swath_start != -1) && (row < image_info->swath_start)) { start_row = 0; jpeg_abort((void *) &image_info->decoder_data.jpg_info.cinfo); jpeg_destroy_decompress(&image_info->decoder_data.jpg_info.cinfo); if (_jpeg_get_hdr(image_info) == ERROR) return(NULL); for(i = 0; i < rows_cached; i++) { image_info->decoder_data.jpg_info.buff[i] = (JSAMPARRAY) (*image_info->decoder_data.jpg_info.cinfo.mem->alloc_sarray) ( (j_common_ptr) &image_info->decoder_data.jpg_info.cinfo, JPOOL_IMAGE, BYTES_PER_PIXEL(image_info->decoder_data.jpg_info.cinfo.output_width), 1); if (image_info->decoder_data.jpg_info.buff[i] == NULL) break; } rows_cached = MIN(i, rows_cached); } if (rows_cached == 0) return(NULL); if (setjmp(image_info->decoder_data.jpg_info.jerr.env)) { image_info->wprint_ifc->debug(DBG_ERROR, "ERROR: JPEG read error or corrupt file"); return(NULL); } image_info->swath_start = ((row / rows_cached) * rows_cached); for(i = start_row; i <= image_info->swath_start; i += rows_cached) { rows = MIN(rows_cached, (image_info->sampled_height - i)); for(j = 0; j < rows; j++) { jpeg_read_scanlines(&image_info->decoder_data.jpg_info.cinfo, image_info->decoder_data.jpg_info.buff[j], 1); if (image_info->decoder_data.jpg_info.jerr.pub.num_warnings != 0) { image_info->wprint_ifc->debug(DBG_ERROR, "ERROR: JPEG scanline error"); return(NULL); } } } } return((unsigned char*)image_info->decoder_data.jpg_info.buff[row - image_info->swath_start][0]); } /* _jpeg_decode_row */
int main(int argc, char **argv) { FILE *stdlog = NULL; bool borderless = false; char *input_pathname = NULL; char *output_pathname = NULL; int debug = DBG_ALL; int option; int option_index; int render_flags = 0; int printable_width = -1; int printable_height = -1; int rotation = -1; int inkjet = 1; int resolution = 300; int page_backside = 0; int stripe_height = STRIPE_HEIGHT; int concurrent_stripes = (BUFFERED_ROWS / STRIPE_HEIGHT); DF_duplex_t duplex = DF_DUPLEX_MODE_NONE; DF_media_size_t media_size = DF_MEDIA_SIZE_UNKNOWN; output_format_t output_format = OUTPUT_PPM; int testResult = ERROR; double extra_margin_left, extra_margin_right, extra_margin_top, extra_margin_bottom; int padding_options = PAD_NONE; extra_margin_left = extra_margin_right = extra_margin_top = extra_margin_bottom = 0.0f; const char *logfilename = NULL; FILE *imgfile = NULL; FILE *outputfile = NULL; bool monochrome = false; #ifndef EXCLUDE_PCLM bool pclm_test_mode = false; uint8 *pclm_output_buffer = NULL; void *pclmgen_obj= NULL; int outBuffSize = 0; PCLmPageSetup mypage; PCLmPageSetup *page_info = &mypage; memset(page_info, 0, sizeof(PCLmPageSetup)); #endif /* EXCLUDE_PCLM */ //Add pwg definitions #ifndef NO_CUPS cups_raster_t *ras_out = NULL; /* Raster stream */ cups_page_header2_t header_pwg; /* Page header */ #endif /* NO_CUPS */ while ( (option = getopt_long(argc, argv, "i:o:d:l:w:h:f:s:c:m:r:2:p:x:e:buz?v", long_options, &option_index)) != EOF ) { switch(option) { case 'i': input_pathname = optarg; break; case 'o': output_pathname = optarg; break; case 'd': debug = atoi(optarg); break; case 'l': logfilename = optarg; break; case 'b': borderless = true; break; case 'f': render_flags = atoi(optarg); break; case 'm': media_size = atoi(optarg); break; case 'w': printable_width = atoi(optarg); break; case 'h': printable_height = atoi(optarg); break; case 'r': rotation = atoi(optarg); break; case '2': duplex = atoi(optarg); break; case 'z': inkjet = 0; break; case 'x': resolution = atoi(optarg); break; case 'u': page_backside = 1; break; case 'p': output_format = atoi(optarg); break; case 's': stripe_height = atoi(optarg); break; case 'c': concurrent_stripes = atoi(optarg); break; case 'e': padding_options = atoi(optarg) & PAD_ALL; break; case OPTION_EXTRA_MARGIN_LEFT: extra_margin_left = atof(optarg); break; case OPTION_EXTRA_MARGIN_RIGHT: extra_margin_right = atof(optarg); break; case OPTION_EXTRA_MARGIN_TOP: extra_margin_top = atof(optarg); break; case OPTION_EXTRA_MARGIN_BOTTOM: extra_margin_bottom = atof(optarg); break; case OPTION_MONOCHROME: monochrome = true; break; case 'v': #ifndef EXCLUDE_PCLM pclm_test_mode = true; break; #endif /* EXCLUDE_PCLM */ case '?': default: _print_usage(argv[0]); return(0); } /* switch(option) */ } /* while */ // logging to a file? if (logfilename != NULL) { // open the logfile stdlog = fopen(logfilename, "w"); } // set the logging level and output wprint_set_debug_level(debug); wprint_set_stdlog(((stdlog != NULL) ? stdlog : stderr)); { char buffer[4096]; int param; snprintf(buffer, sizeof(buffer), "JOB PARAMETERS:"); for(param = 1; param < argc; param++) { strncat(buffer, " ", sizeof(buffer)); strncat(buffer, argv[param], sizeof(buffer)); } ifprint((DBG_FORCE, "%s", buffer)); } switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: if (!pclm_test_mode) { padding_options = PAD_ALL; } break; #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: break; #endif /* NO_CUPS */ case OUTPUT_PPM: break; default: ifprint((DBG_FORCE, "ERROR: output format not supported, switching to PPM")); output_format = OUTPUT_PPM; break; } do { /* if input file is specified at the end of the command line * without the '-f' option, take it */ if (!input_pathname && optind < argc && argv[optind] != NULL) { // coverity[var_assign_var] input_pathname = argv[optind++]; } if (!input_pathname) { ifprint((DBG_FORCE, "ERROR: invalid arguments")); _print_usage(argv[0]); continue; } /* if output file is specified at the end of the command line * without the '-f' option, take it */ if (!output_pathname && optind < argc && argv[optind] != NULL) { // coverity[var_assign_var] output_pathname = argv[optind++]; } if ((media_size != DF_MEDIA_SIZE_UNKNOWN) && (printable_width <= 0) && (printable_height <= 0)) { float margin_top, margin_bottom, margin_left, margin_right; wprint_job_params_t job_params; printer_capabilities_t printer_caps; memset(&job_params, 0, sizeof(wprint_job_params_t)); memset(&printer_caps, 0, sizeof(printer_capabilities_t)); printer_caps.canDuplex = 1; printer_caps.canPrintBorderless = 1; printer_caps.inkjet = inkjet; job_params.media_size = media_size; job_params.pixel_units = resolution; job_params.duplex = duplex, job_params.borderless = borderless; switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: job_params.pcl_type = PCLm; break; #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: job_params.pcl_type = PCLPWG; break; #endif /* NO_CUPS */ default: job_params.pcl_type = PCLNONE; break; } printable_area_get_default_margins(&job_params, &printer_caps, &margin_top, &margin_left, &margin_right, &margin_bottom); printable_area_get(&job_params, margin_top, margin_left, margin_right, margin_bottom); printable_width = job_params.printable_area_width; printable_height = job_params.printable_area_height; // mypage.mediaWidthInPixels = printable_width; //mypage.mediaHeightInPixels = printable_height; #ifndef EXCLUDE_PCLM if(margin_left < 0.0f || margin_top < 0.0f) { mypage.mediaWidthOffset=0.0f; mypage.mediaHeightOffset=0.0f; } else { mypage.mediaWidthOffset=margin_left; mypage.mediaHeightOffset=margin_top; } mypage.pageOrigin=top_left; // REVISIT mypage.dstColorSpaceSpefication=deviceRGB; #endif /* EXCLUDE_PCLM */ } #ifndef EXCLUDE_PCLM mypage.stripHeight=stripe_height; if(resolution==300) { mypage.destinationResolution=res300; } else if(resolution==600) { mypage.destinationResolution=res600; } else if(resolution==1200) { mypage.destinationResolution=res1200; } mypage.duplexDisposition=simplex; mypage.mirrorBackside=false; #endif /* EXCLUDE_PCLM */ if ((printable_width <= 0) || (printable_height <= 0)) { ifprint((DBG_FORCE, "ERROR: missing argumetns for dimensions")); _print_usage(argv[0]); continue; } imgfile = fopen(input_pathname, "r"); if (imgfile == NULL) { ifprint((DBG_FORCE, "unable to open input file")); continue; } testResult = OK; outputfile = NULL; if (output_pathname != NULL) { outputfile = fopen(output_pathname, "w"); } else { ifprint((DBG_FORCE, "output file not provided")); } wprint_image_info_t image_info; wprint_image_setup(&image_info, MIME_TYPE_HPIMAGE, &_wprint_ifc); wprint_image_init(&image_info); /* get the image_info of the input file of specified MIME type */ if ( wprint_image_get_info(imgfile, &image_info) == OK ) { if (rotation < 0) { rotation = ROT_0; if ((render_flags & RENDER_FLAG_PORTRAIT_MODE) != 0) { ifprint((DBG_LOG, "_print_page(): portrait mode")); rotation = ROT_0; } else if ((render_flags & RENDER_FLAG_LANDSCAPE_MODE) != 0) { ifprint((DBG_LOG, "_print_page(): landscape mode")); rotation = ROT_90; } else if (wprint_image_is_landscape(&image_info) && ((render_flags & RENDER_FLAG_AUTO_ROTATE) != 0)) { ifprint((DBG_LOG, "_print_page(): auto mode")); rotation = ROT_90; } if ((duplex == DF_DUPLEX_MODE_BOOK) && page_backside && ((render_flags & RENDER_FLAG_ROTATE_BACK_PAGE) != 0) && ((render_flags & RENDER_FLAG_BACK_PAGE_PREROTATED) == 0)) rotation = ((rotation == ROT_0) ? ROT_180 : ROT_270); } } else { ifprint((DBG_FORCE, "unable to process image")); } wprint_image_set_output_properties(&image_info, rotation, printable_width, printable_height, floor(resolution * extra_margin_top), floor(resolution * extra_margin_left), floor(resolution * extra_margin_right), floor(resolution * extra_margin_bottom), render_flags, stripe_height, concurrent_stripes, padding_options); int buff_size = wprint_image_get_output_buff_size(&image_info); unsigned char * buff = (unsigned char *)malloc(buff_size); memset(buff, 0xff, buff_size); int rows_left, num_rows; int output_width = wprint_image_get_width(&image_info); num_rows = rows_left = wprint_image_get_height(&image_info); int bytes_per_row = BYTES_PER_PIXEL(output_width); // process job start switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { pclmgen_obj= (void*)CreatePCLmGen(); outBuffSize = 0; PCLmStartJob(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize, pclm_test_mode); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { ras_out = cupsRasterOpen(fileno(outputfile), CUPS_RASTER_WRITE_PWG); break; } #endif /* NO_CUPS */ default: { break; } } // write start page information switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { mypage.SourceWidthPixels = output_width; mypage.SourceHeightPixels = num_rows; if (media_size != DF_MEDIA_SIZE_UNKNOWN) { _get_pclm_media_size_name(media_size, (char*)mypage.mediaSizeName); PCLmGetMediaDimensions(pclmgen_obj, mypage.mediaSizeName, &mypage ); } else { strcpy((char*)mypage.mediaSizeName, "CUSTOM"); mypage.mediaWidth = (((float)printable_width * STANDARD_SCALE_FOR_PDF)/(float)resolution); mypage.mediaHeight = (((float)printable_height * STANDARD_SCALE_FOR_PDF)/(float)resolution); mypage.mediaWidthInPixels = printable_width; mypage.mediaHeightInPixels = printable_height; } float standard_scale =(float)resolution/(float)72; page_info->sourceHeight = (float)num_rows/standard_scale; page_info->sourceWidth = (float)output_width/standard_scale; page_info->colorContent=color_content; page_info->srcColorSpaceSpefication=deviceRGB; page_info->compTypeRequested=compressDCT; outBuffSize = 0; PCLmStartPage(pclmgen_obj, page_info, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { _write_header_pwg(ras_out, resolution, image_info, &header_pwg, monochrome); /* * Output the pages... */ ifprint((DBG_LOG, "cupsWidth = %d", header_pwg.cupsWidth)); ifprint((DBG_LOG, "cupsHeight = %d", header_pwg.cupsHeight)); ifprint((DBG_LOG, "cupsBitsPerColor = %d", header_pwg.cupsBitsPerColor)); ifprint((DBG_LOG, "cupsBitsPerPixel = %d", header_pwg.cupsBitsPerPixel)); ifprint((DBG_LOG, "cupsBytesPerLine = %d", header_pwg.cupsBytesPerLine)); ifprint((DBG_LOG, "cupsColorOrder = %d", header_pwg.cupsColorOrder)); ifprint((DBG_LOG, "cupsColorSpace = %d", header_pwg.cupsColorSpace)); break; } #endif /* NO_CUPS */ default: { _write_header(outputfile, output_width, num_rows, monochrome); break; } } int height, nbytes; int image_row = 0; int actual_rows = 0; while(rows_left > 0) { height = MIN(rows_left, stripe_height); nbytes = wprint_image_decode_stripe(&image_info, image_row, &height, buff); if (nbytes > 0) { int rows_returned = (nbytes / bytes_per_row); actual_rows += rows_returned; if (height != rows_returned) { ifprint((DBG_LOG, "LOG: mismatch in reported bytes & height: %d vs %d", height, rows_returned)); } if (monochrome) { int readIndex, writeIndex; for(readIndex = writeIndex = 0; readIndex < nbytes; readIndex += BYTES_PER_PIXEL(1)) { unsigned char gray = SP_GRAY(buff[readIndex + 0], buff[readIndex + 1], buff[readIndex + 2]); buff[writeIndex++] = gray; if (output_format == OUTPUT_PDF) { buff[writeIndex++] = gray; buff[writeIndex++] = gray; } } nbytes = writeIndex; } // write the data switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize= 0; PCLmEncapsulate(pclmgen_obj, buff, bytes_per_row, rows_returned, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { if (ras_out != NULL) { cupsRasterWritePixels(ras_out, buff, nbytes); } break; } #endif /* NO_CUPS */ default: { if (outputfile != NULL) { fwrite(buff, 1, nbytes, outputfile); } } } image_row += height; rows_left -= height; } else { if (nbytes < 0) { ifprint((DBG_ERROR, "ERROR: file appears to be corrupted")); } else { ifprint((DBG_ERROR, "LOG: data end with request image_row: %d for %d rows", image_row, MIN(rows_left, stripe_height))); } break; } } if (num_rows != actual_rows) { ifprint((DBG_ERROR, "ERROR: actual image rows: %d", actual_rows)); } // end of page processing switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize = 0; PCLmEndPage(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { break; } #endif /* NO_CUPS */ default: { if (num_rows != actual_rows) { _write_header(outputfile, wprint_image_get_width(&image_info), actual_rows, monochrome); break; } break; } } // end of job processing switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize = 0; PCLmEndJob(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } PCLmFreeBuffer(pclmgen_obj, pclm_output_buffer); DestroyPCLmGen(pclmgen_obj); break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { break; } #endif /* NO_CUPS */ default: { break; } } wprint_image_cleanup(&image_info); if (buff != NULL) { free(buff); } } while(0); // close the imagefile if (imgfile != NULL) { fclose(imgfile); } // close the output file if (outputfile != NULL) { fclose(outputfile); } //if we use a res stream close it #ifndef NO_CUPS if(ras_out != NULL){ cupsRasterClose(ras_out); } #endif /* NO_CUPS */ // close the logfile if (stdlog != NULL) { fclose(stdlog); } return(testResult); } /* main */
/* create_sub_bitmap: * Creates a sub bitmap, ie. a bitmap sharing drawing memory with a * pre-existing bitmap, but possibly with different clipping settings. * Usually will be smaller, and positioned at some arbitrary point. * * Mark Wodrich is the owner of the brain responsible this hugely useful * and beautiful function. */ BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height) { BITMAP *bitmap; int nr_pointers; int i; ASSERT(parent); ASSERT((x >= 0) && (y >= 0) && (x < parent->w) && (y < parent->h)); ASSERT((width > 0) && (height > 0)); ASSERT(system_driver); if (x+width > parent->w) width = parent->w-x; if (y+height > parent->h) height = parent->h-y; if (parent->vtable->create_sub_bitmap) return parent->vtable->create_sub_bitmap(parent, x, y, width, height); if (system_driver->create_sub_bitmap) return system_driver->create_sub_bitmap(parent, x, y, width, height); /* get memory for structure and line pointers */ /* (see create_bitmap for the reason we need at least two) */ nr_pointers = MAX(2, height); bitmap = _AL_MALLOC(sizeof(BITMAP) + (sizeof(char *) * nr_pointers)); if (!bitmap) return NULL; acquire_bitmap(parent); bitmap->w = bitmap->cr = width; bitmap->h = bitmap->cb = height; bitmap->clip = TRUE; bitmap->cl = bitmap->ct = 0; bitmap->vtable = parent->vtable; bitmap->write_bank = parent->write_bank; bitmap->read_bank = parent->read_bank; bitmap->dat = NULL; bitmap->extra = NULL; bitmap->x_ofs = x + parent->x_ofs; bitmap->y_ofs = y + parent->y_ofs; bitmap->seg = parent->seg; /* All bitmaps are created with zero ID's. When a sub-bitmap is created, * a unique ID is needed to identify the relationship when blitting from * one to the other. This is obtained from the global variable * _sub_bitmap_id_count, which provides a sequence of integers (yes I * know it will wrap eventually, but not for a long time :-) If the * parent already has an ID the sub-bitmap adopts it, otherwise a new * ID is given to both the parent and the child. */ if (!(parent->id & BMP_ID_MASK)) { parent->id |= _sub_bitmap_id_count; _sub_bitmap_id_count = (_sub_bitmap_id_count+1) & BMP_ID_MASK; } bitmap->id = parent->id | BMP_ID_SUB; bitmap->id &= ~BMP_ID_LOCKED; if (is_planar_bitmap(bitmap)) x /= 4; x *= BYTES_PER_PIXEL(bitmap_color_depth(bitmap)); /* setup line pointers: each line points to a line in the parent bitmap */ for (i=0; i<height; i++) bitmap->line[i] = parent->line[y+i] + x; if (bitmap->vtable->set_clip) bitmap->vtable->set_clip(bitmap); if (parent->vtable->created_sub_bitmap) parent->vtable->created_sub_bitmap(bitmap, parent); if (system_driver->created_sub_bitmap) system_driver->created_sub_bitmap(bitmap, parent); if (parent->id & BMP_ID_VIDEO) _register_switch_bitmap(bitmap, parent); release_bitmap(parent); return bitmap; }
/* create_bitmap_ex * Creates a new memory bitmap in the specified color_depth */ BITMAP *create_bitmap_ex(int color_depth, int width, int height) { GFX_VTABLE *vtable; BITMAP *bitmap; int nr_pointers; int padding; int i; ASSERT(width >= 0); ASSERT(height > 0); ASSERT(system_driver); if (system_driver->create_bitmap) return system_driver->create_bitmap(color_depth, width, height); vtable = _get_vtable(color_depth); if (!vtable) return NULL; /* We need at least two pointers when drawing, otherwise we get crashes with * Electric Fence. We think some of the assembly code assumes a second line * pointer is always available. */ nr_pointers = MAX(2, height); bitmap = _AL_MALLOC(sizeof(BITMAP) + (sizeof(char *) * nr_pointers)); if (!bitmap) return NULL; /* This avoids a crash for assembler code accessing the last pixel, as it * read 4 bytes instead of 3. */ padding = (color_depth == 24) ? 1 : 0; bitmap->dat = _AL_MALLOC_ATOMIC(width * height * BYTES_PER_PIXEL(color_depth) + padding); if (!bitmap->dat) { _AL_FREE(bitmap); return NULL; } bitmap->w = bitmap->cr = width; bitmap->h = bitmap->cb = height; bitmap->clip = TRUE; bitmap->cl = bitmap->ct = 0; bitmap->vtable = vtable; bitmap->write_bank = bitmap->read_bank = _stub_bank_switch; bitmap->id = 0; bitmap->extra = NULL; bitmap->x_ofs = 0; bitmap->y_ofs = 0; bitmap->seg = _default_ds(); if (height > 0) { bitmap->line[0] = bitmap->dat; for (i=1; i<height; i++) bitmap->line[i] = bitmap->line[i-1] + width * BYTES_PER_PIXEL(color_depth); } if (system_driver->created_bitmap) system_driver->created_bitmap(bitmap); return bitmap; }
static int fb_hHookConWriteGfx ( FB_GFXCTX *context, int target_x, int target_y, const void *buffer, size_t length, int *dirty_start, int *dirty_end ) { const unsigned char *pachText = (const unsigned char *) buffer; /* cursor? */ if( (length == 1) && ((size_t)*pachText == 255) ) { /* note: can't use 'mask' because it will be always 0 (due the endless levels if indirection */ int x; for( x = 0; x < __fb_gfx->font->w; x++ ) { context->put_pixel( context, target_x + x, target_y + __fb_gfx->font->h - 1, context->fg_color ); } } else { int char_bit_mask; int char_row_byte_count = BYTES_PER_PIXEL(__fb_gfx->font->w); size_t i, char_size = char_row_byte_count * __fb_gfx->font->h; for( i=0; i!=length; ++i ) { size_t char_index = (size_t) *pachText++; const unsigned char *src = &__fb_gfx->font->data[char_index * char_size]; int char_y; for (char_y = 0; char_y != __fb_gfx->font->h; char_y++) { int char_x, char_row_byte; int text_y = target_y + char_y; int text_x = target_x; for( char_row_byte=0; char_row_byte!=char_row_byte_count; ++char_row_byte ) { unsigned char char_data = *src++; for (char_x = 0, char_bit_mask = 1; char_x != 8; char_x++, char_bit_mask <<= 1) { unsigned color = (char_data & char_bit_mask) ? context->fg_color : context->bg_color; context->put_pixel(context, text_x++, text_y, color); } } } target_x += __fb_gfx->font->w; } } fb_hSetDirty( dirty_start, dirty_end, target_y, target_y + __fb_gfx->font->h ); return TRUE; }
/* gfx_directx_lock: * Locks the surface and prepares the lines array of the bitmap. */ void gfx_directx_lock(BITMAP *bmp) { DDRAW_SURFACE *surf; BITMAP *parent; HRESULT hr; DDSURFACEDESC ddsurf_desc; int pitch; unsigned char *data; int y; if (bmp->id & BMP_ID_SUB) { /* if it's a sub-bitmap, start by locking our parent */ parent = (BITMAP *)bmp->extra; gfx_directx_lock(parent); bmp->id |= BMP_ID_LOCKED; /* update the line array if our parent has moved */ pitch = (long)parent->line[1] - (long)parent->line[0]; data = parent->line[0] + (bmp->y_ofs - parent->y_ofs) * pitch + (bmp->x_ofs - parent->x_ofs) * BYTES_PER_PIXEL(bitmap_color_depth(bmp)); if (data != bmp->line[0]) { for (y = 0; y < bmp->h; y++) { bmp->line[y] = data; data += pitch; } } } else { /* require exclusive ownership of the bitmap */ _enter_gfx_critical(); /* handle display switch */ if (!_win_app_foreground) gfx_directx_switch_out(); /* this is a real bitmap, so can be locked directly */ surf = DDRAW_SURFACE_OF(bmp); surf->lock_nesting++; if (!(bmp->id & BMP_ID_LOCKED)) { /* try to lock surface */ bmp->id |= BMP_ID_LOCKED; surf->flags &= ~DDRAW_SURFACE_LOST; ddsurf_desc.dwSize = sizeof(DDSURFACEDESC); ddsurf_desc.dwFlags = 0; hr = IDirectDrawSurface2_Lock(surf->id, NULL, &ddsurf_desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); /* If the surface has been lost, try to restore all surfaces * and, on success, try again to lock the surface. */ if (hr == DDERR_SURFACELOST) { if (restore_all_ddraw_surfaces() == 0) { ddsurf_desc.dwSize = sizeof(DDSURFACEDESC); ddsurf_desc.dwFlags = 0; hr = IDirectDrawSurface2_Lock(surf->id, NULL, &ddsurf_desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); } } if (FAILED(hr)) { _TRACE(PREFIX_E "Can't lock surface (%x)\n", hr); /* lock failed, use pseudo surface memory */ surf->flags |= DDRAW_SURFACE_LOST; data = pseudo_surf_mem; pitch = 0; } else { data = ddsurf_desc.lpSurface; pitch = ddsurf_desc.lPitch; } /* prepare line array */ if (data != bmp->line[0]) { for (y = 0; y < bmp->h; y++) { bmp->line[y] = data; data += pitch; } } } } }
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) { int j, v; unsigned int x, y; int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest)); unsigned long color[12]; unsigned char **src_line = new unsigned char*[4]; unsigned char **dst_line = new unsigned char*[2]; /* Point to the first 3 lines. */ src_line[0] = src; src_line[1] = src; src_line[2] = src + src_pitch; src_line[3] = src + src_pitch * 2; /* Can we write the results directly? */ if (is_video_bitmap(dest) || is_planar_bitmap(dest)) { //dst_line[0] = malloc(sizeof(char) * sbpp * width); //dst_line[1] = malloc(sizeof(char) * sbpp * width); dst_line[0] = new unsigned char[sbpp*width]; dst_line[1] = new unsigned char[sbpp*width]; v = 1; } else { dst_line[0] = dest->line[0]; dst_line[1] = dest->line[1]; v = 0; } /* Set destination */ bmp_select(dest); x = 0, y = 0; if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } for (y = 0; y < height; y++) { /* Todo: x = width - 2, x = width - 1 */ for (x = 0; x < width; x++) { unsigned long product1a, product1b, product2a, product2b; //--------------------------------------- B1 B2 0 1 // 4 5 6 S2 -> 2 3 4 5 // 1 2 3 S1 6 7 8 9 // A1 A2 10 11 if (color[7] == color[4] && color[3] != color[8]) { product1b = product2a = color[7]; if ((color[6] == color[7]) || (color[4] == color[1])) product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3])); else product1a = INTERPOLATE(color[3], color[4]); if ((color[4] == color[5]) || (color[7] == color[10])) product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8])); else product2b = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] != color[4]) { product2b = product1a = color[3]; if ((color[0] == color[3]) || (color[5] == color[9])) product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4])); else product1b = INTERPOLATE(color[3], color[1]); if ((color[8] == color[11]) || (color[2] == color[3])) product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2])); else product2a = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] == color[4]) { register int r = 0; r += GET_RESULT(color[4], color[3], color[6], color[10]); r += GET_RESULT(color[4], color[3], color[2], color[0]); r += GET_RESULT(color[4], color[3], color[11], color[9]); r += GET_RESULT(color[4], color[3], color[1], color[5]); if (r > 0) { product1b = product2a = color[7]; product1a = product2b = INTERPOLATE(color[3], color[4]); } else if (r < 0) { product2b = product1a = color[3]; product1b = product2a = INTERPOLATE(color[3], color[4]); } else { product2b = product1a = color[3]; product1b = product2a = color[7]; } } else { product2b = product1a = INTERPOLATE(color[7], color[4]); product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b); product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a); product2a = product1b = INTERPOLATE(color[3], color[8]); product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a); product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b); } if (PixelsPerMask == 2) { *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16); *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16); } else { *((unsigned long *) (&dst_line[0][x * 8])) = product1a; *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; *((unsigned long *) (&dst_line[1][x * 8])) = product2a; *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; } /* Move color matrix forward */ color[0] = color[1]; color[2] = color[3]; color[3] = color[4]; color[4] = color[5]; color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; color[10] = color[11]; if (x < width - 2) { x += 2; if (PixelsPerMask == 2) { color[1] = *(((unsigned short*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned short*)src_line[1]) + x + 1); color[9] = *(((unsigned short*)src_line[2]) + x + 1); } color[11] = *(((unsigned short*)src_line[3]) + x); } else { color[1] = *(((unsigned long*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned long*)src_line[1]) + x + 1); color[9] = *(((unsigned long*)src_line[2]) + x + 1); } color[11] = *(((unsigned long*)src_line[3]) + x); } x -= 2; } } /* We're done with one line, so we shift the source lines up */ src_line[0] = src_line[1]; src_line[1] = src_line[2]; src_line[2] = src_line[3]; /* Read next line */ if (y + 3 >= height) src_line[3] = src_line[2]; else src_line[3] = src_line[2] + src_pitch; /* Then shift the color matrix up */ if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = *(sbp + 1); sbp = (unsigned short*)src_line[1]; color[2] = *sbp; color[3] = color[2]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = *(lbp + 1); lbp = (unsigned long*)src_line[1]; color[2] = *lbp; color[3] = color[2]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } /* Write the 2 lines, if not already done so */ if (v) { unsigned long dst_addr; dst_addr = bmp_write_line(dest, y * 2); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j))); dst_addr = bmp_write_line(dest, y * 2 + 1); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j))); } else { if (y < height - 1) { dst_line[0] = dest->line[y * 2 + 2]; dst_line[1] = dest->line[y * 2 + 3]; } } } bmp_unwrite_line(dest); if (v) { delete dst_line[0]; delete dst_line[1]; } delete[] src_line; delete[] dst_line; }