Example #1
0
/* read a stream of cells
 * RgetSomeCells views a raster as one linear stream of
 * cells, with row i+1 placed after row i. 
 * In this stream any sequence can be read by specifying an
 * offset and the number of cells to be read
 * returns the number of cells read, just as fread
 *
 * example
 * .so examples/somecell.tr
 */
size_t RgetSomeCells(
	MAP *map,	/* map handle */
	size_t offset,   /* offset from pixel (row,col) = (0,0) */
	size_t nrCells,  /* number of cells to be read */
	void *buf)/* write-only. Buffer large enough to
                   * hold nrCells cells in the in-file cell representation
                   * or the in-app cell representation.
                   */
{

	CSF_FADDR  readAt;
	size_t cellsRead;
	UINT2  inFileCR = RgetCellRepr(map);

	offset <<= LOG_CELLSIZE(inFileCR);
	readAt = ADDR_DATA + (CSF_FADDR)offset;
	fseek(map->fp, (long)readAt, SEEK_SET);
	cellsRead = map->read(buf, (size_t)CELLSIZE(inFileCR),
	(size_t)nrCells, map->fp);

	PRECOND(map->file2app != NULL);
	map->file2app(nrCells, buf);

	return(cellsRead);
}
Example #2
0
/* write a stream of cells
 * RputSomeCells views a raster as one linear stream of
 * cells, with row i+1 placed after row i. 
 * In this stream any sequence can be written by specifying an
 * offset and the number of cells to be written
 * returns the number of cells written, just as fwrite
 *
 * example
 * .so examples/somecell.tr
 */
size_t RputSomeCells(
	MAP *map,	/* map handle */
	size_t offset,   /* offset from pixel (row,col) = (0,0) */
	size_t nrCells,  /* number of cells to be read */
	void *buf)/* read-write. Buffer large enough to
                   * hold nrCells cells in the in-file cell representation
                   * or the in-app cell representation.
                   * If these types are not equal then the buffer is
                   * converted from the in-app to the in-file 
                   * cell representation. 
                   */
{
	CSF_FADDR  writeAt;
	CSF_CR  cr = map->raster.cellRepr;

	/* convert */
	map->app2file(nrCells, buf);
	

	if (map->minMaxStatus == MM_KEEPTRACK)
	{
		const DF  detMinMaxFunc[12] = {
			 (DF)DetMinMaxUINT1, (DF)DetMinMaxUINT2, 
			 (DF)DetMinMaxUINT4, NULL /* 0x03  */  ,
			 (DF)DetMinMaxINT1 , (DF)DetMinMaxINT2 , 
			 (DF)DetMinMaxINT4 , NULL /* 0x07  */  ,
			 NULL /* 0x08 */   , NULL /* 0x09 */   , 
			 (DF)DetMinMaxREAL4, (DF)DetMinMaxREAL8 };

		void *min = &(map->raster.minVal);
		void *max = &(map->raster.maxVal);

		PRECOND(CSF_UNIQ_CR_MASK(cr) < 12);
		PRECOND(detMinMaxFunc[CSF_UNIQ_CR_MASK(cr)] != NULL);

		detMinMaxFunc[CSF_UNIQ_CR_MASK(cr)](min, max, nrCells, buf);
		
	}
	else
		map->minMaxStatus = MM_WRONGVALUE;

	writeAt  = ((CSF_FADDR)offset) << LOG_CELLSIZE(cr);
	writeAt += ADDR_DATA;
	if( csf_fseek(map->fp, writeAt, SEEK_SET) != 0 )
            return 0;
	return(map->write(buf, (size_t)CELLSIZE(cr), (size_t)nrCells, map->fp));
}
Example #3
0
/* seek to space for attribute  (LIBRARY_INTERNAL)
 * CsfSeekAttrSpace seeks to the a point in the file where
 * the attribute must be stored and update the attribute control
 * blocks accordingly.
 * Writing can still fail since there is no check if that space is really
 * avalaible on the device. After this call returns the file is already
 * seeked to the point the functions returns.
 * returns the file position or 0 in case of error.
 *
 * Merrno
 * ATTRDUPL
 * NOACCESS
 * WRITE_ERROR
 */
CSF_FADDR32 CsfSeekAttrSpace(
	MAP *m,       		/* map handle */
	CSF_ATTR_ID id,               /* attribute identification only for check if avalaible */
	size_t size)            /* size to be seeked to */
{
	ATTR_CNTRL_BLOCK b;
	CSF_FADDR32 currBlockPos, prevBlockPos=USED_UNINIT_ZERO, newPos, endBlock, resultPos=0;
	int noPosFound;
	int i;

	if (MattributeAvail(m ,id))
	{
		M_ERROR(ATTRDUPL);
		goto error;
	}

	if (! WRITE_ENABLE(m))
	{
		M_ERROR(NOACCESS);
		goto error;
	}

	currBlockPos = m->main.attrTable;
        noPosFound = 1;
	while (noPosFound)
	{
		if (currBlockPos == 0)
		{
			if (m->main.attrTable == 0)
			{ /* FIRST BLOCK */
				newPos =( (CSF_FADDR)(m->raster.nrRows)*
					   (CSF_FADDR)(m->raster.nrCols)*
					  (CSF_FADDR)(CELLSIZE(RgetCellRepr(m))))
					  + ADDR_DATA;
				m->main.attrTable = newPos;
			}
			else
			{ /* NEW/NEXT BLOCK */
				newPos = b.attrs[LAST_ATTR_IN_BLOCK].attrOffset
					+
					b.attrs[LAST_ATTR_IN_BLOCK].attrSize;
				b.next = newPos;
				if (CsfWriteAttrBlock(m, prevBlockPos, &b))
				{
					M_ERROR(WRITE_ERROR);
					resultPos = 0;
				}
			}
			InitBlock(&b);
			b.attrs[0].attrOffset =
				newPos + SIZE_OF_ATTR_CNTRL_BLOCK;
			currBlockPos = newPos;
			noPosFound = 0;
		}
		else
			CsfReadAttrBlock(m, currBlockPos, &b);
		i = 0; /* this is also the right index if a new block
			   is added ! */
		while (noPosFound  && i < NR_ATTR_IN_BLOCK)
			switch (b.attrs[i].attrId)
			{
				case END_OF_ATTRS:
					POSTCOND(i >= 1);
					/* i >= 1 , no block otherwise */
					b.attrs[i].attrOffset =
						b.attrs[i-1].attrOffset  +
						b.attrs[i-1].attrSize;
					noPosFound = 0;
                                        break;
				case ATTR_NOT_USED:
					if (i == NR_ATTR_IN_BLOCK)
						endBlock = b.next;
					else
						endBlock = b.attrs[i+1].attrOffset;
					if ( (size_t)( endBlock - b.attrs[i].attrOffset) >= size)
						/* this position can
							hold the attr */
						noPosFound = 0;
                                        else
                                            i++;
                                        break;
				 default:
                                            i++;
			} /* switch */
/*		if (b.next == 0)
                     ? When did I change this CW
		       remember this block position since it may be have
		       to rewritten
*/
		prevBlockPos = currBlockPos;
		if (noPosFound)
			currBlockPos = b.next;
 	} /* while */

	b.attrs[i].attrSize = size;
	b.attrs[i].attrId   = id;
	resultPos = b.attrs[i].attrOffset;

	if (CsfWriteAttrBlock(m, currBlockPos, &b))
	{
		M_ERROR(WRITE_ERROR);
		resultPos = 0;
	}
	fseek(m->fp, (long)resultPos, SEEK_SET); /* fsetpos() is better */
error:	return resultPos;
} /* CsfSeekAttrSpace */