libexif: writing new exif into image with IPTC/XMP - jpeg

I am trying to write EXIF metadata to JPEG images using libexif. I've faced with problem with images without EXIF but with IPTC/XMP metadata. After writing EXIF to images with IPTC/XMP I can't read EXIF. The "exif" command line utility (which also use libexif) report EXIF corruption. If I do the same for images without any metadata everything works fine.
Here is small test application which demonstrates issue (it assume that we are working with image without EXIF).
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <libexif/exif-data.h>
#include <libexif/exif-loader.h>
#include <jpeglib.h>
#include "jpegexif/jpeg-data.h"
#include "jpegexif/jpeg-marker.h"
#include "jpegexif/jpeg-data.c"
#include "jpegexif/jpeg-marker.c"
static ExifEntry *create_ascii_tag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len) {
void *buf;
ExifEntry *entry;
// Create a memory allocator to manage this ExifEntry.
ExifMem *mem = exif_mem_new_default();
// Create a new ExifEntry using our allocator.
entry = exif_entry_new_mem(mem);
// Allocate memory to use for holding the tag data.
buf = exif_mem_alloc(mem, len);
// Fill in the entry.
entry->data = (unsigned char*) buf;
entry->size = len;
entry->tag = tag;
entry->components = len;
entry->format = EXIF_FORMAT_ASCII;
// Attach the ExifEntry to an IFD.
exif_content_add_entry(exif->ifd[ifd], entry);
// The ExifMem and ExifEntry are now owned elsewhere.
exif_mem_unref(mem);
exif_entry_unref(entry);
return entry;
}
int create_exif_and_set_software(const char* const filename, const char* const tagvalue) {
// For simplification we assume here that file has no EXIF, so we create new.
ExifData* exif = exif_data_new();
exif_data_set_option(exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
exif_data_set_data_type(exif, EXIF_DATA_TYPE_COMPRESSED);
exif_data_set_byte_order(exif, EXIF_BYTE_ORDER_INTEL);
exif_data_fix(exif);
// Create entry for "Software" and set it's data.
ExifEntry* entry = create_ascii_tag(exif, EXIF_IFD_0, EXIF_TAG_SOFTWARE, strlen(tagvalue) + 1);
memcpy(entry->data, tagvalue, strlen(tagvalue) + 1);
// Write exif to JPEG.
JPEGData* image = jpeg_data_new_from_file(filename);
jpeg_data_set_exif_data(image, exif);
jpeg_data_save_file(image, filename);
// Unreference exif.
exif_data_unref(exif);
return 0;
}
int main(int argc, char ** argv) {
char* filename = argv[1];
// Create EXIF, set software and write EXIF to file.
create_exif_and_set_software(filename, "Awesome image editor.");
// Check that EXIF exists in file.
ExifData* exif = exif_data_new_from_file(filename);
printf("EXIF exists: %d\n", exif != NULL);
return 0;
}
Here you could download project and sample images. I used the following command to build it on mac with libexif installed via macports:
gcc exif.c -I/opt/local/include -L/opt/local/lib -lexif

The easy way, is to start writing the JPEG from scratch:
First, write the JPEG with no APP1 sections, than add Exif section, than add all other XMP APP1 sections.
Note that IFD offsets should be updated appropriately.

Related

No zlib.h file in usr/local/include how to get it

so I have been trying to run a C++ program which requires Zlib library on compiling the file it gave an error saying "zlib.h no such file or directory exists" upon looking in usr/local/include i found that the file is not there can i just copy the file to that location or should i Install some thing. i am kinda new to ubuntu so please help
Install zlib with development support by using
sudo apt-get install zlib1g-dev
In case you don't want or need to use the full zlib, it is fairly easy to write wrapper routines which map the zlib functions 1:1 to ordinary file functions which don't support compression and decompression.
//
// dummy zlib.h
//
#pragma once
#include <stdio.h>
typedef FILE *gzFile;
int gzclose(gzFile file);
gzFile gzdopen(int fd, const char *mode);
gzFile gzopen(const char *path, const char *mode);
int gzread(gzFile file, void *buf, unsigned int len);
//
// zlibDummy.cpp
//
#include <zlib.h>
int gzclose(gzFile file)
{
return fclose(file);
}
gzFile gzdopen(int fd, const char *mode)
{
return _fdopen(fd, mode);
}
gzFile gzopen(const char *path, const char *mode)
{
return fopen(path, mode);
}
int gzread(gzFile file, void *buf, unsigned int len)
{
return fread(buf, 1, len, file);
}
Well, temporary solution
download from : https://github.com/madler/zlib/blob/master/zlib.h
put the file in the same folder as your project file.
#include "zlib.h"

Converting between WinRT HttpBufferContent and unmanaged memory in C++cx

As part of a WinRT C++cx component, what's the most efficient way to convert an unmanaged buffer of bytes (say expressed as a std::string) back and forth with a Windows::Web::Http::HttpBufferContent?
This is what I ended up with, but it doesn't seem very optimal:
std::string to HttpBufferContent:
std::string m_body = ...;
auto writer = ref new DataWriter();
writer->WriteBytes(ArrayReference<unsigned char>(reinterpret_cast<unsigned char*>(const_cast<char*>(m_body.data())), m_body.length()));
auto content = ref new HttpBufferContent(writer->DetachBuffer());
HttpBufferContent to std::string:
HttpBufferContent^ content = ...
auto operation = content->ReadAsBufferAsync();
auto task = create_task(operation);
if (task.wait() == task_status::completed) {
auto buffer = task.get();
size_t length = buffer->Length;
if (length > 0) {
unsigned char* storage = static_cast<unsigned char*>(malloc(length));
DataReader::FromBuffer(buffer)->ReadBytes(ArrayReference<unsigned char>(storage, length));
auto m_body = std::string(reinterpret_cast<char*>(storage), length);
free(storage);
}
} else {
abort();
}
UPDATE: Here's the version I ended up using (you can trivially create a HttpBufferContent^ from an Windows::Storage::Streams::IBuffer^):
void IBufferToString(IBuffer^ buffer, std::string& string) {
Array<unsigned char>^ array = nullptr;
CryptographicBuffer::CopyToByteArray(buffer, &array); // TODO: Avoid copy
string.assign(reinterpret_cast<char*>(array->Data), array->Length);
}
IBuffer^ StringToIBuffer(const std::string& string) {
auto array = ArrayReference<unsigned char>(reinterpret_cast<unsigned char*>(const_cast<char*>(string.data())), string.length());
return CryptographicBuffer::CreateFromByteArray(array);
}
I think you are making at least one unnecessary copy of your data in your current approach for HttpBufferContent to std::string, you could improve this by accessing the IBuffer data directly, see the accepted answer here: Getting an array of bytes out of Windows::Storage::Streams::IBuffer
I think it's better to use smart pointer (no memory management needed) :
#include <wrl.h>
#include <robuffer.h>
#include <memory>
using namespace Windows::Storage::Streams;
using namespace Microsoft::WRL;
IBuffer^ buffer;
ComPtr<IBufferByteAccess> byte_access;
reinterpret_cast<IInspectable*>(buffer)->QueryInterface(IID_PPV_ARGS(&byte_access));
std::unique_ptr<byte[]> raw_buffer = std::make_unique<byte[]>(buffer->Length);
byte_access->Buffer(raw_buffer.get());
std::string str(reinterpret_cast<char*>(raw_buffer.get())); // just 1 copy

How to play and detect an object using captured video in background subtractor model?

everyone.! I am using opencv2.4.2. actually I am doing project on object detection. I tried using BackgroundSubtractorMOG model.
But I am not able to load video file from my computer. While running on real time this below code for segmentation works fine.
I have implemented using frame differencing method for object detection. Now I want to segment whole object from the background. I have static background. so can anybody help me in below code how to segment object from captured video. also how to load a video file?
thank you.
#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "conio.h"
#include "time.h"
#include "opencv/cvaux.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
//IplImage* tmp_frame;
//std::string arg = argv[1];
//VideoCapture capture();
cv::VideoCapture cap;
/*CvCapture *cap =cvCaptureFromFile("S:\\offline object detection database\\SINGLE PERSON Database\\video4.avi");
if(!cap){
printf("Capture failure\n");
return -1;
}
IplImage* frame=0;
frame = cvQueryFrame(cap);
if(!frame)
return -1;*/
bool update_bg_model = true;
if( argc < 2 )
cap.open(0);
else
cap.open(std::string(argv[1]));
if( !cap.isOpened() )
{
printf("can not open camera or video file\n");
return -1;
}
Mat tmp_frame, bgmask;
cap >> tmp_frame;
if(!tmp_frame.data)
{
printf("can not read data from the video source\n");
return -1;
}
namedWindow("video", 1);
namedWindow("segmented", 1);
BackgroundSubtractorMOG bgsubtractor;
for(;;)
{
//double t = (double)cvGetTickCount();
cap >> tmp_frame;
if( !tmp_frame.data )
break;
bgsubtractor(tmp_frame, bgmask, update_bg_model ? -1 : 0);
//t = (double)cvGetTickCount() - t;
//printf( "%d. %.1f\n", fr, t/(cvGetTickFrequency()*1000.) );
imshow("video", tmp_frame);
imshow("segmented", bgmask);
char keycode = waitKey(30);
if( keycode == 27 ) break;
if( keycode == ' ' )
update_bg_model = !update_bg_model;
}
return 0;
}
The video loading in opencv works for me. To load a video you can try something like this. Once you have captured frame you either do processing in the loop or can call a separate function.
std::cout<<"Video File "<<argv[1]<<std::endl;
cv::VideoCapture input_video(argv[1]);
namedWindow("My_Win",1);
Mat cap_img;
while(input_video.grab())
{
if(input_video.retrieve(cap_img))
{
imshow("My_Win", cap_img);
/* Once you have the image do all the processing here */
/* Or Call your image processing function */
waitKey(1);
}
}
or You can do something
int main(int argc, char*argv[])
{
char *my_file = "C:\\vid_an2\\desp_me.avi";
std::cout<<"Video File "<<my_file<<std::endl;
cv::VideoCapture input_video;
if(input_video.open(my_file))
{
std::cout<<"Video file open "<<std::endl;
}
else
{
std::cout<<"Not able to Video file open "<<std::endl;
}
namedWindow("My_Win",1);
namedWindow("Segemented", 1);
Mat cap_img;
for(;;)
{
input_video >> cap_img;
imshow("My_Win", cap_img);
waitKey(0);
}
return 0;
}

Is it possible to change strings (content and size) in Lua bytecode so that it will still be correct?

Is it possible to change strings (content and size) in Lua bytecode so that it will still be correct?
It's about translating strings in Lua bytecode. Of course, not every language has the same size for each word...
Yes, it is if you know what you're doing. Strings are prefixed by their size stored as an int. The size and endianness of that int is platform-dependent. But why do you have to edit bytecode? Have you lost the sources?
After some diving throught Lua source-code I found such a solution:
#include "lua.h"
#include "lauxlib.h"
#include "lopcodes.h"
#include "lobject.h"
#include "lundump.h"
/* Definition from luac.c: */
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
writer_function(lua_State* L, const void* p, size_t size, void* u)
{
UNUSED(L);
return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
}
static void
lua_bytecode_change_const(lua_State *l, Proto *f_proto,
int const_index, const char *new_const)
{
TValue *tmp_tv = NULL;
const TString *tmp_ts = NULL;
tmp_ts = luaS_newlstr(l, new_const, strlen(new_const));
tmp_tv = &f_proto->k[INDEXK(const_index)];
setsvalue(l, tmp_tv, tmp_ts);
return;
}
int main(void)
{
lua_State *l = NULL;
Proto *lua_function_prototype = NULL;
FILE *output_file_hnd = NULL;
l = lua_open();
luaL_loadfile(l, "some_input_file.lua");
lua_proto = toproto(l, -1);
output_file_hnd = fopen("some_output_file.luac", "w");
lua_bytecode_change_const(l, lua_function_prototype, some_const_index, "some_new_const");
lua_lock(l);
luaU_dump(l, lua_function_prototype, writer_function, output_file_hnd, 0);
lua_unlock(l);
return 0;
}
Firstly, we have start Lua VM and load the script we want to modify. Compiled or not, doesn't matter. Then build a Lua function prototype, parse and change it's constant table. Dump Prototype to a file.
I hope You got that for the basic idea.
You can try using the decompiler LuaDec. The decompiler would allow the strings to be modified in generated Lua code similar to the original source.
ChunkSpy has A No-Frills Introduction to Lua 5.1 VM Instructions that may help you understand the compiled chunk format and make the changes directly to bytecode if necessary.

What happens to an open file handle on Linux if the pointed file gets moved or deleted

What happens to an open file handle on Linux if the pointed file meanwhile gets:
Moved away -> Does the file handle stay valid?
Deleted -> Does this lead to an EBADF, indicating an invalid file handle?
Replaced by a new file -> Does the file handle pointing to this new file?
Replaced by a hard link to a new file -> Does my file handle "follow" this link?
Replaced by a soft link to a new file -> Does my file handle hit this soft link file now?
Why I'm asking such questions: I'm using hot-plugged hardware (such as USB devices etc.). It can happen, that the device (and also its /dev/file) gets reattached by the user or another Gremlin.
What's the best practice dealing with this?
If the file is moved (in the same filesystem) or renamed, then the file handle remains open and can still be used to read and write the file.
If the file is deleted, the file handle remains open and can still be used (This is not what some people expect). The file will not really be deleted until the last handle is closed.
If the file is replaced by a new file, it depends exactly how. If the file's contents are overwritten, the file handle will still be valid and access the new content. If the existing file is unlinked and a new one created with the same name or, if a new file is moved onto the existing file using rename(), it's the same as deletion (see above) - that is, the file handle will continue to refer to the original version of the file.
In general, once the file is open, the file is open, and nobody changing the directory structure can change that - they can move, rename the file, or put something else in its place, it simply remains open.
In Unix there is no delete, only unlink(), which makes sense as it doesn't necessarily delete the file - just removes the link from the directory.
If on the other hand the underlying device disappears (e.g. USB unplug) then the file handle won't be valid any more and is likely to give IO/error on any operation. You still have to close it though. This is going to be true even if the device is plugged back in, as it's not sensible to keep a file open in this case.
File handles point to an inode not to a path, so most of your scenarios still work as you assume, since the handle still points to the file.
Specifically, with the delete scenario - the function is called "unlink" for a reason, it destroys a "link" between a filename (a dentry) and a file. When you open a file, then unlink it, the file actually still exists until its reference count goes to zero, which is when you close the handle.
Edit: In the case of hardware, you have opened a handle to a specific device node, if you unplug the device, the kernel will fail all accesses to it, even if the device comes back. You will have to close the device and reopen it.
I'm not sure about the other operations, but as for deletion: Deletion simply doesn't take place (physically, i.e. in the file system) until the last open handle to the file is closed. Thus it should not be possible to delete a file out from under your application.
A few apps (that don't come to mind) rely on this behavior, by creating, opening and immediately deleting files, which then live exactly as long as the application - allowing other applications to be aware of the first app's lifecycle without needing to look at process maps and such.
It's possible similar considerations apply to the other stuff.
if you want to check if the file handler(file descriptor) is okay, you can call this function.
/**
* version : 1.1
* date : 2015-02-05
* func : check if the fileDescriptor is fine.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
/**
* On success, zero is returned. On error, -1 is returned, and errno is set
* appropriately.
*/
int check_fd_fine(int fd) {
struct stat _stat;
int ret = -1;
if(!fcntl(fd, F_GETFL)) {
if(!fstat(fd, &_stat)) {
if(_stat.st_nlink >= 1)
ret = 0;
else
printf("File was deleted!\n");
}
}
if(errno != 0)
perror("check_fd_fine");
return ret;
}
int main() {
int fd = -1;
fd = open("/dev/ttyUSB1", O_RDONLY);
if(fd < 0) {
perror("open file fail");
return -1;
}
// close or remove file(remove usb device)
// close(fd);
sleep(5);
if(!check_fd_fine(fd)) {
printf("fd okay!\n");
} else {
printf("fd bad!\n");
}
close(fd);
return 0;
}
The in-memory information of a deleted file (all the examples you give are instances of a deleted file) as well as the inodes on-disk remain in existence until the file is closed.
Hardware being hotplugged is a completely different issue, and you should not expect your program to stay alive long if the on-disk inodes or metadata have changed at all.
The following experiment shows that MarkR's answer is correct.
code.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
void perror_and_exit() {
perror(NULL);
exit(1);
}
int main(int argc, char *argv[]) {
int fd;
if ((fd = open("data", O_RDONLY)) == -1) {
perror_and_exit();
}
char buf[5];
for (int i = 0; i < 5; i++) {
bzero(buf, 5);
if (read(fd, buf, 5) != 5) {
perror_and_exit();
}
printf("line: %s", buf);
sleep(20);
}
if (close(fd) != 0) {
perror_and_exit();
}
return 0;
}
data:
1234
1234
1234
1234
1234
Use gcc code.c to produce a.out. Run ./a.out. When you see the following output:
line: 1234
Use rm data to delete data. But ./a.out will continue to run without errors and produce the following whole output:
line: 1234
line: 1234
line: 1234
line: 1234
line: 1234
I have done the experiment on Ubuntu 16.04.3.
Under /proc/ directory you will find a list of every process currently active, just find your PID and all data regarding is there. An interresting info is the folder fd/, you will find all file handlers currently opened by the process.
Eventually you will find a symbolic link to your device (under /dev/ or even /proc/bus/usb/), if the device hangs the link will be dead and it will be impossible to refresh this handle, the process must close and open it again (even with reconnection)
This code can read your PID's link current status
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
int main() {
// the directory we are going to open
DIR *d;
// max length of strings
int maxpathlength=256;
// the buffer for the full path
char path[maxpathlength];
// /proc/PID/fs contains the list of the open file descriptors among the respective filenames
sprintf(path,"/proc/%i/fd/",getpid() );
printf("List of %s:\n",path);
struct dirent *dir;
d = opendir(path);
if (d) {
//loop for each file inside d
while ((dir = readdir(d)) != NULL) {
//let's check if it is a symbolic link
if (dir->d_type == DT_LNK) {
const int maxlength = 256;
//string returned by readlink()
char hardfile[maxlength];
//string length returned by readlink()
int len;
//tempath will contain the current filename among the fullpath
char tempath[maxlength];
sprintf(tempath,"%s%s",path,dir->d_name);
if ((len=readlink(tempath,hardfile,maxlength-1))!=-1) {
hardfile[len]='\0';
printf("%s -> %s\n", dir->d_name,hardfile);
} else
printf("error when executing readlink() on %s\n",tempath);
}
}
closedir(d);
}
return 0;
}
This final code is simple, you can play with linkat function.
int
open_dir(char * path)
{
int fd;
path = strdup(path);
*strrchr(path, '/') = '\0';
fd = open(path, O_RDONLY | O_DIRECTORY);
free(path);
return fd;
}
int
main(int argc, char * argv[])
{
int odir, ndir;
char * ofile, * nfile;
int status;
if (argc != 3)
return 1;
odir = open_dir(argv[1]);
ofile = strrchr(argv[1], '/') + 1;
ndir = open_dir(argv[2]);
nfile = strrchr(argv[2], '/') + 1;
status = linkat(odir, ofile, ndir, nfile, AT_SYMLINK_FOLLOW);
if (status) {
perror("linkat failed");
}
return 0;
}

Resources