Ejemplo n.º 1
0
void
exif_loader_write_file (ExifLoader *l, const char *path)
{
	FILE *f;
	int size;
	unsigned char data[1024];

	if (!l) 
		return;

	f = fopen (path, "rb");
	if (!f) {
		exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
			  _("The file '%s' could not be opened."), path);
		return;
	}
	while (1) {
		size = fread (data, 1, sizeof (data), f);
		if (size <= 0) 
			break;
		if (!exif_loader_write (l, data, size)) 
			break;
	}
	fclose (f);
}
/**
 * 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);
    }
}
Ejemplo n.º 3
0
static void
file_read_callback (GObject      *object,
                    GAsyncResult *res,
                    gpointer      data)
{
    CajaImagePropertiesPage *page;
    GInputStream *stream;
    gssize count_read;
    GError *error;
    int exif_still_loading;
    gboolean done_reading;

    page = CAJA_IMAGE_PROPERTIES_PAGE (data);
    stream = G_INPUT_STREAM (object);

    error = NULL;
    done_reading = FALSE;
    count_read = g_input_stream_read_finish (stream, res, &error);

    if (count_read > 0)
    {

        g_assert (count_read <= sizeof(page->details->buffer));

#ifdef HAVE_EXIF
        exif_still_loading = exif_loader_write (page->details->exifldr,
                                                page->details->buffer,
                                                count_read);
#else
        exif_still_loading = 0;
#endif /*HAVE_EXIF*/

        if (page->details->pixbuf_still_loading)
        {
            if (!gdk_pixbuf_loader_write (page->details->loader,
                                          page->details->buffer,
                                          count_read,
                                          NULL))
            {
                page->details->pixbuf_still_loading = FALSE;
            }
        }

        if (page->details->pixbuf_still_loading ||
                (exif_still_loading == 1))
        {
            g_input_stream_read_async (G_INPUT_STREAM (stream),
                                       page->details->buffer,
                                       sizeof (page->details->buffer),
                                       0,
                                       page->details->cancellable,
                                       file_read_callback,
                                       page);
        }
        else
        {
            done_reading = TRUE;
        }
    }
    else
    {
        /* either EOF, cancelled or an error occurred */
        done_reading = TRUE;
    }

    if (done_reading)
    {
        load_finished (page);
        g_input_stream_close_async (stream,
                                    0,
                                    page->details->cancellable,
                                    file_close_callback,
                                    page);
    }
}
Ejemplo n.º 4
0
static void
file_read_callback (GObject      *object,
		    GAsyncResult *res,
		    gpointer      data)
{
	NemoImagePropertiesPage *page;
	GInputStream *stream;
	gssize count_read;
	GError *error;
	int exif_still_loading;
	gboolean done_reading;

	page = NEMO_IMAGE_PROPERTIES_PAGE (data);
	stream = G_INPUT_STREAM (object);

	error = NULL;
	done_reading = FALSE;
	count_read = g_input_stream_read_finish (stream, res, &error);

	if (count_read > 0) {

		g_assert (count_read <= sizeof(page->details->buffer));

#ifdef HAVE_EXIF
		exif_still_loading = exif_loader_write (page->details->exifldr,
				  		        (guchar *) page->details->buffer,
				  			count_read);
#else
		exif_still_loading = 0;
#endif

		if (page->details->pixbuf_still_loading) {
			if (!gdk_pixbuf_loader_write (page->details->loader,
					      	      (const guchar *) page->details->buffer,
					      	      count_read,
					      	      NULL)) {
				page->details->pixbuf_still_loading = FALSE;
			}
		}

		if (page->details->pixbuf_still_loading ||
		    (exif_still_loading == 1)) {
			g_input_stream_read_async (G_INPUT_STREAM (stream),
						   page->details->buffer,
						   sizeof (page->details->buffer),
						   0,
						   page->details->cancellable,
						   file_read_callback,
						   page);
		}
		else {
			done_reading = TRUE;
		}
	}
	else {
		/* either EOF, cancelled or an error occurred */
		done_reading = TRUE;
	}

	if (error != NULL) {
		char *uri = g_file_get_uri (G_FILE (object));
		g_warning ("Error reading %s: %s", uri, error->message);
		g_free (uri);
		g_clear_error (&error);
	}

	if (done_reading) {
		load_finished (page);
		g_input_stream_close_async (stream,
					    0,
					    page->details->cancellable,
					    file_close_callback,
					    page);
	}
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
    /**
     * Module execution function. Receives a pointer to a file the module is to
     * process. The file is represented by a TskFile interface which is used
     * to read the contents of the file and post extracted EXIF data to the  
     * database.
     *
     * @param pFile A pointer to a file.
     * @returns TskModule::OK on success, TskModule::FAIL on error.
     */
    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile) 
    {
        if (pFile == NULL) 
        {
            LOGERROR(L"ExifExtractModule: passed NULL file pointer.");
            return TskModule::FAIL;
        }

        try 
        {
            char buffer[FILE_BUFFER_SIZE];
            int bytesRead = 0;

            memset(buffer, 0, FILE_BUFFER_SIZE);
            bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);

            if (bytesRead < 4)
                return TskModule::OK;

            // Check the first 4 bytes to see if this is a JPEG file.
            // We check for both the JFIF and EXIF signatures.
            if (memcmp(buffer, jfifSig, sizeof(jfifSig)) != 0 &&
                memcmp(buffer, exifSig, sizeof(exifSig)) != 0)
            {
                // It's not a JPEG file so we skip it.
                return TskModule::OK;
            }

            ExifLoader * exifLoader = exif_loader_new();

            if (exifLoader == NULL)
            {
                LOGERROR(L"ExifExtractModule - Received NULL ExifLoader pointer");
                return TskModule::FAIL;
            }

            // Feed the file content into libexif
            while (bytesRead > 0)
            {
                exif_loader_write(exifLoader, reinterpret_cast<unsigned char *>(buffer), bytesRead);
                memset(buffer, 0, FILE_BUFFER_SIZE);
                bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);
            }

            ExifData * exifData = exif_loader_get_data(exifLoader);

            // exifData will be NULL if there is no EXIF data in the image
            if (exifData != NULL)
            {
                // For debugging, exif_data_dump writes all exif data to stdout
                //exif_data_dump(exifData);

                extractExifData(exifData, pFile);

                exif_data_unref(exifData);
            }

            // Free the loader
            exif_loader_unref(exifLoader);
        }
        catch (TskException& tskEx)
        {
            std::wstringstream msg;
            msg << L"ExifExtractModule - Error processing file id " << pFile->getId() << L": " << tskEx.what();
            LOGERROR(msg.str());
            return TskModule::FAIL;
        }
        catch (std::exception& ex)
        {
            std::wstringstream msg;
            msg << L"ExifExtractModule - Error processing file id " << pFile->getId() << L": " << ex.what();
            LOGERROR(msg.str());
            return TskModule::FAIL;
        }

        return TskModule::OK;
    }