/**
 * Updates the sensor by reading the current value into it
 */
static void update(CAMERA_STATE *camera, struct sensor *sensor) {
    if (!sensor->enabled)
        return;

    struct state *state = (struct state *) sensor;

    if (!state->loader)
        state->loader = exif_loader_new();

    exif_loader_reset(state->loader);
    exif_loader_write(state->loader, camera->imagedata.buffer, camera->imagedata.pos);
    ExifData *data = exif_loader_get_data(state->loader);
    ExifByteOrder bo = exif_data_get_byte_order(data);

    int valid = get_shutter_speed(data, bo, &state->shutter_speed);

    if (valid)
        valid = get_aperture(data, bo, &state->aperture);

    if (valid)
        valid = getDouble(data, bo, EXIF_TAG_ISO_SPEED_RATINGS, &state->iso);

    exif_data_free(data);

    if (valid) {
        // Calculate the light level
        state->light_level = (2.0 * log(state->aperture) - log(state->shutter_speed) - log(state->iso / 100.0)) / log(2.0);

        // Update the sensor
        sensor_log(camera, &state->sensor, (int) (state->light_level * 1000), "Lvl %.1f", state->light_level);
    }
}
Example #2
0
static void
exif_loader_free (ExifLoader *loader)
{
	ExifMem *mem;

	if (!loader)
		return;

	mem = loader->mem;
	exif_loader_reset (loader);
	exif_mem_free (mem, loader);
	exif_mem_unref (mem);
}
Example #3
0
unsigned char
exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
{
	unsigned int i;

	if (!eld || (len && !buf)) 
		return 0;

	switch (eld->state) {
	case EL_EXIF_FOUND:
		return exif_loader_copy (eld, buf, len);
	case EL_SKIP_BYTES:
		if (eld->size > len) { 
			eld->size -= len; 
			return 1; 
		}
		len -= eld->size;
		buf += eld->size;
		eld->size = 0;
		eld->b_len = 0;
		switch (eld->data_format) {
		case EL_DATA_FORMAT_FUJI_RAW:
			eld->state = EL_READ_SIZE_BYTE_24;
			break;
		default:
			eld->state = EL_READ;
			break;
		}
		break;

	case EL_READ:
	default:
		break;
	}

	if (!len)
		return 1;
	exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
		  "Scanning %i byte(s) of data...", len);

	/*
	 * First fill the small buffer. Only continue if the buffer
	 * is filled. Note that EXIF data contains at least 12 bytes.
	 */
	i = MIN (len, sizeof (eld->b) - eld->b_len);
	if (i) {
		memcpy (&eld->b[eld->b_len], buf, i);
		eld->b_len += i;
		if (eld->b_len < sizeof (eld->b)) 
			return 1;
		buf += i;
		len -= i;
	}

	switch (eld->data_format) {
	case EL_DATA_FORMAT_UNKNOWN:

		/* Check the small buffer against known formats. */
		if (!memcmp (eld->b, "FUJIFILM", 8)) {

			/* Skip to byte 84. There is another offset there. */
			eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
			eld->size = 84;
			eld->state = EL_SKIP_BYTES;
			eld->size = 84;

		} else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {

			/* Read the size (2 bytes). */
			eld->data_format = EL_DATA_FORMAT_EXIF;
			eld->state = EL_READ_SIZE_BYTE_08;
		}
	default:
		break;
	}

	for (i = 0; i < sizeof (eld->b); i++)
		switch (eld->state) {
		case EL_EXIF_FOUND:
			if (!exif_loader_copy (eld, eld->b + i,
					sizeof (eld->b) - i)) 
				return 0;
			return exif_loader_copy (eld, buf, len);
		case EL_SKIP_BYTES:
			eld->size--;
			if (!eld->size) 
				eld->state = EL_READ;
			break;

		case EL_READ_SIZE_BYTE_24:
			eld->size |= eld->b[i] << 24;
			eld->state = EL_READ_SIZE_BYTE_16;
			break;
		case EL_READ_SIZE_BYTE_16:
			eld->size |= eld->b[i] << 16;
			eld->state = EL_READ_SIZE_BYTE_08;
			break;
		case EL_READ_SIZE_BYTE_08:
			eld->size |= eld->b[i] << 8;
			eld->state = EL_READ_SIZE_BYTE_00;
			break;
		case EL_READ_SIZE_BYTE_00:
			eld->size |= eld->b[i] << 0;
			switch (eld->data_format) {
			case EL_DATA_FORMAT_JPEG:
				eld->state = EL_SKIP_BYTES;
				eld->size -= 2;
				break;
			case EL_DATA_FORMAT_FUJI_RAW:
				eld->data_format = EL_DATA_FORMAT_EXIF;
				eld->state = EL_SKIP_BYTES;
				eld->size -= 86;
				break;
			case EL_DATA_FORMAT_EXIF:
				eld->state = EL_EXIF_FOUND;
				break;
			default:
				break;
			}
			break;

		default:
			switch (eld->b[i]) {
			case JPEG_MARKER_APP1:
			  if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) {
					eld->data_format = EL_DATA_FORMAT_EXIF;
				} else {
					eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
				}
				eld->size = 0;
				eld->state = EL_READ_SIZE_BYTE_08;
				break;
			case JPEG_MARKER_DHT:
			case JPEG_MARKER_DQT:
			case JPEG_MARKER_APP0:
			case JPEG_MARKER_APP2:
			case JPEG_MARKER_APP13:
			case JPEG_MARKER_COM:
				eld->data_format = EL_DATA_FORMAT_JPEG;
				eld->size = 0;
				eld->state = EL_READ_SIZE_BYTE_08;
				break;
			case 0xff:
			case JPEG_MARKER_SOI:
				break;
			default:
				exif_log (eld->log,
					EXIF_LOG_CODE_CORRUPT_DATA,
					"ExifLoader", _("The data supplied "
						"does not seem to contain "
						"EXIF data."));
				exif_loader_reset (eld);
				return 0;
			}
		}

	/*
	 * If we reach this point, the buffer has not been big enough
	 * to read all data we need. Fill it with new data.
	 */
	eld->b_len = 0;
	return exif_loader_write (eld, buf, len);
}