legend.c

来自「支持各种栅格图像和矢量图像读取的库」· C语言 代码 · 共 135 行

C
135
字号
/* * legend.c  */#include "csf.h"#include "csfimpl.h"/* get the number of entries with a negative * number for a type 1 legend */static int NrLegendEntries(MAP *m){	int size = CsfAttributeSize(m, ATTR_ID_LEGEND_V2);	if (size == 0)	{		if ( (size = -CsfAttributeSize(m, ATTR_ID_LEGEND_V1)) != 0 )			size -= CSF_LEGEND_ENTRY_SIZE;	}	return size/CSF_LEGEND_ENTRY_SIZE;}static int CmpEntries(	CSF_LEGEND *e1,	CSF_LEGEND *e2){	return (int) ((e1->nr) - (e2->nr));}static void SortEntries(	CSF_LEGEND *l, /* version 2 legend */	size_t        nr) /* nr entries + name */{#ifndef USE_IN_PCR	typedef int (*QSORT_CMP)(const void *e1, const void *e2);#endif	PRECOND(nr >= 1);	qsort(l+1, (size_t)nr-1, sizeof(CSF_LEGEND), (QSORT_CMP)CmpEntries);}/* get the number of legend entries * MgetNrLegendEntries tries to find a version 2 or version 1 * legend. The return number can be used to allocate the appropriate * array for legend.  * returns the number of entries in a legend plus 1 (for the name of the legend) * or 0 if there is no legend */size_t MgetNrLegendEntries(	MAP *m) /* the map pointer */{	return (size_t)ABS(NrLegendEntries(m));}/* read a legend * MgetLegend reads a version 2 and 1 legend. * Version 1 legend are converted to version 2: the first * array entry holds an empty string in the description field. * returns  * 0 if no legend is available or in case of an error, * nonzero otherwise */int MgetLegend(	MAP *m,        /* Map handle */	CSF_LEGEND *l) /* array large enough to hold name and all entries, 	                * the entries are sorted 	                * struct CSF_LEGEND is typedef'ed in csfattr.h	                */{	CSF_ATTR_ID id = NrLegendEntries(m) < 0 ? ATTR_ID_LEGEND_V1 : ATTR_ID_LEGEND_V2;	size_t size;	CSF_FADDR pos = CsfGetAttrPosSize(m, id, &size);	size_t i,nr,start = 0;        if (pos == 0)        	return 0;        fseek(m->fp, (long)pos, SEEK_SET);        if (id == ATTR_ID_LEGEND_V1)        {         	/* empty name */        	l[0].nr       = 0;        	l[0].descr[0] = '\0';        	start = 1; /* don't read in name */        }	nr = size/CSF_LEGEND_ENTRY_SIZE;	for(i = start; i < nr+start; i++)	{		m->read(&(l[i].nr), sizeof(INT4), (size_t)1, m->fp);		m->read(l[i].descr, sizeof(char), (size_t)CSF_LEGEND_DESCR_SIZE, m->fp);	}	SortEntries(l, nr+start);	return 1;}/* write a legend * MputLegend writes a (version 2) legend to a map replacing * the old one if existent. * See  csfattr.h for the legend structure. * * returns  * 0 in case of an error, * nonzero otherwise * * Merrno * NOACCESS * WRITE_ERROR */int MputLegend(	MAP *m,        /* Map handle */	CSF_LEGEND *l, /* read-write, array with name and entries, the entries	                * are sorted before writing to the file.	                * Strings are padded with zeros.	                */	size_t nrEntries) /* number of array elements. That is name plus real legend entries */{	int i = NrLegendEntries(m);	CSF_ATTR_ID id = i < 0 ? ATTR_ID_LEGEND_V1 : ATTR_ID_LEGEND_V2;	if (i)		if (! MdelAttribute(m, id))			return 0;	SortEntries(l, nrEntries);	if (CsfSeekAttrSpace(m, ATTR_ID_LEGEND_V2, (size_t)(nrEntries*CSF_LEGEND_ENTRY_SIZE)) == 0)			return 0;	for(i = 0; i < (int)nrEntries; i++)	{	     if(		m->write(&(l[i].nr), sizeof(INT4), (size_t)1, m->fp) != 1 ||		m->write(		 CsfStringPad(l[i].descr,(size_t)CSF_LEGEND_DESCR_SIZE), 		 sizeof(char), (size_t)CSF_LEGEND_DESCR_SIZE, m->fp) 		 != CSF_LEGEND_DESCR_SIZE )		 {		 	M_ERROR(WRITE_ERROR);		 	return 0;		 }	}	return 1;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?