⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exif.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (format_raw_img_exif_offsets(f, size, NULL, &offset))			{			res = exif_tiff_parse(exif, (unsigned char*)f + offset, size - offset, ExifKnownMarkersList);			}		}	if (res != 0)		{		exif_free(exif);		exif = NULL;		}	unmap_file(f, size);	if (exif) exif->items = g_list_reverse(exif->items);#if 0	exif_write_data_list(exif, stdout, TRUE);	exif_write_data_list(exif, stdout, FALSE);#endif	return exif;}ExifItem *exif_get_item(ExifData *exif, const gchar *key){	GList *work;	if (!key) return NULL;	work = exif->items;	while (work) 		{		ExifItem *item;		item = work->data;		work = work->next;		if (item->marker->key && strcmp(key, item->marker->key) == 0) return item;                }	return NULL;}gchar *exif_item_get_data_as_text(ExifItem *item){	const ExifMarker *marker;	gpointer data;	GString *string;	gchar *text;	gint ne;	gint i;	if (!item) return NULL;	marker = item->marker;	if (!marker) return NULL;	data = item->data;	ne = item->elements;	string = g_string_new("");	switch (item->format)		{		case EXIF_FORMAT_UNKNOWN:			break;		case EXIF_FORMAT_BYTE_UNSIGNED:		case EXIF_FORMAT_BYTE:		case EXIF_FORMAT_UNDEFINED:			if (ne == 1 && marker->list)				{				gchar *result;				unsigned char val;				if (item->format == EXIF_FORMAT_BYTE_UNSIGNED ||				    item->format == EXIF_FORMAT_UNDEFINED)					{					val = ((unsigned char *)data)[0];					}				else					{					val = (unsigned char)(((signed char *)data)[0]);					}				result = exif_text_list_find_value(marker->list, (guint)val);				string = g_string_append(string, result);				g_free(result);				}			else				{				string = string_append_raw_bytes(string, data, ne);				}			break;		case EXIF_FORMAT_STRING:			string = g_string_append(string, (gchar *)(item->data));			break;		case EXIF_FORMAT_SHORT_UNSIGNED:			if (ne == 1 && marker->list)				{				gchar *result;				result = exif_text_list_find_value(marker->list, ((unsigned short *)data)[0]);				string = g_string_append(string, result);				g_free(result);				}			else for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "",							((unsigned short *)data)[i]);				}			break;		case EXIF_FORMAT_LONG_UNSIGNED:			for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "",							((unsigned long *)data)[i]);				}			break;		case EXIF_FORMAT_RATIONAL_UNSIGNED:			for (i = 0; i < ne; i++)				{				ExifRational *r;				r = &((ExifRational *)data)[i];				g_string_append_printf(string, "%s%ld/%ld", (i > 0) ? ", " : "",							(unsigned long)r->num, (unsigned long)r->den);				}			break;		case EXIF_FORMAT_SHORT:			for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "",							((short *)data)[i]);				}			break;		case EXIF_FORMAT_LONG:			for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "",							((long *)data)[i]);				}			break;		case EXIF_FORMAT_RATIONAL:			for (i = 0; i < ne; i++)				{				ExifRational *r;				r = &((ExifRational *)data)[i];				g_string_append_printf(string, "%s%ld/%ld", (i > 0) ? ", " : "",							(long)r->num, (long)r->den);				}			break;		case EXIF_FORMAT_FLOAT:			for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%f", (i > 0) ? ", " : "",							((float *)data)[i]);				}			break;		case EXIF_FORMAT_DOUBLE:			for (i = 0; i < ne; i++)				{				g_string_append_printf(string, "%s%f", (i > 0) ? ", " : "",							((double *)data)[i]);				}			break;		}	text = g_strdup(string->str);	g_string_free(string, TRUE);	return text;}gint exif_item_get_integer(ExifItem *item, gint *value){	if (!item) return FALSE;	switch (item->format)		{		case EXIF_FORMAT_SHORT:			*value = (gint)(((short *)(item->data))[0]);			return TRUE;			break;		case EXIF_FORMAT_SHORT_UNSIGNED:			*value = (gint)(((unsigned short *)(item->data))[0]);			return TRUE;			break;		case EXIF_FORMAT_LONG:			*value = (gint)(((long *)(item->data))[0]);			return TRUE;			break;		case EXIF_FORMAT_LONG_UNSIGNED:			/* FIXME: overflow possible */			*value = (gint)(((unsigned long *)(item->data))[0]);			return TRUE;		default:			/* all other type return FALSE */			break;		}	return FALSE;}gint exif_get_integer(ExifData *exif, const gchar *key, gint *value){	ExifItem *item;	item = exif_get_item(exif, key);	return exif_item_get_integer(item, value);}ExifRational *exif_item_get_rational(ExifItem *item, gint *sign){	if (!item) return NULL;	if (item->format == EXIF_FORMAT_RATIONAL ||	    item->format == EXIF_FORMAT_RATIONAL_UNSIGNED)		{		if (sign) *sign = (item->format == EXIF_FORMAT_RATIONAL);		return &((ExifRational *)(item->data))[0];		}	return NULL;}ExifRational *exif_get_rational(ExifData *exif, const gchar *key, gint *sign){	ExifItem *item;	item = exif_get_item(exif, key);	return exif_item_get_rational(item, sign);}double exif_rational_to_double(ExifRational *r, gint sign){	if (!r || r->den == 0.0) return 0.0;	if (sign) return (double)((int)r->num) / (double)((int)r->den);	return (double)r->num / r->den;}static double exif_get_rational_as_double(ExifData *exif, const gchar *key){	ExifRational *r;	gint sign;	r = exif_get_rational(exif, key, &sign);	return exif_rational_to_double(r, sign);}static GString *append_comma_text(GString *string, const gchar *text){	string = g_string_append(string, ", ");	string = g_string_append(string, text);	return string;}static gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_valid){	/* must begin with f, else not formatted */	if (key[0] != 'f')		{		if (key_valid) *key_valid = FALSE;		return NULL;		}	if (key_valid) *key_valid = TRUE;	if (strcmp(key, "fCamera") == 0)		{		gchar *text;		gchar *make = exif_get_data_as_text(exif, "Make");		gchar *model = exif_get_data_as_text(exif, "Model");		gchar *software = exif_get_data_as_text(exif, "Software");		text = g_strdup_printf("%s%s%s%s%s%s", (make) ? make : "", ((make) && (model)) ? " " : "",						       (model) ? model : "",						       (software) ? " (" : "",						       (software) ? software : "",						       (software) ? ")" : "");		g_free(make);		g_free(model);		g_free(software);		return text;		}	if (strcmp(key, "fDateTime") == 0)		{		gchar *text = exif_get_data_as_text(exif, "DateTimeOriginal");		gchar *subsec = NULL;		if (text) subsec = exif_get_data_as_text(exif, "SubsecTimeOriginal");		if (!text)			{			text = exif_get_data_as_text(exif, "DateTime");			if (text) subsec = exif_get_data_as_text(exif, "SubsecTime");			}		if (subsec)			{			gchar *tmp = text;			text = g_strconcat(tmp, ".", subsec, NULL);			g_free(tmp);			g_free(subsec);			}		return text;		}	if (strcmp(key, "fShutterSpeed") == 0)		{		ExifRational *r;		r = exif_get_rational(exif, "ExposureTime", NULL);		if (r && r->num && r->den)			{			double n = (double)r->den / (double)r->num;			return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",							  n > 1.0 ? n : 1.0 / n);			}		r = exif_get_rational(exif, "ShutterSpeedValue", NULL);		if (r && r->num  && r->den)			{			double n = pow(2.0, exif_rational_to_double(r, TRUE));			/* Correct exposure time to avoid values like 1/91s (seen on Minolta DImage 7) */			if (n > 1.0 && (int)n - ((int)(n/10))*10 == 1) n--;			return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",							  n > 1.0 ? floor(n) : 1.0 / n);				}		return NULL;		}	if (strcmp(key, "fAperture") == 0)		{		double n;		n = exif_get_rational_as_double(exif, "FNumber");		if (n == 0.0) n = exif_get_rational_as_double(exif, "ApertureValue");		if (n == 0.0) return NULL;		return g_strdup_printf("f/%.1f", n);		}	if (strcmp(key, "fExposureBias") == 0)		{		ExifRational *r;		gint sign;		double n;		r = exif_get_rational(exif, "ExposureBiasValue", &sign);		if (!r) return NULL;		n = exif_rational_to_double(r, sign);		return g_strdup_printf("%+.1f", n);		}	if (strcmp(key, "fFocalLength") == 0)		{		double n;		n = exif_get_rational_as_double(exif, "FocalLength");		if (n == 0.0) return NULL;		return g_strdup_printf("%.2f mm", n);		}	if (strcmp(key, "fISOSpeedRating") == 0)		{		gchar *text;		text = exif_get_data_as_text(exif, "ISOSpeedRatings");		/* kodak may set this instead */		if (!text) text = exif_get_data_as_text(exif, "ExposureIndex");		return text;		}	if (strcmp(key, "fSubjectDistance") == 0)		{		ExifRational *r;		gint sign;		double n;		r = exif_get_rational(exif, "SubjectDistance", &sign);		if (!r) return NULL;		if ((long)r->num == 0xffffffff) return g_strdup(_("infinity"));		if ((long)r->num == 0) return g_strdup(_("unknown"));		n = exif_rational_to_double(r, sign);		if (n == 0.0) return _("unknown");		return g_strdup_printf("%.3f m", n);		}	if (strcmp(key, "fFlash") == 0)		{		/* grr, flash is a bitmask... */		GString *string;		gchar *text;		gint n;		gint v;		if (!exif_get_integer(exif, "Flash", &n)) return NULL;		/* Exif 2.1 only defines first 3 bits */		if (n <= 0x07) return exif_text_list_find_value(ExifFlashList, n);		/* must be Exif 2.2 */		string = g_string_new("");		/* flash fired (bit 0) */		string = g_string_append(string, (n & 0x01) ? _("yes") : _("no"));		/* flash mode (bits 3, 4) */		v = (n >> 3) & 0x03;		if (v) string = append_comma_text(string, _("mode:"));		switch (v)			{			case 1:				string = g_string_append(string, _("on"));				break;			case 2:				string = g_string_append(string, _("off"));				break;			case 3:				string = g_string_append(string, _("auto"));				break;			}		/* return light (bits 1, 2) */		v = (n >> 1) & 0x03;		if (v == 2) string = append_comma_text(string, _("not detected by strobe"));		if (v == 3) string = append_comma_text(string, _("detected by strobe"));		/* we ignore flash function (bit 5) */		/* red-eye (bit 6) */		if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction"));		text = string->str;		g_string_free(string, FALSE);		return text;		}	if (strcmp(key, "fResolution") == 0)		{		ExifRational *rx, *ry;		gchar *units;		gchar *text;		rx = exif_get_rational(exif, "XResolution", NULL);		ry = exif_get_rational(exif, "YResolution", NULL);		if (!rx || !ry) return NULL;		units = exif_get_data_as_text(exif, "ResolutionUnit");		text = g_strdup_printf("%0.f x %0.f (%s/%s)", rx->den ? (double)rx->num / rx->den : 1.0,							      ry->den ? (double)ry->num / ry->den : 1.0,							      _("dot"), (units) ? units : _("unknown"));		g_free(units);		return text;		}	if (key_valid) *key_valid = FALSE;	return NULL;}gchar *exif_get_data_as_text(ExifData *exif, const gchar *key){	ExifItem *item;	gchar *text;	gint key_valid;	if (!key) return NULL;	text = exif_get_formatted_by_key(exif, key, &key_valid);	if (key_valid) return text;	item = exif_get_item(exif, key);	if (item) return exif_item_get_data_as_text(item);	return NULL;}const gchar *exif_get_description_by_key(const gchar *key){	gint i;	if (!key) return NULL;	i = 0;	while (ExifFormattedList[i].key != NULL)		{		if (strcmp(key, ExifFormattedList[i].key) == 0) return _(ExifFormattedList[i].description);		i++;		}	i = 0;	while (ExifKnownMarkersList[i].tag > 0)		{		if (strcmp(key, ExifKnownMarkersList[i].key) == 0) return _(ExifKnownMarkersList[i].description);		i++;		}	return NULL;}static void exif_write_item(FILE *f, ExifItem *item){	gchar *text;	text = exif_item_get_data_as_text(item);	if (text)		{		fprintf(f, "%4x %9s %30s %s\n", item->tag, ExifFormatList[item->format].short_name,			exif_item_get_tag_name(item), text);		}	g_free(text);}void exif_write_data_list(ExifData *exif, FILE *f, gint human_readable_list){	if (!f || !exif) return;	fprintf(f, " tag   format                             key value\n");	fprintf(f, "----------------------------------------------------\n");	if (human_readable_list)		{		gint i;		i = 0;		while (ExifFormattedList[i].key)			{			gchar *text;			text = exif_get_formatted_by_key(exif, ExifFormattedList[i].key, NULL);			if (text)				{				fprintf(f, "     %9s %30s %s\n", "string", ExifFormattedList[i].key, text);				}			i++;			}		}	else		{		GList *work;		work = exif->items;		while (work)			{			ExifItem *item;			item = work->data;			work = work->next;			exif_write_item(f, item);			}		}	fprintf(f, "----------------------------------------------------\n");}

⌨️ 快捷键说明

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