static unsigned calc_raw_width (pixma_t * s, const pixma_scan_param_t * sp) { unsigned raw_width; /* FIXME: Does MP730 need the alignment? */ /* TODO test: MP710/740 */ if (sp->channels == 1) { if (sp->depth == 8) /* grayscale */ { if (s->cfg->pid == MP700_PID || s->cfg->pid == MP730_PID || s->cfg->pid == MP360_PID || s->cfg->pid == MP370_PID || s->cfg->pid == MP375R_PID || s->cfg->pid == MP390_PID || s->cfg->pid == IR1020_PID) raw_width = ALIGN_SUP (sp->w, 4); else raw_width = ALIGN_SUP (sp->w, 12); } else /* depth = 1 : LINEART */ raw_width = ALIGN_SUP (sp->w, 16); } else raw_width = ALIGN_SUP (sp->w, 4); return raw_width; }
static int iclass_scan (pixma_t * s) { int error, n; iclass_t *mf = (iclass_t *) s->subdriver; uint8_t *buf, ignore; unsigned buf_len, ignore2; if (mf->state != state_idle) return PIXMA_EBUSY; /* clear interrupt packets buffer */ while (handle_interrupt (s, 0) > 0) { } mf->raw_width = ALIGN_SUP (s->param->w, 32); PDBG (pixma_dbg (3, "raw_width = %u\n", mf->raw_width)); n = IMAGE_BLOCK_SIZE / s->param->line_size + 1; buf_len = (n + 1) * s->param->line_size + IMAGE_BLOCK_SIZE; if (buf_len > mf->buf_len) { buf = (uint8_t *) realloc (mf->buf, buf_len); if (!buf) return PIXMA_ENOMEM; mf->buf = buf; mf->buf_len = buf_len; } mf->lineptr = mf->buf; mf->blkptr = mf->buf + n * s->param->line_size; mf->blk_len = 0; error = step1 (s); if (error >= 0 && (s->param->adf_pageid == 0 || mf->generation == 1)) { /* single sheet or first sheet from ADF */ PDBG (pixma_dbg (3, "*iclass_scan***** start scanning *****\n")); error = start_session (s); if (error >= 0) mf->state = state_scanning; if (error >= 0) error = select_source (s); } else if (error >= 0) { /* next sheet from ADF */ PDBG (pixma_dbg (3, "*iclass_scan***** scan next sheet from ADF *****\n")); mf->state = state_scanning; } if (error >= 0) error = send_scan_param (s); if (error >= 0) error = request_image_block (s, 0, &ignore, &ignore2, &ignore, &ignore2); if (error < 0) { iclass_finish_scan (s); return error; } mf->last_block = 0; return 0; }
static size_t image_headersz_v1(struct image_tool_params *params, int *hasext) { struct image_cfg_element *binarye; size_t headersz; int ret; /* * Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v1); if (image_count_options(IMAGE_CFG_BINARY) > 1) { fprintf(stderr, "More than one binary blob, not supported\n"); return 0; } if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return 0; } binarye = image_find_option(IMAGE_CFG_BINARY); if (binarye) { struct stat s; ret = stat(binarye->binary.file, &s); if (ret < 0) { char cwd[PATH_MAX]; char *dir = cwd; memset(cwd, 0, sizeof(cwd)); if (!getcwd(cwd, sizeof(cwd))) { dir = "current working directory"; perror("getcwd() failed"); } fprintf(stderr, "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n" "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n" "image for your board. See 'kwbimage -x' to extract it from an existing image.\n", binarye->binary.file, dir); return 0; } headersz += s.st_size + binarye->binary.nargs * sizeof(unsigned int); if (hasext) *hasext = 1; } /* * The payload should be aligned on some reasonable * boundary */ return ALIGN_SUP(headersz, 4096); }
static int iclass_check_param (pixma_t * s, pixma_scan_param_t * sp) { UNUSED (s); sp->depth = 8; sp->line_size = ALIGN_SUP (sp->w, 32) * sp->channels; return 0; }
static int iclass_check_param (pixma_t * s, pixma_scan_param_t * sp) { UNUSED (s); sp->depth = 8; sp->line_size = ALIGN_SUP (sp->w, 32) * sp->channels; /* Some exceptions here for particular devices */ /* Those devices can scan up to Legal 14" with ADF, but A4 11.7" in flatbed */ if (sp->source == PIXMA_SOURCE_FLATBED && ( s->cfg->pid == MF4770_PID )) sp->h = MIN (sp->h, 877 * sp->xdpi / 75); return 0; }
static int mp750_check_param (pixma_t * s, pixma_scan_param_t * sp) { unsigned raw_width; UNUSED (s); sp->depth = 8; /* FIXME: Does MP750 supports other depth? */ /* GH: my implementation */ /* if ((sp->channels == 3) || (is_ccd_grayscale (s))) raw_width = ALIGN_SUP (sp->w, 4); else raw_width = ALIGN_SUP (sp->w, 12);*/ /* the above code gives segmentation fault?!? why... it seems to work in the mp750_scan function */ raw_width = ALIGN_SUP (sp->w, 4); /*sp->line_size = raw_width * sp->channels;*/ sp->line_size = raw_width * sp->channels * (sp->depth / 8); /* no cropping? */ return 0; }
static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, struct image_tool_params *params) { FILE *fcfg; void *image = NULL; int version; size_t headersz = 0; uint32_t checksum; int ret; int size; fcfg = fopen(params->imagename, "r"); if (!fcfg) { fprintf(stderr, "Could not open input file %s\n", params->imagename); exit(EXIT_FAILURE); } image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); if (!image_cfg) { fprintf(stderr, "Cannot allocate memory\n"); fclose(fcfg); exit(EXIT_FAILURE); } memset(image_cfg, 0, IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); rewind(fcfg); ret = image_create_config_parse(fcfg); fclose(fcfg); if (ret) { free(image_cfg); exit(EXIT_FAILURE); } /* The MVEBU BootROM does not allow non word aligned payloads */ sbuf->st_size = ALIGN_SUP(sbuf->st_size, 4); version = image_get_version(); switch (version) { /* * Fallback to version 0 if no version is provided in the * cfg file */ case -1: case 0: image = image_create_v0(&headersz, params, sbuf->st_size); break; case 1: image = image_create_v1(&headersz, params, sbuf->st_size); break; default: fprintf(stderr, "Unsupported version %d\n", version); free(image_cfg); exit(EXIT_FAILURE); } if (!image) { fprintf(stderr, "Could not create image\n"); free(image_cfg); exit(EXIT_FAILURE); } free(image_cfg); /* Build and add image checksum header */ checksum = cpu_to_le32(image_checksum32((uint32_t *)ptr, sbuf->st_size)); size = write(ifd, &checksum, sizeof(uint32_t)); if (size != sizeof(uint32_t)) { fprintf(stderr, "Error:%s - Checksum write %d bytes %s\n", params->cmdname, size, params->imagefile); exit(EXIT_FAILURE); } sbuf->st_size += sizeof(uint32_t); /* Finally copy the header into the image area */ memcpy(ptr, image, headersz); free(image); }
static void *image_create_v1(size_t *imagesz, struct image_tool_params *params, int payloadsz) { struct image_cfg_element *e, *binarye; struct main_hdr_v1 *main_hdr; size_t headersz; void *image, *cur; int hasext = 0; int ret; /* * Calculate the size of the header and the size of the * payload */ headersz = image_headersz_v1(params, &hasext); if (headersz == 0) return NULL; image = malloc(headersz); if (!image) { fprintf(stderr, "Cannot allocate memory for image\n"); return NULL; } memset(image, 0, headersz); cur = main_hdr = image; cur += sizeof(struct main_hdr_v1); /* Fill the main header */ main_hdr->blocksize = cpu_to_le32(payloadsz - headersz + sizeof(uint32_t)); main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF); main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16; main_hdr->destaddr = cpu_to_le32(params->addr); main_hdr->execaddr = cpu_to_le32(params->ep); main_hdr->srcaddr = cpu_to_le32(headersz); main_hdr->ext = hasext; main_hdr->version = 1; e = image_find_option(IMAGE_CFG_BOOT_FROM); if (e) main_hdr->blockid = e->bootfrom; e = image_find_option(IMAGE_CFG_NAND_BLKSZ); if (e) main_hdr->nandblocksize = e->nandblksz / (64 * 1024); e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION); if (e) main_hdr->nandbadblklocation = e->nandbadblklocation; e = image_find_option(IMAGE_CFG_BAUDRATE); if (e) main_hdr->options = baudrate_to_option(e->baudrate); e = image_find_option(IMAGE_CFG_DEBUG); if (e) main_hdr->flags = e->debug ? 0x1 : 0; binarye = image_find_option(IMAGE_CFG_BINARY); if (binarye) { struct opt_hdr_v1 *hdr = cur; uint32_t *args; size_t binhdrsz; struct stat s; int argi; FILE *bin; hdr->headertype = OPT_HDR_V1_BINARY_TYPE; bin = fopen(binarye->binary.file, "r"); if (!bin) { fprintf(stderr, "Cannot open binary file %s\n", binarye->binary.file); return NULL; } fstat(fileno(bin), &s); binhdrsz = sizeof(struct opt_hdr_v1) + (binarye->binary.nargs + 2) * sizeof(uint32_t) + s.st_size; /* * The size includes the binary image size, rounded * up to a 4-byte boundary. Plus 4 bytes for the * next-header byte and 3-byte alignment at the end. */ binhdrsz = ALIGN_SUP(binhdrsz, 4) + 4; hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF); hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16; cur += sizeof(struct opt_hdr_v1); args = cur; *args = cpu_to_le32(binarye->binary.nargs); args++; for (argi = 0; argi < binarye->binary.nargs; argi++) args[argi] = cpu_to_le32(binarye->binary.args[argi]); cur += (binarye->binary.nargs + 1) * sizeof(uint32_t); ret = fread(cur, s.st_size, 1, bin); if (ret != 1) { fprintf(stderr, "Could not read binary image %s\n", binarye->binary.file); return NULL; } fclose(bin); cur += ALIGN_SUP(s.st_size, 4); /* * For now, we don't support more than one binary * header, and no other header types are * supported. So, the binary header is necessarily the * last one */ *((uint32_t *)cur) = 0x00000000; cur += sizeof(uint32_t); } /* Calculate and set the header checksum */ main_hdr->checksum = image_checksum8(main_hdr, headersz); *imagesz = headersz; return image; }
static int mp750_scan (pixma_t * s) { mp750_t *mp = (mp750_t *) s->subdriver; int error; uint8_t *buf; unsigned size, dpi, spare; dpi = s->param->ydpi; /* add a stripe shift for 2400dpi */ mp->stripe_shift = (dpi == 2400) ? 4 : 0; if (mp->state != state_idle) return PIXMA_EBUSY; /* clear interrupt packets buffer */ while (handle_interrupt (s, 0) > 0) { } /* if (s->param->channels == 1) mp->raw_width = ALIGN_SUP (s->param->w, 12); else mp->raw_width = ALIGN_SUP (s->param->w, 4);*/ /* change to use CCD grayscale mode --- why does this give segmentation error at runtime in mp750_check_param? */ if ((s->param->channels == 3) || (is_ccd_grayscale (s))) mp->raw_width = ALIGN_SUP (s->param->w, 4); else mp->raw_width = ALIGN_SUP (s->param->w, 12); /* not sure about MP750, but there is no need for aligning at 12 for the MP760/770, MP780/790 since always use CCD color mode */ /* modify for stripe shift */ spare = 2 * calc_component_shifting (s) + 2 * mp->stripe_shift; /* FIXME: or maybe (2*... + 1)? */ mp->raw_height = s->param->h + spare; PDBG (pixma_dbg (3, "raw_width=%u raw_height=%u dpi=%u\n", mp->raw_width, mp->raw_height, dpi)); /* PDBG (pixma_dbg (4, "line_size=%"PRIu64"\n",s->param->line_size)); */ mp->line_size = get_cis_ccd_line_size (s); /* scanner hardware line_size multiplied by 3 for CCD grayscale */ size = 8 + 2 * IMAGE_BLOCK_SIZE + spare * mp->line_size; buf = (uint8_t *) malloc (size); if (!buf) return PIXMA_ENOMEM; mp->buf = buf; mp->rawimg = buf; mp->imgbuf_ofs = spare * mp->line_size; mp->imgcol = mp->rawimg + IMAGE_BLOCK_SIZE + 8; /* added to make rgb->gray */ mp->img = mp->rawimg + IMAGE_BLOCK_SIZE + 8; mp->imgbuf_len = IMAGE_BLOCK_SIZE + mp->imgbuf_ofs; mp->rawimg_left = 0; mp->last_block_size = 0; mp->shifted_bytes = -(int) mp->imgbuf_ofs; error = step1 (s); if (error >= 0) error = start_session (s); if (error >= 0) mp->state = state_warmup; if (error >= 0) error = select_source (s); if (error >= 0) error = send_scan_param (s); if (error < 0) { mp750_finish_scan (s); return error; } return 0; }
static void *image_create_v1(struct image_cfg_element *image_cfg, int cfgn, const char *output, size_t *imagesz) { struct image_cfg_element *e, *payloade, *binarye; struct main_hdr_v1 *main_hdr; size_t headersz, payloadsz, totalsz; void *image, *cur; int hasext = 0; int ret; /* Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v1); payloadsz = 0; if (image_count_options(image_cfg, cfgn, IMAGE_CFG_BINARY) > 1) { fprintf(stderr, "More than one binary blob, not supported\n"); return NULL; } if (image_count_options(image_cfg, cfgn, IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return NULL; } binarye = image_find_option(image_cfg, cfgn, IMAGE_CFG_BINARY); if (binarye) { struct stat s; ret = stat(binarye->binary.file, &s); if (ret < 0) { char *cwd = get_current_dir_name(); fprintf(stderr, "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n" "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n" "image for your board. See 'kwbimage -x' to extract it from an existing image.\n", binarye->binary.file, cwd); free(cwd); return NULL; } headersz += s.st_size + binarye->binary.nargs * sizeof(unsigned int); hasext = 1; } payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD); if (payloade) { struct stat s; ret = stat(payloade->payload, &s); if (ret < 0) { fprintf(stderr, "Cannot stat payload file %s\n", payloade->payload); return NULL; } payloadsz = s.st_size; } /* The payload should be aligned on some reasonable * boundary */ headersz = ALIGN_SUP(headersz, 4096); /* The total size includes the headers, the payload, and the * 32 bits checksum at the end of the payload */ totalsz = headersz + payloadsz + sizeof(uint32_t); image = malloc(totalsz); if (!image) { fprintf(stderr, "Cannot allocate memory for image\n"); return NULL; } memset(image, 0, totalsz); cur = main_hdr = image; cur += sizeof(struct main_hdr_v1); /* Fill the main header */ main_hdr->blocksize = payloadsz + sizeof(uint32_t); main_hdr->headersz_lsb = headersz & 0xFFFF; main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16; main_hdr->srcaddr = headersz; main_hdr->ext = hasext; main_hdr->version = 1; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM); if (e) main_hdr->blockid = e->bootfrom; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR); if (e) main_hdr->destaddr = e->dstaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR); if (e) main_hdr->execaddr = e->execaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BLKSZ); if (e) main_hdr->nandblocksize = e->nandblksz / (64 * 1024); e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BADBLK_LOCATION); if (e) main_hdr->nandbadblklocation = e->nandbadblklocation; if (binarye) { struct opt_hdr_v1 *hdr = cur; unsigned int *args; size_t binhdrsz; struct stat s; int argi; FILE *bin; hdr->headertype = OPT_HDR_V1_BINARY_TYPE; bin = fopen(binarye->binary.file, "r"); if (!bin) { fprintf(stderr, "Cannot open binary file %s\n", binarye->binary.file); return NULL; } fstat(fileno(bin), &s); binhdrsz = sizeof(struct opt_hdr_v1) + (binarye->binary.nargs + 1) * sizeof(unsigned int) + s.st_size; hdr->headersz_lsb = binhdrsz & 0xFFFF; hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16; cur += sizeof(struct opt_hdr_v1); args = cur; *args = binarye->binary.nargs; args++; for (argi = 0; argi < binarye->binary.nargs; argi++) args[argi] = binarye->binary.args[argi]; cur += (binarye->binary.nargs + 1) * sizeof(unsigned int); ret = fread(cur, s.st_size, 1, bin); if (ret != 1) { fprintf(stderr, "Could not read binary image %s\n", binarye->binary.file); return NULL; } fclose(bin); cur += s.st_size; /* * For now, we don't support more than one binary * header, and no other header types are * supported. So, the binary header is necessarily the * last one */ *((unsigned char *) cur) = 0; cur += sizeof(uint32_t); } /* Calculate and set the header checksum */ main_hdr->checksum = image_checksum8(main_hdr, headersz); if (payloade) { ret = image_create_payload(image + headersz, payloadsz, payloade->payload); if (ret < 0) return NULL; } *imagesz = totalsz; return image; }