static int mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { int error, n; mp730_t *mp = (mp730_t *) s->subdriver; unsigned block_size, bytes_received; uint8_t header[16]; do { do { if (s->cancel) return PIXMA_ECANCELED; if (mp->last_block) /* end of image */ return 0; error = read_image_block (s, header, mp->imgbuf + mp->imgbuf_len); if (error < 0) return error; bytes_received = error; block_size = pixma_get_be16 (header + 4); mp->last_block = ((header[2] & 0x28) == 0x28); if (mp->last_block) { /* end of image */ mp->state = state_finished; } if ((header[2] & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n")); PDBG (pixma_hexdump (1, header, 16)); } PASSERT (bytes_received == block_size); if (block_size == 0) { /* no image data at this moment. */ /*pixma_sleep(100000); *//* FIXME: too short, too long? */ handle_interrupt (s, 100); } } while (block_size == 0); /* TODO: simplify! */ mp->imgbuf_len += bytes_received; n = mp->imgbuf_len / s->param->line_size; /* n = number of full lines (rows) we have in the buffer. */ if (n != 0) { if (s->param->channels != 1 && s->cfg->pid != MF5730_PID && s->cfg->pid != MF5750_PID && s->cfg->pid != MF5770_PID && s->cfg->pid != MF3110_PID && s->cfg->pid != IR1020_PID) { /* color, and not an MF57x0 nor MF3110 */ pack_rgb (mp->imgbuf, n, mp->raw_width, mp->lbuf); } else /* grayscale/lineart or MF57x0 or MF3110 */ memcpy (mp->lbuf, mp->imgbuf, n * s->param->line_size); block_size = n * s->param->line_size; mp->imgbuf_len -= block_size; memcpy (mp->imgbuf, mp->imgbuf + block_size, mp->imgbuf_len); } } while (n == 0); ib->rptr = mp->lbuf; ib->rend = mp->lbuf + block_size; return ib->rend - ib->rptr; }
static int mp750_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { mp750_t *mp = (mp750_t *) s->subdriver; int error; uint8_t info; unsigned block_size, bytes_received, n; int shift[3], base_shift; int c; c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8; /* single-byte or double-byte data */ if (mp->state == state_warmup) { int tmo = 60; query_status (s); check_status (s); /*SIM*/ while (!is_calibrated (s) && --tmo >= 0) { if (s->cancel) return PIXMA_ECANCELED; if (handle_interrupt (s, 1000) > 0) { block_size = 0; error = request_image_block (s, &block_size, &info); /*SIM*/ if (error < 0) return error; } } if (tmo < 0) { PDBG (pixma_dbg (1, "WARNING: Timed out waiting for calibration\n")); return PIXMA_ETIMEDOUT; } pixma_sleep (100000); query_status (s); if (is_warming_up (s) || !is_calibrated (s)) { PDBG (pixma_dbg (1, "WARNING: Wrong status: wup=%d cal=%d\n", is_warming_up (s), is_calibrated (s))); return PIXMA_EPROTO; } block_size = 0; request_image_block (s, &block_size, &info); /*SIM*/ mp->state = state_scanning; mp->last_block = 0; } /* TODO: Move to other place, values are constant. */ base_shift = calc_component_shifting (s) * mp->line_size; if (s->param->source == PIXMA_SOURCE_ADF) { shift[0] = 0; shift[1] = -base_shift; shift[2] = -2 * base_shift; } else { shift[0] = -2 * base_shift; shift[1] = -base_shift; shift[2] = 0; } do { if (mp->last_block_size > 0) { block_size = mp->imgbuf_len - mp->last_block_size; memcpy (mp->img, mp->img + mp->last_block_size, block_size); } do { if (s->cancel) return PIXMA_ECANCELED; if (mp->last_block) { /* end of image */ info = mp->last_block; if (info != 0x38) { query_status (s); /*SIM*/ while ((info & 0x28) != 0x28) { pixma_sleep (10000); error = request_image_block2 (s, &info); if (s->cancel) return PIXMA_ECANCELED; /* FIXME: Is it safe to cancel here? */ if (error < 0) return error; } } mp->needs_abort = (info != 0x38); mp->last_block = info; mp->state = state_finished; return 0; } check_status (s); /*SIM*/ while (handle_interrupt (s, 1) > 0); /*SIM*/ block_size = IMAGE_BLOCK_SIZE; error = request_image_block (s, &block_size, &info); if (error < 0) { if (error == PIXMA_ECANCELED) read_error_info (s, NULL, 0); return error; } mp->last_block = info; if ((info & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unknown info byte %x\n", info)); } if (block_size == 0) { /* no image data at this moment. */ pixma_sleep (10000); } } while (block_size == 0); error = read_image_block (s, mp->rawimg + mp->rawimg_left); if (error < 0) { mp->state = state_transfering; return error; } bytes_received = error; PASSERT (bytes_received == block_size); /* TODO: simplify! */ mp->rawimg_left += bytes_received; n = mp->rawimg_left / 3; /* n = number of pixels in the buffer? */ /* Color to Grayscale converion for CCD sensor */ if (is_ccd_grayscale (s)) { shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, mp->imgcol + mp->imgbuf_ofs); /* dst: img, src: imgcol */ rgb_to_gray (mp->img, mp->imgcol, n, c); /* cropping occurs later? */ PDBG (pixma_dbg (4, "*fill_buffer: did grayscale conversion \n")); } /* Color image processing */ else { shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, mp->img + mp->imgbuf_ofs); PDBG (pixma_dbg (4, "*fill_buffer: no grayscale conversion---keep color \n")); } /* entering remaining unprocessed bytes after last complete pixel into mp->rawimg buffer -- no influence on mp->img */ n *= 3; mp->shifted_bytes += n; mp->rawimg_left -= n; /* rawimg_left = 0, 1 or 2 bytes left in the buffer. */ mp->last_block_size = n; memcpy (mp->rawimg, mp->rawimg + n, mp->rawimg_left); } while (mp->shifted_bytes <= 0); if ((unsigned) mp->shifted_bytes < mp->last_block_size) { if (is_ccd_grayscale (s)) ib->rptr = mp->img + mp->last_block_size/3 - mp->shifted_bytes/3; /* testing---works OK */ else ib->rptr = mp->img + mp->last_block_size - mp->shifted_bytes; } else ib->rptr = mp->img; if (is_ccd_grayscale (s)) ib->rend = mp->img + mp->last_block_size/3; /* testing---works OK */ else ib->rend = mp->img + mp->last_block_size; return ib->rend - ib->rptr; }
static void read_image_data(Gif_Context *gfc, Gif_Reader *grr) { /* we need a bit more than GIF_MAX_BLOCK in case a single code is split across blocks */ uint8_t buffer[GIF_MAX_BLOCK + 5]; int i; uint32_t accum; int bit_position; int bit_length; Gif_Code code; Gif_Code old_code; Gif_Code clear_code; Gif_Code eoi_code; Gif_Code next_code; #define CUR_BUMP_CODE (1 << bits_needed) #define CUR_CODE_MASK ((1 << bits_needed) - 1) int min_code_size; int bits_needed; gfc->decodepos = 0; min_code_size = gifgetbyte(grr); GIF_DEBUG(("\n\nmin_code_size(%d)", min_code_size)); if (min_code_size >= GIF_MAX_CODE_BITS) { gif_read_error(gfc, 1, "image corrupted, min_code_size too big"); min_code_size = GIF_MAX_CODE_BITS - 1; } else if (min_code_size < 2) { gif_read_error(gfc, 1, "image corrupted, min_code_size too small"); min_code_size = 2; } clear_code = 1 << min_code_size; for (code = 0; code < clear_code; code++) { gfc->prefix[code] = 49428; gfc->suffix[code] = (uint8_t)code; gfc->length[code] = 1; } eoi_code = clear_code + 1; next_code = eoi_code; bits_needed = min_code_size + 1; code = clear_code; bit_length = bit_position = 0; /* Thus the 'Read in the next data block.' code below will be invoked on the first time through: exactly right! */ while (1) { old_code = code; /* GET A CODE INTO THE 'code' VARIABLE. * * 9.Dec.1998 - Rather than maintain a byte pointer and a bit offset into * the current byte (and the processing associated with that), we maintain * one number: the offset, in bits, from the beginning of 'buffer'. This * much cleaner choice was inspired by Patrick J. Naughton * <*****@*****.**>'s GIF-reading code, which does the same thing. * His code distributed as part of XV in xvgif.c. */ if (bit_position + bits_needed > bit_length) /* Read in the next data block. */ if (!read_image_block(grr, buffer, &bit_position, &bit_length, bits_needed)) goto zero_length_block; i = bit_position / 8; accum = buffer[i] + (buffer[i+1] << 8); if (bits_needed >= 8) accum |= (buffer[i+2]) << 16; code = (Gif_Code)((accum >> (bit_position % 8)) & CUR_CODE_MASK); bit_position += bits_needed; GIF_DEBUG(("%d", code)); /* CHECK FOR SPECIAL OR BAD CODES: clear_code, eoi_code, or a code that is * too large. */ if (code == clear_code) { GIF_DEBUG(("clear")); bits_needed = min_code_size + 1; next_code = eoi_code; continue; } else if (code == eoi_code) break; else if (code > next_code && next_code && next_code != clear_code) { /* code > next_code: a (hopefully recoverable) error. Bug fix, 5/27: Do this even if old_code == clear_code, and set code to 0 to prevent errors later. (If we didn't zero code, we'd later set old_code = code; then we had old_code >= next_code; so the prefixes array got all screwed up!) Bug fix, 4/12/2010: It is not an error if next_code == clear_code. This happens at the end of a large GIF: see the next comment ("If no meaningful next code should be defined...."). */ if (gfc->errors[1] < 20) gif_read_error(gfc, 1, "image corrupted, code out of range"); else if (gfc->errors[1] == 20) gif_read_error(gfc, 1, "(not reporting more errors)"); code = 0; } /* PROCESS THE CURRENT CODE and define the next code. If no meaningful * next code should be defined, then we have set next_code to either * 'eoi_code' or 'clear_code' -- so we'll store useless prefix/suffix data * in a useless place. */ /* *First,* set up the prefix and length for the next code (in case code == next_code). */ gfc->prefix[next_code] = old_code; gfc->length[next_code] = gfc->length[old_code] + 1; /* Use one_code to process code. It's nice that it returns the first pixel in code: that's what we need. */ gfc->suffix[next_code] = one_code(gfc, code); /* Special processing if code == next_code: we didn't know code's final suffix when we called one_code, but we do now. */ /* 7.Mar.2014 -- Avoid error if image has zero width/height. */ if (code == next_code && gfc->image + gfc->decodepos <= gfc->maximage) gfc->image[gfc->decodepos - 1] = gfc->suffix[next_code]; /* Increment next_code except for the 'clear_code' special case (that's when we're reading at the end of a GIF) */ if (next_code != clear_code) { next_code++; if (next_code == CUR_BUMP_CODE) { if (bits_needed < GIF_MAX_CODE_BITS) bits_needed++; else next_code = clear_code; } } } /* read blocks until zero-length reached. */ i = gifgetbyte(grr); GIF_DEBUG(("\nafter_image(%d)\n", i)); while (i > 0) { gifgetblock(buffer, i, grr); i = gifgetbyte(grr); GIF_DEBUG(("\nafter_image(%d)\n", i)); } /* zero-length block reached. */ zero_length_block: { long delta = (long) (gfc->maximage - gfc->image) - (long) gfc->decodepos; char buf[BUFSIZ]; if (delta > 0) { sprintf(buf, "missing %ld pixels of image data", delta); gif_read_error(gfc, 1, buf); } else if (delta < -1) { /* One pixel of superfluous data is OK; that could be the code == next_code case. */ sprintf(buf, "%ld superfluous pixels of image data", -delta); gif_read_error(gfc, 0, buf); } } }
static int iclass_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { int error, n; iclass_t *mf = (iclass_t *) s->subdriver; unsigned block_size, lines_size, first_block_size; uint8_t info; /* * 1. send a block request cmd (d4 20 00... 04 00 06) * 2. examine the response for block size and/or end-of-scan flag * 3. read the block one chunk at a time * 4. repeat until have enough to process >=1 lines */ do { do { if (s->cancel) return PIXMA_ECANCELED; if (mf->last_block) { /* end of image */ mf->state = state_finished; return 0; } first_block_size = 0; error = request_image_block (s, 4, &info, &block_size, mf->blkptr + mf->blk_len, &first_block_size); /* add current block to remainder of previous */ mf->blk_len += first_block_size; if (error < 0) { /* NOTE: seen in traffic logs but don't know the meaning. */ read_error_info (s, NULL, 0); if (error == PIXMA_ECANCELED) return error; } /* info: 0x28 = end; 0x38 = end + ADF empty */ mf->last_block = info & 0x38; if ((info & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n")); PDBG (pixma_hexdump (1, &info, 1)); } if (block_size == 0) { /* no image data at this moment. */ /*pixma_sleep(100000); *//* FIXME: too short, too long? */ handle_interrupt (s, 100); } } while (block_size == 0 && first_block_size == 0); error = read_image_block (s, mf->blkptr + mf->blk_len, block_size); block_size = error; if (error < 0) return error; /* add current block to remainder of previous */ mf->blk_len += block_size; /* n = number of full lines (rows) we have in the buffer. */ n = mf->blk_len / s->param->line_size; if (n != 0) { if (s->param->channels != 1 && s->cfg->pid != MF3010_PID && s->cfg->pid != MF4410_PID && s->cfg->pid != MF4770_PID && s->cfg->pid != MF4550_PID && s->cfg->pid != MF4600_PID && s->cfg->pid != MF6500_PID && s->cfg->pid != MF8030_PID) { /* color and not MF46xx or MF65xx */ pack_rgb (mf->blkptr, n, mf->raw_width, mf->lineptr); } else { /* grayscale */ memcpy (mf->lineptr, mf->blkptr, n * s->param->line_size); } lines_size = n * s->param->line_size; /* cull remainder and shift left */ mf->blk_len -= lines_size; memcpy (mf->blkptr, mf->blkptr + lines_size, mf->blk_len); } } while (n == 0); /* output full lines, keep partial lines for next block */ ib->rptr = mf->lineptr; ib->rend = mf->lineptr + lines_size; return ib->rend - ib->rptr; }