Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
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);
}
Beispiel #4
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;
  return 0;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}