Beispiel #1
0
int iclose(RGB_IMAGE *image) {
  long tablesize, ret;

  iflush(image);
  img_optseek(image, 0);
  if (image->flags&_IOWRT) {
    if (image->dorev)
      cvtimage((long *)image);
    swapImage(image) ;
    if (img_write(image,(char *)image,sizeof(RGB_IMAGE)) != sizeof(RGB_IMAGE)) {
      i_errhdlr("iclose: error on write of image header\n",0,0,0,0);
      return EOF;
    }
    swapImage(image) ;
    if (image->dorev)
      cvtimage((long *)image);
    if (ISRLE(image->type)) {
      img_optseek(image, 512L);
      tablesize = image->ysize*image->zsize*sizeof(long);
      if (image->dorev)
        cvtlongs((long *)image->rowstart,(long)tablesize);
      if (img_write(image,(char *)(image->rowstart),tablesize) != tablesize) {
        i_errhdlr("iclose: error on write of rowstart\n",0,0,0,0);
        return EOF;
      }
      if (image->dorev)
        cvtlongs((long *)image->rowsize,tablesize);
      if (img_write(image,(char *)(image->rowsize),tablesize) != tablesize) {
        i_errhdlr("iclose: error on write of rowsize\n",0,0,0,0);
        return EOF;
      }
    }
  }
  if (image->base) {
    free(image->base);
    image->base = 0;
  }
  if (image->tmpbuf) {
    free(image->tmpbuf);
    image->tmpbuf = 0;
  }
  if (ISRLE(image->type)) {
    free(image->rowstart);
    image->rowstart = 0;
    free(image->rowsize);
    image->rowsize = 0;
  }
  ret = close(image->file);
  if (ret != 0)
    i_errhdlr("iclose: error on close of file\n",0,0,0,0);
  free(image);
  return ret;
}
Beispiel #2
0
/*
 * and input1 input2 output: logical-and pixels of two images
 */
static int
cmd_and(int argc, char *argv[])
{
	img_t *image, *mask;
	int rv;

	if (argc < 3)
		return (EXIT_USAGE);

	image = img_read(argv[0]);
	mask = img_read(argv[1]);

	if (mask == NULL || image == NULL) {
		img_free(image);
		return (EXIT_FAILURE);
	}

	if (image->img_width != mask->img_width ||
	    image->img_height != mask->img_height) {
		warnx("image dimensions do not match");
		img_free(image);
		img_free(mask);
		return (EXIT_FAILURE);
	}

	img_and(image, mask);
	rv = img_write(image, argv[2]);
	img_free(image);
	img_free(mask);
	return (rv == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
Beispiel #3
0
main(int argc, char **argv)
{
  Prim *o;
  Color c; int u, v;
  Ray r; Inode *l;

  o = sphere_instance(&sphere_funcs);
  init_sdl();
  s = scene_read();
  init_render();

  for (v = s->view->sc.ll.y; v < s->view->sc.ur.y; v += 1) {
    for (u = s->view->sc.ll.x; u < s->view->sc.ur.x; u += 1) {
      r = ray_unit(ray_transform(ray_view(u, v), mclip));
      if ((l = ray_intersect(s->objs, r)) != NULL) 
        c = point_tshade(ray_point(r, l->t), l->n, s->view->center, rc, l->m, o);
      else 
	c = bgcolor;
      inode_free(l);
      img_putc(s->img, u, v, col_dpymap(c));
    }
  }
  img_write(s->img,"stdout",0);
  exit(0);
}
Beispiel #4
0
int main(int argc, char **argv)
{
  Poly *l, *p, *q = poly_alloc(3);
  Hpoly *t = hpoly_alloc(3);
  Item *i;

  init_sdl();
  s = scene_read();
  init_render();

  for (o = s->objs; o != NULL; o = o->next) {
    for (l = prim_uv_decomp(o->u.prim, 1.); l != NULL; l = l->next) {
      p = poly_transform(prim_polys(o->u.prim, l), mclip);
      if (!is_backfacing(p, v3_unit(v3_scale(-1, poly_centr(p)))))
	hither_clip(0, p, z_store, plist_free);
    }
  }
  z = z_sort(z);

  for (i = z->head; i != NULL; i = i->next) {
    t = hpoly_polyxform(t, S(i), mdpy);
    q = poly_wz_hpoly(q, W(i), t);
    texture_wscale(W(i), T(i));
    scan_spoly3(q, 2, texture_shadepaint,
             texture_set(td,W(i),T(i),P(i),N(i),DU(i),DV(i),rc,M(i)));
  }
  img_write(s->img, "stdout", 0);
  exit(0);
}
Beispiel #5
0
int main(int argc, char **argv)
{
  Poly *l, *p, *c = poly_alloc(3);
  Item *i;

  init_sdl();
  s = scene_read();
  init_render();

  for (o = s->objs; o != NULL; o = o->next) {
    for (l = prim_uv_decomp(o->u.prim, 1.); l != NULL; l = l->next) {
      p = poly_transform(prim_polys(o->u.prim, l), mclip);
      if (!is_backfacing(p, v3_unit(v3_scale(-1, poly_centr(p)))))
	hither_clip(VIEW_ZMIN(s->view), p, z_store, plist_free);
    }
  }
  z = z_sort(z);

  for (i = z->head; i != NULL; i = i->next) { 
    gouraud_shade(c, P(i), N(i), s->view->center, rc, M(i));
    p = poly_homoxform(S(i),mdpy);
    scan_poly(p, gouraud_paint, gouraud_set(g,c,s->img));
  }
  img_write(s->img, "stdout", 0);
  exit(0);
}
Beispiel #6
0
/*
 * translatexy input output xoffset yoffset: shift an image by the given offsets
 */
static int
cmd_translatexy(int argc, char *argv[])
{
	img_t *image, *newimage;
	char *q;
	int rv;
	long dx, dy;

	if (argc < 4)
		return (EXIT_USAGE);

	image = img_read(argv[0]);
	if (image == NULL)
		return (EXIT_FAILURE);

	dx = strtol(argv[2], &q, 0);
	if (*q != '\0')
		warnx("x offset value truncated to %d", dx);

	dy = strtol(argv[3], &q, 0);
	if (*q != '\0')
		warnx("y offset value truncated to %d", dy);

	newimage = img_translatexy(image, dx, dy);
	if (newimage == NULL) {
		warn("failed to translate image");
		img_free(image);
		return (EXIT_FAILURE);
	}

	rv = img_write(newimage, argv[1]);
	img_free(newimage);
	return (rv);
}
Beispiel #7
0
/**
 * @brief def_write_sector - default write sector function
 *
 * This assumes the default image type with disk geometry
 * defined by the system driver.
 */
static int def_write_sector(struct img_s *img, uint32_t head, uint32_t sec,
	void *buff, size_t size, uint32_t den, uint32_t ddam)
{
	uint32_t cyl, heads, spt, sn0, len, lba;
	off_t offs;

	cyl = img_get_flag(img, DRV_CURRENT_CYLINDER);
	heads = img_get_flag(img, DRV_TOTAL_HEADS);
	spt = img_get_flag(img, DRV_SECTORS_PER_TRACK);
	sn0 = img_get_flag(img, DRV_FIRST_SECTOR_ID);
	len = img_get_flag(img, DRV_SECTOR_LENGTH);

	if (head >= heads)
		return -1;

	if (cyl >= img_get_flag(img, DRV_TOTAL_CYLINDERS))
		return -1;

	if (sec > spt)
		return -1;

	lba = (heads * cyl + head) * spt + sec - sn0;
	LOG((1,"DEF","write C:%02x H:%x R:%02x SPT:%02x (LBA:%x) size:0x%x\n",
		cyl, head, sec, spt, lba, size));
	fdd_set_ddam(img, lba, ddam);

	offs = (off_t)len * lba;
	if (size == img_write(img, offs, buff, size))
		return 0;
	return -1;
}
Beispiel #8
0
void texture_save_to_file(const texture_t *tex, const char *path)
{
    uint8_t *data;
    int w, h;
    LOG_I("save texture to %s", path);
    w = tex->tex_w;
    h = tex->tex_h;
    data = calloc(w * h, 4);
    texture_get_data(tex, w, h, 4, data);
    img_write(data, w, h, 4, path);
    free(data);
}
Beispiel #9
0
void
kv_vidctx_frame_emit(kv_vidctx_t *kvp, const char *framename, int i, int timems,
    img_t *img, kv_screen_t *ksp, kv_screen_t *raceksp, FILE *fp)
{
	if (kvp->kv_dbgdir[0] != '\0') {
		char buf[PATH_MAX];
		(void) snprintf(buf, sizeof (buf), "%s/%s.png", kvp->kv_dbgdir,
		    framename);
		(void) img_write(img, buf);
	}

	kvp->kv_emit(framename, i, timems, ksp, raceksp, fp);
}
Beispiel #10
0
/*
 * compare image mask: compute a difference score for the given image and mask.
 */
static int
cmd_compare(int argc, char *argv[])
{
	img_t *image, *mask, *dbgmask;
	char *dbgfile = NULL;
	int rv;
	char c;

	while ((c = getopt(argc, argv, "s:")) != -1) {
		switch (c) {
		case 's':
			dbgfile = optarg;
			break;
		default:
			return (EXIT_USAGE);
		}
	}

	if (optind + 2 > argc)
		return (EXIT_USAGE);

	image = img_read(argv[optind++]);
	mask = img_read(argv[optind++]);

	if (mask == NULL || image == NULL) {
		img_free(image);
		return (EXIT_FAILURE);
	}

	if (image->img_width != mask->img_width ||
	    image->img_height != mask->img_height) {
		warnx("image dimensions do not match");
		rv = EXIT_FAILURE;
		goto done;
	}

	(void) printf("%f\n",
	    img_compare(image, mask, dbgfile ? &dbgmask : NULL));

	if (dbgfile != NULL && dbgmask != NULL) {
		(void) img_write(dbgmask, dbgfile);
		img_free(dbgmask);
	}

	rv = EXIT_SUCCESS;

done:
	img_free(image);
	img_free(mask);
	return (rv);
}
Beispiel #11
0
int main (int argc, char *argv[]){


    unsigned int out[NUM_COLS * NUM_ROWS] = {0};

    unsigned short theta = 0;

    theta = atoi(argv[1]);

    bilinear(in, (unsigned int)(NUM_COLS), (unsigned int) (NUM_ROWS), theta, out);
    img_write(out, 1024, 1024);
    return 0;
    
}
Beispiel #12
0
static int
write_frame(video_frame_t *vfp, void *rawarg)
{
	const char *dir = (char *)rawarg;
	char buf[PATH_MAX];

	(void) snprintf(buf, sizeof (buf), "%s/frame%d.png",
	    dir, vfp->vf_framenum);
	(void) img_write(&vfp->vf_image, buf);

	if (vfp->vf_framenum > 5)
		return (EXIT_FAILURE);

	return (EXIT_SUCCESS);
}
Beispiel #13
0
main(int argc, char **argv)
{
    Color c;
    int u, v;
    Ray r;

    init_sdl();
    s = scene_read();
    init_render();

    for (v = s->view->sc.ll.y; v < s->view->sc.ur.y; v += 1) {
        for (u = s->view->sc.ll.x; u < s->view->sc.ur.x; u += 1) {
            r = ray_unit(ray_transform(ray_view(u, v), mclip));
            c = ray_shade(0, 1., r, rc, s->objs);
            img_putc(s->img, u, v, col_dpymap(c));
        }
    }
    img_write(s->img,"stdout",0);
    exit(0);
}
Beispiel #14
0
int dmk_put_track(struct img_s *img, dmk_t *dmk, uint32_t cyl, uint32_t head)
{
	uint32_t drive, cyllen, heads;
	off_t offs;

	drive = img_minor(img);
	cyllen = dmk->cyllen[0] + 256 * dmk->cyllen[1];
	heads = (dmk->flags & DMK_FLAG_SSIDE) ? 1 : 2;

	LOG((3,"DMK","#%x write track %u, head %u from buffer\n",
		drive, cyl, head));

	offs = DMK_HEADER_SIZE + (off_t)cyllen * (cyl * heads + head);
	if (cyllen != img_write(img, offs, dmk->track, cyllen))
		return -1;

#if	DMK_CACHE_TRACK
	dmk->rsvd[DMK_TRACK_BUFF] = cyl;
	dmk->rsvd[DMK_SIDE_BUFF] = head;
#endif
	return 0;
}
Beispiel #15
0
void texture_save_to_file(const texture_t *tex, const char *path)
{
    LOG_I("save texture to %s", path);
    int bpp;
    uint8_t *data, *tmp;
    int i, w, h;

    w = tex->tex_w;
    h = tex->tex_h;
    GL(glBindFramebuffer(GL_FRAMEBUFFER, tex->framebuffer));
    bpp = 4;
    data = calloc(w * h, bpp);
    GL(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data));
    // Flip output y.
    tmp = data;
    data = calloc(w * h, bpp);
    for (i = 0; i < h; i++) {
        memcpy(&data[i * w * bpp], &tmp[(h - i - 1) * w * bpp], bpp * w);
    }
    free(tmp);

    img_write(data, w, h, bpp, path);
    free(data);
}
Beispiel #16
0
int putrow( IMAGE *image, IMushort *buffer, int y, int z )
{
    register IMushort 	*sptr;
    register unsigned char      *cptr;
    register unsigned int x;
    register IMulong min, max;
    register int cnt;

    if( !(image->flags & (_IORW|_IOWRT)) )
	return -1;
    if(image->dim<3)
	z = 0;
    if(image->dim<2)
	y = 0;
    if(ISVERBATIM(image->type)) {
	switch(BPP(image->type)) {
	    case 1:
		min = image->min;
		max = image->max;
		cptr = (unsigned char *)image->tmpbuf;
		sptr = buffer;
		for(x=image->xsize; x--;) {
		    *cptr = *sptr++;
		    if (*cptr > max) max = *cptr;
		    if (*cptr < min) min = *cptr;
		    cptr++;
		}
		image->min = min;
		image->max = max;
		img_seek(image,y,z);
		cnt = image->xsize;
		if (img_write(image,(char *)image->tmpbuf,cnt) != cnt)
		    return -1;
		else
		    return cnt;

	    case 2:
		min = image->min;
		max = image->max;
		sptr = buffer;
		for(x=image->xsize; x--;) {
		    if (*sptr > max) max = *sptr;
		    if (*sptr < min) min = *sptr;
		    sptr++;
		}
		image->min = min;
		image->max = max;
		img_seek(image,y,z);
		cnt = image->xsize<<1;
		if(image->dorev)
		    cvtshorts(buffer,cnt);
		if (img_write(image,(char *)buffer,cnt) != cnt) {
		    if(image->dorev)
			cvtshorts(buffer,cnt);
		    return -1;
		} else {
		    if(image->dorev)
			cvtshorts(buffer,cnt);
		    return image->xsize;
		}

	    default:
		i_errhdlr("putrow: wierd bpp\n");
	}
    } else if(ISRLE(image->type)) {
	switch(BPP(image->type)) {
	    case 1:
		min = image->min;
		max = image->max;
		sptr = buffer;
		for(x=image->xsize; x--;) {
		    if (*sptr > max) max = *sptr;
		    if (*sptr < min) min = *sptr;
		    sptr++;
		}
		image->min = min;
		image->max = max;
		cnt = img_rle_compact(buffer,2,image->tmpbuf,1,image->xsize);
		img_setrowsize(image,cnt,y,z);
		img_seek(image,y,z);
		if (img_write(image,(char *)image->tmpbuf,cnt) != cnt)
		    return -1;
		else
		    return image->xsize;
		break;

	    case 2:
		min = image->min;
		max = image->max;
		sptr = buffer;
		for(x=image->xsize; x--;) {
		    if (*sptr > max) max = *sptr;
		    if (*sptr < min) min = *sptr;
		    sptr++;
		}
		image->min = min;
		image->max = max;
		cnt = img_rle_compact(buffer,2,image->tmpbuf,2,image->xsize);
		cnt <<= 1;
		img_setrowsize(image,cnt,y,z);
		img_seek(image,y,z);
		if(image->dorev)
		    cvtshorts(image->tmpbuf,cnt);
		if (img_write(image,(char *)image->tmpbuf,cnt) != cnt) {
		    if(image->dorev)
			cvtshorts(image->tmpbuf,cnt);
		    return -1;
		} else {
		    if(image->dorev)
			cvtshorts(image->tmpbuf,cnt);
		    return image->xsize;
		}
		break;

	    default:
		i_errhdlr("putrow: wierd bpp\n");
	}
    } else
	i_errhdlr("putrow: wierd image type\n");
    return 0;
}
Beispiel #17
0
int _tmain(int argc, _TCHAR* argv[])
{
  BPNN *net;
  IMAGE *img;
  int nr, nc,  i, j, k, out, pxl;
  double maxwt, minwt, range;

  if (argc < 6) {
    fprintf(stderr, "usage:  %s net-file image-file x y output-unit-num\n",
	    argv[0]);
    exit(1);
  }

  if ((net = bpnn_read(argv[1])) == NULL) {
    fprintf(stderr, "%s:  can't read net-file '%s'\n", argv[0], argv[1]);
    exit(1);
  }
      
  nc = atoi(argv[3]);
  nr = atoi(argv[4]);
  out = atoi(argv[5]);
  if ((img = img_creat(argv[2], 2*nr, 2*nc)) == NULL) {
    fprintf(stderr, "%s:  can't create image-file '%s'\n", argv[0], argv[2]);
    exit(1);
  }
      
  /* let the user in on the weight values */
  fprintf(stdout, "Output unit %s:\n Weight values: \n", argv[5]);  
  for (i = 0; i < nc; i++) {
    printf("i=%d\n", i);
    fprintf(stdout, "  %g\n", net->hidden_weights[i][out]);
  }
  /* first get min and max wts */
  k = 0;
  maxwt = -1e6;
  minwt = 1e6;
  for (i = 0; i < nr; i++) {
    for (j = 0; j < nc; j++) {
      if (net->hidden_weights[k][out] > maxwt)
	maxwt = net->hidden_weights[k][out];
      if (net->hidden_weights[k][out] < minwt)
	minwt = net->hidden_weights[k][out];
      k++;
    }
  }
  range = maxwt - minwt;
  /* now scale values */
  k = 0;
  for (i = 0; i < nr; i++) {
    for (j = 0; j < nc; j++) {
      tmpimg = net->hidden_weights[k][out];
      pxl = ((tmpimg-minwt)/range) * 255.0;
      /* because of xv problem with single-line images, make image double the
         number of rows and columns */
      img_setpixel(img, 2*i, 2*j, pxl);
      img_setpixel(img, 1+2*i, 1+2*j, pxl);
      img_setpixel(img, 2*i, 1+2*j, pxl);
      img_setpixel(img, 1+2*i, 2*j, pxl);
      k++;
    }
  }

  img_write(img, argv[2]);
  return 0;
}
Beispiel #18
0
// -----------------------------------------------------------------------
int main(int argc, char **argv)
{
	parse_args(argc, argv);

	// open input file
	yyin = fopen(argv[optind], "r");
	if (!yyin) {
		printf("Error: cannot open input file, exiting.\n");
		exit(1);
	}

	// parse program
	int res = yyparse();

	fclose(yyin);
	yylex_destroy();

	if (res != 0) {
		printf("Cannot parse source, exiting.\n");
		nodelist_drop(program);
		exit(1);
	}

	// assembly binary image
	res = assembly(program->head);

	if (res < 0) {
		printf("Error at %s\n", assembly_error);
		nodelist_drop(program);
		exit(1);
	}

	res = img_write(output_file);

	if (res < 0) {
		if (res == E_IO_OPEN) {
			printf("Cannot open output file '%s', exiting.\n", output_file);
		} else if (res == E_IO_WRITE) {
			printf("Error: not all words written, output file '%s' is broken.\n", output_file);
		} else {
			printf("Unknown error during image write\n");
		}
	} else {
		printf("Written %i words to '%s'.\n", res, output_file);
	}

	// write preprocessor output
	if (preprocessor) {
		char *pp_file = malloc(strlen(output_file)+10);
		sprintf(pp_file, "%s.pp.asm", output_file);
		printf("Writing preprocessor output to %s\n", pp_file);
		FILE *ppf = fopen(pp_file, "w");
		if (!ppf) {
			printf("Cannot open preprocessor output file '%s' for writing, sorry.\n", pp_file);
		}
		preprocess(program, ppf);
		fclose(ppf);
		free(pp_file);
	}

	if (dump_labels) {
		char *lab_file = malloc(strlen(output_file)+10);
		sprintf(lab_file, "%s.lab", output_file);
		printf("Writing labels to %s\n", lab_file);
		FILE *labf = fopen(lab_file, "w");
		if (!labf) {
			printf("Cannot open labels file '%s' for writing, sorry.\n", lab_file);
		}
		write_labels(labf);
		fclose(labf);
		free(lab_file);
	}

	free(output_file);
	nodelist_drop(program);
	labels_drop();

	return 0;
}
Beispiel #19
0
/**
 * @brief jv3_write_sector - JV3 format write sector function
 *
 * This assumes the JV3 image type.
 */
static int jv3_write_sector(struct img_s *img, uint32_t head, uint32_t sec,
	void *buff, size_t size, uint32_t den, uint32_t ddam)
{
	jv3_t *jv3;
	jv3_track_t *tp;
	jv3_dam_t *dp;
	uint32_t drive, cyl;
	off_t offs;
	uint8_t n[1];
	uint32_t i;

	if (0 != jv3_setup(img, &jv3))
		return -1;

	drive = img_minor(img);
	cyl = img_get_flag(img, DRV_CURRENT_CYLINDER);

	if (cyl >= jv3->cylinders)
		return -1;
	if (head >= jv3->heads)
		return -1;

	tp = &jv3->track[cyl][head];
	for (i = 0; i < tp->sectors; i++)
		if (tp->sector[i].r == sec)
			break;
	/* record not found? */
	if (i >= tp->sectors) {
		LOG((1,"JV3","#%x/%cD write sector %02x not found SPT:%02x\n",
			drive, DEN_FM_LO == den ? 'S' : 'D',
			sec, tp->sectors));
		return -1;
	}
	dp = &tp->sector[i];

	LOG((1,"JV3","#%x/%cD write C:%02x H:%x R:%02x N:%02x SPT:%02x\n",
		drive, DEN_FM_LO == den ? 'S' : 'D',
		dp->c, dp->h, dp->r, dp->n & 0x03, tp->sectors));

	dp->n &= ~JV3_DAM_MASK;
	switch (den) {
	case DEN_FM_LO:
		if (ddam)
			dp->n |= JV3_DAM_SD_DEL;
		else
			dp->n |= JV3_DAM_SD_STD;
		break;
	case DEN_MFM_LO:
		if (ddam)
			dp->n |= JV3_DAM_DD_DEL;
		else
			dp->n |= JV3_DAM_DD_STD;
		break;
	}
	/* write the (new) flag for this sector */
	n[0] = dp->n ^ 1;
	img_write(img, dp->oflg, n, 1);

	offs = dp->offs;

	if (size <= dp->size) {
		if (size == img_write(img, offs, buff, size))
			return 0;
	} else {
		if (size == img_write(img, offs, buff, dp->size))
			return 0;
	}

	return -1;
}
Beispiel #20
0
/**
 * @brief dmk_write_track - DMK format write track function
 *
 * This function writes an entire track from the track buffer.
 */
static int dmk_write_track(struct img_s *img, uint32_t cyl, uint32_t head,
	void *buff, size_t size, uint32_t den)
{
	uint32_t cyllen, dd, dp, d0, ip, c, h, r, n, crc;
	uint8_t *src;
	dmk_t *dmk;
	int state;

	if (0 != dmk_setup(img, &dmk))
		return -1;

	cyllen = dmk->cyllen[0] + 256 * dmk->cyllen[1];

	if (cyl >= dmk->cylinders) {
		dmk->cylinders = cyl + 1;
		memset(dmk->rsvd, 0x00, sizeof(dmk->rsvd));
		img_write(img, 0, dmk, DMK_HEADER_SIZE);
		memset(dmk->rsvd, 0xff, sizeof(dmk->rsvd));
		img_set_flag(img, DRV_TOTAL_CYLINDERS, dmk->cylinders);
		img_set_flag(img, DRV_CURRENT_CYLINDER, cyl);
	}

	/* zap idam and track before trying to read it from the image */
	memset(dmk->track, 0xff, cyllen);
	memset(dmk->track, 0x00, DMK_IDAM_SIZE);

	src = buff;
	state = 0;
	dd = DEN_FM_LO == den ? 0 : DMK_IDAM_DDEN;
	ip = 0;			/* idam pointer */
	dp = DMK_IDAM_SIZE;	/* data pointer */
	d0 = 0;			/* data pointer of current 0xfe */
	c = h = r = n = 0;
	crc = 0xffff;
	while (dp < cyllen && size > 0) {
		dmk->track[dp] = *src;
		switch (state) {
		case 0:	/* looking for address mark (0xfe) */
			switch (*src) {
			case 0xf5:	/* DD reset CRC */
				dmk->track[dp] = 0xa1;
				break;
			case 0xfe:	/* address mark */
				crc = 0xffff;
				if (DEN_FM_LO != den) {
					crc = calc_crc(crc, 0xa1);
					crc = calc_crc(crc, 0xa1);
					crc = calc_crc(crc, 0xa1);
				}
				crc = calc_crc(crc, *src);
				d0 = dp;
				state++;
				break;
			}
			break;
		case 1:	/* get track number */
			c = *src;
			crc = calc_crc(crc, c);
			state++;
			break;
		case 2:	/* get head number */
			h = *src;
			crc = calc_crc(crc, h);
			state++;
			break;
		case 3:	/* get sector number */
			r = *src;
			crc = calc_crc(crc, r);
			state++;
			break;
		case 4:	/* get sector length code */
			n = *src;
			crc = calc_crc(crc, n);
			state++;
			n = 1 << (n & 3);
			break;
		case 5:	/* write address mark CRC high byte */
			if (0xf7 == *src) {
				dmk->track[dp] = crc / 256;
				state++;
				src--;
				size++;
			}
			break;
		case 6:	/* write address mark CRC low byte */
			dmk->track[dp] = crc % 256;
			state++;
			break;
		case 7:	/* now look for a data address mark (0xf8-0xfb) */
			switch (*src) {
			case 0xf5:	/* DD reset CRC */
				dmk->track[dp] = 0xa1;
				break;
			case 0xf8:
			case 0xf9:
			case 0xfa:
			case 0xfb:
				crc = 0xffff;
				if (DEN_FM_LO != den) {
					crc = calc_crc(crc, 0xa1);
					crc = calc_crc(crc, 0xa1);
					crc = calc_crc(crc, 0xa1);
				}
				crc = calc_crc(crc, *src);
				state++;
				break;
			}
			break;
		case 8:	/* skip sector data */
			crc = calc_crc(crc, *src);
			if (0 == --n)
				state++;
			break;
		case 9:	/* write data CRC high byte */
			if (0xf7 == *src) {
				dmk->track[dp] = crc / 256;
				state++;
				src--;
				size++;
			}
			break;
		case 10:/* write data CRC low byte */
			dmk->track[dp] = crc % 256;
			state++;
			break;
		case 11:/* look for next sector */
			d0 |= dd;
			dmk->track[ip+0] = d0 % 256;
			dmk->track[ip+1] = d0 / 256;
			ip += 2;
			/* abort if idam size reached */
			if (ip >= DMK_IDAM_SIZE)
				size = 1;
			state = 0;
			break;
		}
		size--;
		src++;
		dp++;
		if (0 == dd && 0 == (dmk->flags & DMK_FLAG_SD1BYTE)) {
			if (dp < cyllen) {
				/* duplicate byte for single density */
				dmk->track[dp] = dmk->track[dp-1];
				dp++;
			}
		}
	}

	/* pad track with 0xff to cyllen */
	while (dp < cyllen)
		dmk->track[dp++] = 0xff;

	if (0 != dmk_put_track(img, dmk, cyl, head))
		return -1;

#if	DMK_CACHE_TRACK
	dmk->rsvd[DMK_TRACK_BUFF] = cyl;
	dmk->rsvd[DMK_SIDE_BUFF] = head;
#endif
	return 0;
}