Beispiel #1
0
	Exif::Exif(QString path) {
		ExifLoader *loader;

		loader = exif_loader_new();
		exif_loader_write_file(loader, path.toStdString().c_str());
		m_data = exif_loader_get_data(loader);
		exif_loader_unref(loader);
	}
Beispiel #2
0
int main(int argc, char **argv)
{
    int rc = 1;
    ExifLoader *l;

    if (argc < 2) {
        printf("Usage: %s image.jpg\n", argv[0]);
        printf("Extracts a thumbnail from the given EXIF image.\n");
        return rc;
    }

    /* Create an ExifLoader object to manage the EXIF loading process */
    l = exif_loader_new();
    if (l) {
        ExifData *ed;

        /* Load the EXIF data from the image file */
        exif_loader_write_file(l, argv[1]);

        /* Get a pointer to the EXIF data */
        ed = exif_loader_get_data(l);

	/* The loader is no longer needed--free it */
        exif_loader_unref(l);
	l = NULL;
        if (ed) {
	    /* Make sure the image had a thumbnail before trying to write it */
            if (ed->data && ed->size) {
                FILE *thumb;
                char thumb_name[1024];

		/* Try to create a unique name for the thumbnail file */
                snprintf(thumb_name, sizeof(thumb_name),
                         "%s_thumb.jpg", argv[1]);

                thumb = fopen(thumb_name, "wb");
                if (thumb) {
		    /* Write the thumbnail image to the file */
                    fwrite(ed->data, 1, ed->size, thumb);
                    fclose(thumb);
                    printf("Wrote thumbnail to %s\n", thumb_name);
                    rc = 0;
                } else {
                    printf("Could not create file %s\n", thumb_name);
                    rc = 2;
                }
            } else {
                printf("No EXIF thumbnail in file %s\n", argv[1]);
                rc = 1;
            }
	    /* Free the EXIF data */
            exif_data_unref(ed);
        }
    }
    return rc;
}
ExifData *
exif_data_new_from_file (const char *path)
{
	ExifData *edata;
	ExifLoader *loader;

	loader = exif_loader_new ();
	exif_loader_write_file (loader, path);
	edata = exif_loader_get_data (loader);
	exif_loader_unref (loader);

	return (edata);
}
Beispiel #4
0
int64_t
GetImageMetadata(const char *path, char *name)
{
	ExifData *ed;
	ExifEntry *e = NULL;
	ExifLoader *l;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE *infile;
	int width=0, height=0, thumb=0;
	char make[32], model[64] = {'\0'};
	char b[1024];
	struct stat file;
	int64_t ret;
	image_s *imsrc;
	metadata_t m;
	uint32_t free_flags = 0xFFFFFFFF;
	memset(&m, '\0', sizeof(metadata_t));

	//DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
	if ( stat(path, &file) != 0 )
		return 0;
	strip_ext(name);
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);

	/* MIME hard-coded to JPEG for now, until we add PNG support */
	m.mime = strdup("image/jpeg");

	l = exif_loader_new();
	exif_loader_write_file(l, path);
	ed = exif_loader_get_data(l);
	exif_loader_unref(l);
	if( !ed )
		goto no_exifdata;

	e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) )
	{
		m.date = strdup(exif_entry_get_value(e, b, sizeof(b)));
		if( strlen(m.date) > 10 )
		{
			m.date[4] = '-';
			m.date[7] = '-';
			m.date[10] = 'T';
		}
		else {
			free(m.date);
			m.date = NULL;
		}
	}
	else {
		/* One last effort to get the date from XMP */
		image_get_jpeg_date_xmp(path, &m.date);
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
	if( e )
	{
		strncpyt(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
		e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
		if( e )
		{
			strncpyt(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
			if( !strcasestr(model, make) )
				snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
			m.creator = escape_tag(trim(model), 1);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION);
	if( e )
	{
		int rotate;
		switch( exif_get_short(e->data, exif_data_get_byte_order(ed)) )
		{
		case 3:
			rotate = 180;
			break;
		case 6:
			rotate = 90;
			break;
		case 8:
			rotate = 270;
			break;
		default:
			rotate = 0;
			break;
		}
		if( rotate )
			xasprintf(&m.rotation, "%d", rotate);
	}

	if( ed->size )
	{
		/* We might need to verify that the thumbnail is 160x160 or smaller */
		if( ed->size > 12000 )
		{
			imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1, ROTATE_NONE);
			if( imsrc )
			{
 				if( (imsrc->width <= 160) && (imsrc->height <= 160) )
					thumb = 1;
				image_free(imsrc);
			}
		}
		else
		{
			thumb = 1;
			//- 20130708 Sungmin add
			if(ed->data && ed->size)
			{
				char* art_file;
				if( !thumb_cache_exists(path, &art_file) )
				{
					char cache_dir[MAXPATHLEN];
					strncpyt(cache_dir, art_file, sizeof(cache_dir));
					make_dir(dirname(cache_dir), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);

					FILE *thumb = fopen(art_file, "wb");
					//DPRINTF(E_WARN, L_METADATA, " * cache_dir: %s\n", cache_dir);
					//DPRINTF(E_WARN, L_METADATA, " * thumbnail: %s\n", art_file);
					if(thumb)
					{
						fwrite(ed->data, 1, ed->size, thumb);
						fclose(thumb);
					}
				}
				free(art_file);
			}
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);

	exif_data_unref(ed);

no_exifdata:
	/* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */
	if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height )
	{
		infile = fopen(path, "r");
		if( infile )
		{
			cinfo.err = jpeg_std_error(&jerr);
			jerr.error_exit = libjpeg_error_handler;
			jpeg_create_decompress(&cinfo);
			if( setjmp(setjmp_buffer) )
				goto error;
			jpeg_stdio_src(&cinfo, infile);
			jpeg_read_header(&cinfo, TRUE);
			jpeg_start_decompress(&cinfo);
			width = cinfo.output_width;
			height = cinfo.output_height;
			error:
			jpeg_destroy_decompress(&cinfo);
			fclose(infile);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);

	if( !width || !height )
	{
		free_metadata(&m, free_flags);
		return 0;
	}
	if( width <= 640 && height <= 480 )
		m.dlna_pn = strdup("JPEG_SM");
	else if( width <= 1024 && height <= 768 )
		m.dlna_pn = strdup("JPEG_MED");
	else if( (width <= 4096 && height <= 4096) || !GETFLAG(DLNA_STRICT_MASK) )
		m.dlna_pn = strdup("JPEG_LRG");
	xasprintf(&m.resolution, "%dx%d", width, height);

	ret = sql_exec(db, "INSERT into DETAILS"
	                   " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION,"
	                    " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
	                   "VALUES"
	                   " (%Q, '%q', %lld, %ld, %Q, %Q, %Q, %d, %Q, %Q, %Q);",
	                   path, name, (long long)file.st_size, file.st_mtime, m.date, m.resolution,
	                   m.rotation, thumb, m.creator, m.dlna_pn, m.mime);
	if( ret != SQLITE_OK )
	{
		fprintf(stderr, "Error inserting details for '%s'!\n", path);
		ret = 0;
	}
	else
	{
		ret = sqlite3_last_insert_rowid(db);
	}
	free_metadata(&m, free_flags);

	return ret;
}
Beispiel #5
0
/*------------------------------------------------------------------*
 * MODIFICATIONS:                                                   *
 *  Date        Description                         Author          *
 *============  ==================================  =============== *
 *                                                                  *
 *------------------------------------------------------------------*/
void ZImageThread::run()
{
	ZRequestList::iterator	vIt;
	ZImageThreadEvent		*vEvt;
#ifdef ZULU_EXIF
	ExifData				*vEd;
#endif
	bool					vExifHasThumb;
	qDebug("%s::Thread started", __FILE__);
	for(;;)
	{
		qDebug("%s::Loop entered", __FILE__);
		/*
		 * Wait until we are notified to begin processing
		 */
		mThreadWait.wait();
		if (mShutdown)
			break;

		/*
		 * We've got data
		 */
		qDebug("%s::Data to process", __FILE__);
		vIt = mRequests.begin();
		QPixmap *vPix;
		while (vIt != mRequests.end())
		{
			vExifHasThumb = false;
			vPix = NULL;

#ifdef ZULU_EXIF
			/*
			 * try to obtain thumbnail from exif
			 */
			ExifLoader *vLoader = exif_loader_new();
			exif_loader_write_file(vLoader, (*vIt).GetURI().latin1());
			vEd = exif_loader_get_data(vLoader);
			exif_loader_unref(vLoader);
			if (vEd == NULL)
			{
				qDebug("%s::%s does not contain EXIF data!", __FILE__, (*vIt).GetURI().latin1());
			}
			else
			{
				qDebug("%s::%s has EXIF data!", __FILE__, (*vIt).GetURI().latin1());
				if (vEd->data != NULL)
				{
					QImage vTemp;
					if (vTemp.loadFromData(vEd->data, vEd->size) == false)
						qDebug("%s::Unable to load pixmap", __FILE__);
					else
					{
						vPix = new QPixmap(vTemp.smoothScale((*vIt).GetWidth(), (*vIt).GetHeight(), QImage::ScaleMin));
						if (vPix == NULL)
							qDebug("%s::Unable to create pixmap", __FILE__);
						else
							vExifHasThumb = true;
					}
				}
			}
#endif
			/*
			 * Create the thumbnail
			 */
			if (vExifHasThumb == false)
			{
				QString vURI = (*vIt).GetURI();
				qDebug("%s::Image format => [%s]", __FILE__, QImage::imageFormat(vURI));
				qDebug("%s::Loading image %s", __FILE__, (*vIt).GetURI().latin1());
				QImageIO vImgIO;
				vImgIO.setFileName(vURI);
				if (vImgIO.read() == false)
				{
					qDebug("%s::Unable to read image", __FILE__);
					continue;
				}

				vPix = new QPixmap(vImgIO.image().scale((*vIt).GetWidth() , (*vIt).GetHeight(), QImage::ScaleMin));
				if (vPix == NULL)
					qDebug("%s::Unable to create pixmap from image", __FILE__);
			}

			/*
			 * Create and send the notification event
			 */
			vEvt = new ZImageThreadEvent((*vIt).GetKey(), vPix);
			delete vPix;
			vPix = NULL;
			QApplication::postEvent(mParent, vEvt);

			/*
			 * Now remove this request from the queue
			 */
			mListLock.lock();
			vIt = mRequests.erase(vIt);
			mListLock.unlock();
		}
	}
	qDebug("%s::Thread exiting", __FILE__);
}