void BitmapUtilsT<PFsrc,PFdst>::Blit2x(uint8_t* dst_pixels, const uint8_t* src_pixels, int n) { for (int i = 0; i < n; i++) { copy_pixel(dst_pixels, src_pixels); dst_pixels += pf_dst.bytes; copy_pixel(dst_pixels, src_pixels); dst_pixels += pf_dst.bytes; src_pixels += pf_src.bytes; } }
void BitmapUtilsT<PFsrc,PFdst>::FlipH(uint8_t*& pixels_left, uint8_t*& pixels_right, int n) { for (int i = 0; i < n; i++) { if (pixels_left == pixels_right) continue; uint8_t tmp_buffer[4]; copy_pixel(tmp_buffer, pixels_left); copy_pixel(pixels_left, pixels_right); copy_pixel(pixels_right, tmp_buffer); pixels_left += pf_dst.bytes; pixels_right -= pf_dst.bytes; } }
void BitmapUtilsT<PFsrc,PFdst>::FlipHV(uint8_t*& pixels_first, uint8_t*& pixels_last, int n) { for (int i = 0; i < n; i++) { if (pixels_first == pixels_last) break; uint8_t tmp_buffer[4]; copy_pixel(tmp_buffer, pixels_first); copy_pixel(pixels_first, pixels_last); copy_pixel(pixels_last, tmp_buffer); pixels_first += pf_dst.bytes; pixels_last -= pf_dst.bytes; } }
static inline void copy_pixels(BMU* bmu, uint8_t* dst_pixels, const uint8_t* src_pixels, int n) { for (int i = 0; i < n; i++) { copy_pixel(bmu, dst_pixels, src_pixels); src_pixels += bmu->pf_src.bytes; dst_pixels += bmu->pf_dst.bytes; } }
void BitmapUtilsT<PFsrc,PFdst>::FlipHBlit(uint8* dst_pixels, const uint8* src_pixels, int n) { for (int i = 0; i < n; i++) { copy_pixel(dst_pixels, src_pixels); src_pixels -= pf_src.bytes; dst_pixels += pf_dst.bytes; } }
void BitmapUtilsT<PFsrc,PFdst>::CopyScaleBlit(uint8_t* dst_pixels, const uint8_t* src_pixels, int n, int x, int step) { for (int i = 0; i < n; i++) { const uint8_t* p = src_pixels + (x >> FRAC_BITS) * pf_src.bytes; copy_pixel(dst_pixels, p); dst_pixels += pf_dst.bytes; x += step; } }
void BitmapUtilsT<PFsrc,PFdst>::CopyTransformBlit(uint8_t* dst_pixels, const uint8_t* src_pixels, int src_pitch, int x0, int x1, int y, const Rect& src_rect, const Matrix& inv) { const int sx0 = src_rect.x; const int sy0 = src_rect.y; const int sx1 = src_rect.x + src_rect.width; const int sy1 = src_rect.y + src_rect.height; for (int x = x0; x < x1; x++) { double fx, fy; inv.Transform(x + 0.5, y + 0.5, fx, fy); int xi = (int) floor(fx); int yi = (int) floor(fy); if (xi < sx0 || xi >= sx1 || yi < sy0 || yi >= sy1) ; else copy_pixel(dst_pixels, &src_pixels[yi * src_pitch + xi * pf_src.bytes]); dst_pixels += pf_dst.bytes; } }
SDL_Surface* rotozoom(SDL_Surface *old, SDL_Rect *clip, Uint16 newW, Uint16 newH, char rotation) { #ifndef USE_GFX /* Doesn't work #ifdef PSP if(*access_int_global(access_resize) == resize_hardware) { SDL_Rect temp; if(clip == NULL) { temp.x = 0; temp.y = 0; temp.w = old->w; temp.h = old->h; clip = &temp; } float x_ratio; float y_ratio; if(newW == 0) { if(newH == 0) { if((rotation % 4) == 0) return old; x_ratio = 1.0f; y_ratio = 1.0f; } else { x_ratio = y_ratio = ((float)newH)/old->h; newW = old->w * x_ratio; } } else if(newH == 0) { x_ratio = y_ratio = ((float)newW)/old->w; newH = old->h * y_ratio; } else if((newW == old->w) && (newH == old->h) && ((rotation % 4) == 0)) return old; else { x_ratio = ((float)newW)/old->w; y_ratio = ((float)newH)/old->h; } device scr_acc = access_device(access_screen); SDL_Surface *ret = SDL_CreateRGBSurface( SDL_SWSURFACE, newW, newH, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); if(!ret) return NULL; SDL_Surface *hw_buf = SDL_CreateRGBSurface( SDL_HWSURFACE, 256, 256, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); SDL_Surface *hw_draw_buf = SDL_CreateRGBSurface( SDL_HWSURFACE, 256, 256, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); if(!hw_buf || !hw_draw_buf) { if(hw_buf) SDL_FreeSurface(hw_buf); else SDL_FreeSurface(hw_draw_buf); SDL_FreeSurface(ret); return NULL; } void *display_list = memalign(16,262144); if(!display_list) { //TODO } void *draw_buf = (void*)((int)scr_acc.screen->pixels-0x4000000); sceKernelDcacheWritebackInvalidateAll(); sceGuStart(GU_DIRECT,display_list); sceGuEnable(GU_TEXTURE_2D); //sceGuDrawBuffer(GU_PSM_8888,(void*)((int)hw_buf->pixels-0x4000000),256); sceGumMatrixMode(GU_PROJECTION); sceGumLoadIdentity(); sceGumOrtho(0.0f,256.0f,256.0f,0.0f,-1.0f,1.0f); sceGumMatrixMode(GU_VIEW); sceGumLoadIdentity(); sceGumMatrixMode(GU_MODEL); sceGumLoadIdentity(); sceGuTexMode(GU_PSM_8888, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_DECAL, GU_TCC_RGB); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuTexWrap(GU_CLAMP,GU_CLAMP); sceGuTexScale(x_ratio, y_ratio); sceGuTexOffset(0.0f, 0.0f); sceGuTexImage(0,256,256,512,hw_buf->pixels); sceGuFinish(); sceGuSync(0,0); int i; for(i = 0; i < clip->h; i+=256) { int j; for(j = 0; j < clip->w; j+=256) { SDL_Rect region = { .x = clip->x + j, .y = clip->y + i, .w = 256, .h = 256 }; SDL_BlitSurface(old,NULL,hw_buf,NULL); SDL_LockSurface(hw_buf); SDL_LockSurface(scr_acc.screen); sceKernelDcacheWritebackInvalidateAll(); sceGuStart(GU_DIRECT,display_list); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); sceGumDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,NULL,rot0); sceGuFinish(); sceGuSync(0,0); region.x = j*x_ratio; region.y = i*y_ratio; region.w *= x_ratio; region.h *= y_ratio; SDL_UnlockSurface(hw_buf); SDL_UnlockSurface(scr_acc.screen); SDL_BlitSurface(scr_acc.screen,NULL,ret,NULL); flip_screen(); } } //sceGuDrawBuffer(GU_PSM_8888,draw_buf,512); SDL_FreeSurface(hw_buf); SDL_FreeSurface(hw_draw_buf); free(display_list); return ret; } #endif */ SDL_Rect src_rect; if(clip == NULL) { src_rect.x = 0; src_rect.y = 0; src_rect.w = old->w; src_rect.h = old->h; } else src_rect = *clip; if((newW == 0) && (newH != 0)) newW = (Uint16)(((float)newH/src_rect.h)*old->w); else if((newH == 0) && (newW != 0)) newH = (Uint16)(((float)newW/src_rect.w)*old->h); else if((newW == 0) && (newH == 0)) { newW = old->w; newH = old->h; } if((clip == NULL) && (newW == old->w) && (newH == old->h) && ((rotation % 4) == 0)) return old; int current_resize_method = *access_int_global(access_resize); scale_up_cpu(); if((newW/old->w >= 2) && (newH/old->h >= 2)) current_resize_method = resize_nn; SDL_Surface *new_surf = SDL_CreateRGBSurface( SDL_SWSURFACE, (rotation % 2)?newH:newW, (rotation % 2)?newW:newH, ((current_resize_method == resize_nn) || (old->format->BytesPerPixel >= 3)) ? old->format->BitsPerPixel : ((old->format->BytesPerPixel == 1) && (old->flags & SDL_SRCCOLORKEY) && (current_resize_method == resample))? 32 : 24, (old->format->BytesPerPixel == 1)?0x00FF0000:old->format->Rmask, (old->format->BytesPerPixel == 1)?0x0000FF00:old->format->Gmask, (old->format->BytesPerPixel == 1)?0x000000FF:old->format->Bmask, (((old->format->BytesPerPixel == 1) && (old->flags & SDL_SRCCOLORKEY) && (current_resize_method == resample)) || (old->format->BytesPerPixel == 4))?0xFF000000:0 //Not sure why it has to be done this way, but it does... ); if(!new_surf) { scale_down_cpu(); sdl_error(); return NULL; } if((new_surf->format->BytesPerPixel == 1) && !(copy_palette(old, new_surf) == 1)) { SDL_FreeSurface(new_surf); scale_down_cpu(); sdl_error(); return NULL; } /* if(new_surf->format->BytesPerPixel == 4) SDL_SetAlpha(new_surf,SDL_SRCALPHA,SDL_ALPHA_TRANSPARENT); */ SDL_LockSurface(old); SDL_LockSurface(new_surf); Uint32 i, j; Uint8 *new_pixel, *row_start; Uint32 new_pitch = new_surf->pitch; Uint8 bpp = new_surf->format->BytesPerPixel; Uint32 new_to_next_row = new_pitch-bpp*(newW - 1); Uint32 new_to_prev_column = new_pitch*newH - bpp; int oldW = old->w; int oldH = old->h; Uint32 old_pitch = new_surf->pitch; Uint32 old_to_next_row = old_pitch-old->format->BytesPerPixel*(old->w - 1); Uint32 old_to_next_column = -old_pitch*oldH + old->format->BytesPerPixel; Uint32 old_bpp = old->format->BytesPerPixel; if(rotation % 2) { newW = new_surf->w; newH = new_surf->h; } char amount = rotation % 4; if((newW == oldW) && (newH == oldH)) { //Old dims == new dims. Just rotate. Uint8 *old_pixel = old->pixels; switch(amount) { case 1: new_pixel = access_pixel(new_surf,i,newH); for(j = newH; j--;) { for(i = newW; i--;) { copy_pixel(old_pixel,new_pixel,bpp); old_pixel = (Uint8*)old_pixel - old_pitch; new_pixel = (Uint8*)new_pixel - bpp; } old_pixel = (Uint8*)old_pixel + old_bpp; new_pixel = (Uint8*)new_pixel - new_to_next_row; } break; case 2: new_pixel = access_pixel(new_surf,newW-1,newH-1); for(i = newW; i--;) { for(j = newH; j--;) { copy_pixel(old_pixel,new_pixel,bpp); old_pixel = (Uint8*)old_pixel + old_pitch; new_pixel = (Uint8*)new_pixel - new_pitch; } new_pixel = (Uint8*)new_pixel + new_to_prev_column; old_pixel = (Uint8*)old_pixel + old_to_next_column; } break; case 3: new_pixel = new_surf->pixels; for(i = newW; i--;) { for(j = newH; j--;) { copy_pixel(old_pixel,new_pixel,bpp); old_pixel = (Uint8*)old_pixel + bpp; new_pixel = (Uint8*)new_pixel - new_pitch; } old_pixel = (Uint8*)old_pixel + old_to_next_row; new_pixel = (Uint8*)new_pixel + new_to_next_row; } break; } } else { switch(current_resize_method) { case resize_nn: { Uint32 locationX, locationY; Uint8 *old_pixel; new_pixel = new_surf->pixels; for(i = newH; i--;) { row_start = new_pixel; for(j = 0; j < newW; ++j,new_pixel+=bpp) { switch(amount) { case 0: locationX = (j<<16)/newW*(src_rect.w-1) + (src_rect.x<<16); locationY = (src_rect.h<<16) - ((i<<16)/newH*(src_rect.h-1) + (src_rect.y<<16)) - 1; break; case 1: locationX = (src_rect.w<<16) - ((i<<16)/newH*(src_rect.w-1) + (src_rect.x<<16)) - 1; locationY = (src_rect.h<<16) - ((j<<16)/newW*(src_rect.h-1) + (src_rect.y<<16)) - 1; break; case 2: locationX = (src_rect.w<<16) - ((j<<16)/newW*(src_rect.w-1) + (src_rect.x<<16)) - 1; locationY = ((i<<16)/newH*(src_rect.h-1) + (src_rect.y<<16)); break; case 3: locationX = (i<<16)/newH*(src_rect.w-1) + (src_rect.x<<16); locationY = (j<<16)/newW*(src_rect.h-1) + (src_rect.y<<16); break; } old_pixel = access_pixel(old,(Uint16)(locationX>>16),(Uint16)(locationY>>16)); copy_pixel(old_pixel,new_pixel,bpp); } new_pixel = row_start + new_pitch; } } break; case resample: { Uint32 locationX, locationY; Uint16 cornerX0, cornerX1, cornerY0, cornerY1; Uint8 *old_pixel0, *old_pixel1; SDL_Surface *buffer = NULL; if(old->format->BytesPerPixel < 3) { buffer = old; old = SDL_CreateRGBSurface( SDL_SWSURFACE, buffer->w, buffer->h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 ); SDL_SetAlpha(old,SDL_SRCALPHA,SDL_ALPHA_TRANSPARENT); SDL_UnlockSurface(buffer); SDL_BlitSurface(buffer,NULL,old,NULL); SDL_UpdateRect(old,0,0,0,0); SDL_LockSurface(old); } Uint8 k = new_surf->format->BytesPerPixel; Uint16 val; new_pixel = access_pixel(new_surf,newW-1,newH-1); for(i = newH; i--;) { row_start = new_pixel; for(j = newW; j--; new_pixel -= k*2-1) { switch(amount) { case 0: locationX = (j<<16)/newW*(src_rect.w-1) + (src_rect.x<<16); locationY = (i<<16)/newH*(src_rect.h-1) + (src_rect.y<<16); break; case 1: locationX = (i<<16)/newH*(src_rect.w-1) + (src_rect.x<<16); locationY = (src_rect.h<<16) - ((j<<16)/newW*(src_rect.h-1) + (src_rect.y<<16)) - 1; break; case 2: locationX = (src_rect.w<<16) - ((j<<16)/newW*(src_rect.w-1) + (src_rect.x<<16)) - 1; locationY = (src_rect.h<<16) - ((i<<16)/newH*(src_rect.h-1) + (src_rect.y<<16)) - 1; break; case 3: locationX = (src_rect.w<<16) - ((i<<16)/newH*(src_rect.w-1) + (src_rect.x<<16)) - 1; locationY = (j<<16)/newW*(src_rect.h-1) + (src_rect.y<<16); break; } cornerX0 = (Uint16)(locationX>>16); cornerY0 = (Uint16)(locationY>>16); cornerX1 = cornerX0; cornerY1 = cornerY0; if(amount > 1) { if(locationX-(cornerX0<<16)) --cornerX1; } else { if(cornerX0+1<oldW) ++cornerX1; } if((amount < 3) && (amount > 0)) { if(locationY-(cornerY0<<16)) --cornerY1; } else { if(cornerY0+1<oldH) ++cornerY1; } old_pixel0 = access_pixel(old,cornerX0,cornerY0); old_pixel1 = access_pixel(old,cornerX1,cornerY1); //Basically, this averages two pixels' values and puts it //into the new image. val = ((Uint16)(*(old_pixel0))+ (Uint16)(*(old_pixel1)))>>1; *((Uint8*)new_pixel) = (Uint8)val; //Do it up to four times, and also pre-increment the //variables so that the pointer is right immediately val = ((Uint16)(*(++old_pixel0))+ (Uint16)(*(++old_pixel1)))>>1; *((Uint8*)++new_pixel) = (Uint8)val; val = ((Uint16)(*(++old_pixel0))+ (Uint16)(*(++old_pixel1)))>>1; *((Uint8*)++new_pixel) = (Uint8)val; if(k == 4) { val = ((Uint16)(*(++old_pixel0))+ (Uint16)(*(++old_pixel1)))>>1; *((Uint8*)++new_pixel) = (Uint8)val; } } new_pixel = row_start - new_pitch; } if(buffer) { SDL_FreeSurface(old); old = NULL; } } break; } }
static void load_atlas_texture(fs_image *atlas_image, int texture_id, const char *name) { char *path = fs_emu_theme_get_resource(name); if (!path) { fs_emu_warning("Could not find resource %s\n", name); return; } fs_image *image = fs_image_new_from_file(path); if (!image) { fs_emu_warning("error loading texture \"%s\"\n", name); return; } fs_emu_log("loaded sub-texture from \"%s\"\n", path); // find needed number of cells int cw = (image->width + 7) / 8; int ch = (image->height + 7) / 8; // adding 1 to get some spacing between cells if (cw < 128) { cw++; } if (ch < 128) { ch++; } // try to find space for it in the texture atlas using a simple // brute-force search int cx = 0; int cy = 0; int ok = 0; for (cy = 0; cy <= 128 - ch; cy++) { for (cx = 0; cx <= 128 - cw; cx++) { if (check_placement(cx, cy, cw, ch)) { ok = 1; break; } } if (ok) { break; } } if (!ok) { fs_emu_warning("could not find space for \"%s\"\n", name); //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8); return; } // mark cells as used for (int y = cy; y < cy + ch; y++) { for (int x = cx; x < cx + cw; x++) { g_cells[y][x] = 1; } } //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8); // copy sub-texture into texture, also converting to pre-multiplied // alpha, and BGRA if needed. Also copy border pixels to pixels outside // border to fix unwanted bilinear filtering effects int dx = cx * 8; int dy = cy * 8; int ds = atlas_image->width * 4; // stride unsigned char *dst = atlas_image->data + \ (dy * atlas_image->width + dx) * 4; unsigned char *sp = image->data; for (int y = 0; y < image->height; y++) { #if 1 if (y == 0 && dy > 0) { // repeat first line unsigned char *dp = dst - ds; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } sp -= image->width * 4; } #endif unsigned char *dp = dst; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } dst += 1024 * 4; // stride #if 1 if (y == image->height - 1 && dy + y - 1 < atlas_image->height - 1) { // repeat last line sp -= image->width * 4; unsigned char *dp = dst; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } } #endif } // repeat left and right borders uint32_t *idata = (uint32_t *) atlas_image->data; int iwidth = atlas_image->width; int y1 = dy; int y2 = dy + image->height - 1; if (y1 > 0) { y1 -= 1; } if (y2 < atlas_image->height - 1) { y2 += 1; } if (dx > 0) { for (int y = y1; y <= y2; y++) { idata[y * iwidth + dx - 1] = idata[y * iwidth + dx]; } } if (dx + image->width - 1 < atlas_image->width - 1) { for (int y = y1; y <= y2; y++) { idata[y * iwidth + dx + image->width - 1 + 1] = \ idata[y * iwidth + dx + image->width - 1]; } } // register texture coordinates g_entries[texture_id].x = cx * 8; g_entries[texture_id].y = cy * 8; g_entries[texture_id].w = image->width; g_entries[texture_id].h = image->height; // and finally free the sub-texture image fs_unref(image); }
void BitmapUtilsT<PFsrc,PFdst>::SetPixels(uint8_t* dst_pixels, const uint8_t* src_pixel, int n) { uint8_t tmp_pixel[4]; copy_pixel(tmp_pixel, src_pixel); pf_dst.set_pixels(dst_pixels, tmp_pixel, n); }
/* TODO: consider using source.position and source.count (and possibly also phase) */ static int read_mode10_bitmap_data(byte ** pdata, px_args_t * par, px_state_t * pxs, bool mode9031) { px_vendor_state_t *v_state = pxs->vendor_state; mode10_state_t *mode10_state = &v_state->mode10_state; uint avail = min(par->source.available, (v_state->tag.bytes_expected - v_state->tag.bytes_so_far)); const byte *pin = par->source.data; byte *pout; bool end_of_row = false; uint32_t pixel; int i; update_pout(pout); if ((v_state->state == vu_body) && v_state->rowwritten == v_state->BlockHeight) { int code = pl_end_image(pxs->pgs, v_state->info, true); if (code < 0) return code; v_state->state = vu_blank; v_state->rowwritten = 0; return 0; } /* initialize at begin of image */ if (v_state->state == vu_tagged) { int code = vu_begin_image(pxs); if (code < 0) return code; mode10_state->state = next_is_cmd; mode10_state->cursor = 0; v_state->rowwritten = 0; v_state->state = vu_body; } /* one byte at a time until end of input or end of row */ while ((avail || mode10_state->state == process_rle) /* process_rle does not consume */ &&(!end_of_row)) { switch (mode10_state->state) { case next_is_cmd:{ mode10_state->cmd = *pin++; --avail; if_debug4('w', "command:%02X row written:%d cursor:%d cached=%08X\n", mode10_state->cmd, v_state->rowwritten, mode10_state->cursor, mode10_state->cached_pixel); mode10_state->offset = (mode10_state->cmd >> 3) & 0x03; mode10_state->count = mode10_state->cmd & 0x07; mode10_state->cursor += mode10_state->offset; /* may be partial */ if ((mode10_state->offset < 3) && (mode10_state->count < 7) && (!srcNEW(mode10_state->cmd)) ) { /* completed command */ if (mode10_state->cmd & eRLE) { mode10_state->state = process_rle; } else { /* literal, non-new */ update_pout(pout); pixel = get_pixel(pout, &mode10_state->cached_pixel, mode10_state->cmd, v_state->color_space); copy_pixel(pout, pixel); mode10_state->cursor += 1; if (mode10_state->count > 0) { mode10_state->count--; mode10_state->state = next_is_pixel; } else mode10_state->state = next_is_cmd; } } else if (mode10_state->offset == 3) mode10_state->state = partial_offset; else if (srcNEW(mode10_state->cmd)) { if ((mode10_state->cmd & eRLE) && (mode10_state->cursor >= v_state->SourceWidth)) { /* special case */ if_debug0('w', "special\n"); mode10_state->cursor = 0; end_of_row = 1; mode10_state->state = next_is_cmd; } else mode10_state->state = next_is_pixel; } else if (mode10_state->count == 7) mode10_state->state = partial_count; else mode10_state->state = next_is_cmd; /* does not happen */ break; } case partial_offset:{ uint offset = *pin++; avail--; mode10_state->offset += offset; mode10_state->cursor += offset; if (offset == 0xff) mode10_state->state = partial_offset; else { /* completed offset */ if_debug5('w', "%02X row=%d offset=%d cursor=%d/%d\n", mode10_state->cmd, v_state->rowwritten, mode10_state->offset, mode10_state->cursor, v_state->SourceWidth); if (srcNEW(mode10_state->cmd)) { if ((mode10_state->cmd & eRLE) && (mode10_state->cursor >= v_state->SourceWidth)) { /* special case */ if_debug0('w', "special\n"); mode10_state->cursor = 0; end_of_row = 1; mode10_state->state = next_is_cmd; } else mode10_state->state = next_is_pixel; } else if (mode10_state->count == 7) { mode10_state->state = partial_count; } else { /* not new pixels, counts under 7, so we need to process there */ if (mode10_state->cmd & eRLE) { mode10_state->state = process_rle; } else { /* literal non-new */ update_pout(pout); pixel = get_pixel(pout, &mode10_state->cached_pixel, mode10_state->cmd, v_state->color_space); copy_pixel(pout, pixel); mode10_state->cursor += 1; if (mode10_state->count > 0) { mode10_state->count--; mode10_state->state = next_is_pixel; } else mode10_state->state = next_is_cmd; } } } break; } case partial_count:{ uint count = *pin++; avail--; mode10_state->count += count; if (count == 0xff) mode10_state->state = partial_count; else { /* finished count - partial count only happens on RLE */ if_debug1('w', "count=%d\n", mode10_state->count); mode10_state->state = process_rle; } break; } case next_is_pixel:{ if (!mode9031 && (avail < 3)) { /* get to outer loop to get more data */ avail = 0; break; } if_debug3('w', "pixel:%02X%02X%02X\n", pin[0], pin[1], pin[2]); if (v_state->color_space == eGraySub) { /* bug in recent hpijs */ mode10_state->cached_pixel = (pin[0] << 16 | pin[0] << 8 | pin[0]) ^ 0x00ffffff; } else if (mode9031) { mode10_state->cached_pixel = (pin[0] << 16 | pin[0] << 8 | pin[0]); } else mode10_state->cached_pixel = (pin[0] << 16 | pin[1] << 8 | pin[2]); update_pout(pout); update_advance_pixel(pout, pin, mode9031); if (mode9031) { pin += 1; avail -= 1; } else { pin += 3; avail -= 3; } mode10_state->cursor++; if ((mode10_state->cmd & eRLE) && (mode10_state->count == 7)) mode10_state->state = partial_count; else if (mode10_state->cmd & eRLE) { mode10_state->state = process_rle; } else if (mode10_state->count > 0) { /* literal */ mode10_state->count--; mode10_state->state = next_is_pixel; } else mode10_state->state = next_is_cmd; break; } case process_rle:{ update_pout(pout); pixel = get_pixel(pout, &mode10_state->cached_pixel, mode10_state->cmd, v_state->color_space); mode10_state->cursor += mode10_state->count + 2; i = mode10_state->count + 2; if (srcNEW(mode10_state->cmd)) { i--; /* already moved cursor in the case of new pixel */ mode10_state->cursor--; } while (i > 0) { copy_pixel(pout, pixel); i--; } mode10_state->state = next_is_cmd; break; } } /* end switch */ /* conditional on state may not be necessary */ if ((mode10_state->state == next_is_cmd) && (mode10_state->cursor >= v_state->SourceWidth)) { mode10_state->cursor = 0; end_of_row = 1; } } /* end of while */ par->source.available -= pin - par->source.data; /* subtract compressed data used */ par->source.position += pin - par->source.data; par->source.data = pin; /* new compressed data position */ if (end_of_row) { v_state->rowwritten++; return 1; } return pxNeedData; /* not end of row so request more data */ }