Tuesday 17 November 2009

A self explanatory program to understand server socket program in C


/* A simple server in the internet domain using TCP
The port number is passed as an argument */

//header file contains declarations used in most input and output
#include <stdio.h>

//This header file contains definitions of a number of data types
//used in system calls.These types are used in the next two include files.
#include <sys/types.h>

//The header file socket.h includes a number of definitions of structures needed for sockets.
#include <sys/socket.h>


//The header file in.h contains constants and structures needed for internet domain addresses.
#include <netinet/in.h>

//Exit(1) etc are defined in this header file
#include <stdlib.h>

//bzero etc are defined under this header file
#include <string.h>

// This function is called when a system call fails. It displays a message
//about the error on stderr and then aborts the program.
void error(char *msg)
{
perror(msg);
exit(1);
}

int main(int argc, char *argv[])
{
//sockfd and newsockfd are file descriptors, i.e. array subscripts into the file descriptor table .
//These two variables store the values returned by the socket system call and the accept system call.
//portno stores the port number on which the server accepts connections.
//clilen stores the size of the address of the client. This is needed for the accept system call.
int sockfd, newsockfd, portno, clilen;

//The server reads characters from the socket connection into this buffer.
char buffer[256];

//A sockaddr_in is a structure containing an internet address. This structure is defined in netinet/in.h.
//Here is the definition:
// struct sockaddr_in
// {
// short sin_family; /* must be AF_INET */
// u_short sin_port;
// struct in_addr sin_addr;
// char sin_zero[8]; /* Not used, must be zero */
// };
//An in_addr structure, defined in the same header file, contains only one field, a unsigned long called s_addr.
//The variable serv_addr will contain the address of the server, and
//cli_addr will contain the address of the client which connects to the server.
struct sockaddr_in serv_addr, cli_addr;

//n is the return value for the read() and write() calls; i.e. it contains the number of characters read or written
int n;

// This is used for modifying socket options - Details is given later
int on, ret;

//The user needs to pass in the port number on which the server will accept connections as an argument.
//This code displays an error message if the user fails to do this.
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
//The socket() system call creates a new socket. It takes three arguments.
//The first is the address domain of the socket.
//Recall that there are two possible address domains, the unix domain for
//two processes which share a common file system, and the Internet domain
//for any two hosts on the Internet. The symbol constant AF_UNIX is used for the former,
//and AF_INET for the latter (there are actually many other options
//which can be used here for specialized purposes).
//The second argument is the type of socket. Recall that there are two choices here,
//a stream socket in which characters are read in a continuous stream as if from a file or pipe,
//and a datagram socket, in which messages are read in chunks.
//The two symbolic constants are SOCK_STREAM and SOCK_DGRAM.
//The third argument is the protocol. If this argument is zero
//(and it always should be except for unusual circumstances),
//the operating system will choose the most appropriate protocol.
//It will choose TCP for stream sockets and UDP for datagram sockets.
//The socket system call returns an entry into the file descriptor table (i.e. a small integer).
//This value is used for all subsequent references to this socket.
// If the socket call fails, it returns -1.
//In this case the program displays and error message and exits.
//However, this system call is unlikely to fail.
//This is a simplified description of the socket call;
//there are numerous other choices for domains and types,
//but these are the most common.
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd
< 0)
error("ERROR opening socket");

//The function bzero() sets all values in a buffer to zero. It takes two arguments,

//the first is a pointer to the buffer and the second is the size of the buffer.
//Thus, this line initializes serv_addr to zeros.
bzero((char *) &serv_addr, sizeof(serv_addr));

//The port number on which the server will listen for connections is passed in as an argument,

//and this statement uses the atoi() function to convert this from a string of digits to an integer.
portno = atoi(argv[1]);

//The variable serv_addr is a structure of type struct sockaddr_in. This structure has four fields.

//The first field is short sin_family, which contains a code for the address family.
//It should always be set to the symbolic constant AF_INET.
serv_addr.sin_family = AF_INET;

//The third field of sockaddr_in is a structure of type struct in_addr which contains only a

//single field unsigned long s_addr. This field contains the IP address of the host.
//For server code, this will always be the IP address of the machine on which the server is running,
//and there is a symbolic constant INADDR_ANY which gets this address.
serv_addr.sin_addr.s_addr = INADDR_ANY;

//The second field of serv_addr is unsigned short sin_port, which contain the port number.

//However, instead of simply copying the port number to this field,
//it is necessary to convert this to network byte order using the function htons() which
//converts a port number in host byte order to a port number in network byte order.
serv_addr.sin_port = htons(portno);

//The bind() system call binds a socket to an address, in this case the address of the

//current host and port number on which the server will run. It takes three arguments,
//the socket file descriptor, the address to which is bound, and the size of the address
//to which it is bound. The second argument is a pointer to a structure of type sockaddr,
//but what is passed in is a structure of type sockaddr_in, and so this must be cast to the correct type.
//This can fail for a number of reasons, the most obvious being that
//this socket is already in use on this machine.
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
< 0)
error("ERROR on binding");

//The listen system call allows the process to listen on the socket for connections.

//The first argument is the socket file descriptor, and the second is the size of the backlog queue,
//i.e., the number of connections that can be waiting while the process is handling a particular connection.
//This should be set to 5, the maximum size permitted by most systems. If the first argument is a valid socket,
//this call cannot fail, and so the code doesn't check for errors.
listen(sockfd,5);

//The accept() system call causes the process to block until a client connects to the server.
//Thus, it wakes up the process when a connection from a client has been successfully established.
//It returns a new file descriptor, and all communication on this connection should be done using the
//new file descriptor. The second argument is a reference pointer to the address of the client on the
//other end of the connection, and the third argument is the size of this structure.
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");

//Note that we would only get to this point after a client has successfully connected to our server.
//This code initializes the buffer using the bzero() function, and then reads from the socket.
//Note that the read call uses the new file descriptor, the one returned by accept(), not the original
//file descriptor returned by socket(). Note also that the read() will block until there is something
//for it to read in the socket, i.e. after the client has executed a write().
//It will read either the total number of characters in the socket or 255,
//whichever is less, and return the number of characters read.
(buffer,256);
n = read(newsockfd,buffer,255);
if (n
< 0)
error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);

//Once a connection has been established, both ends can both read and write to the connection.
//Naturally, everything written by the client will be read by the server, and everything written
//by the server will be read by the client. This code simply writes a short message to the client.
//The last argument of write is the size of the message.
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");

//This terminates main and thus the program. Since main was declared to be of type int as specified

//by the ascii standard, some compilers complain if it does not return anything.
return 0;
}

Monday 16 November 2009

Updating Metadata of Image file using Perl script !


Exiv2 is a C++ library and a command line utility to manage image metadata. It provides fast and easy read and write access to the Exif, IPTC and XMP metadata of images in various formats. Exiv2 is available as free software and with a commercial license, and is used in many projects.

The Exiv2 library provides
  • fast read and write access to the Exif, IPTC, and XMP metadata of an image
  • an easy to use and extensively documented API
  • a smart IPTC implementation that does not affect data that programs like Photoshop store in the same image segment
  • adjust the Exif timestamp (that's how it all started...)
  • rename Exif image files according to the Exif timestamp
  • extract, insert and delete Exif, IPTC and XMP metadata and JPEG comments
  • extract previews from RAW images and thumbnails from the Exif metadata
  • insert and delete the thumbnail image embedded in the Exif metadata
  • print, set and delete the JPEG comment of JPEG images
  • fix the Exif ISO setting of picture taken with Canon and Nikon cameras

By default, the utility can print a summary of the Exif information by using the following command.

$ exiv2 image1.jpg

With the -pt option, the utility prints out all Exif information as interpreted (translated) values. Alternatively, -pv prints the plain Exif data values.

$ exiv2 -pt image1.jpg

A short description of the actions and options supported by the Exiv2 utility can be viewed by

$ exiv2 -h


Now to write a perl program to modify the metadata of an image you are interested in Ubuntu

Step - 1
*********
Include the EXIF/IPTC metadata manipulation library

$ sudo apt-get install eviv2 libexiv2-5 libexiv2-7 libexiv2-dev libexiv2-7-dev

Step - 2
********

Try the perl program given below:

#!/usr/bin/perl
use warnings;
use POSIX;
use Image::ExifTool qw(:Public);
my $jpg = $ARGV[0] or die "Usage: $0 ";
my $tool = Image::ExifTool->new();
$tool->ExtractInfo($jpg);
$tool->SetNewValue('Make'); # Deleting this tag magically makes it work
$now_time = strftime "%Y:%m:%d %H:%M:%S", localtime;
$success = $tool->SetNewValue("DateTimeOriginal",$now_time);
if ($success) {
$success = $tool->WriteInfo($jpg);
print "DateTimeOriginal Update failed", $tool->GetValue('Error'), "\n" if ! $success;
}
$success = $tool->SetNewValue("DateTime",$now_time);
if ($success) {
$success = $tool->WriteInfo($jpg);
print "DateTime Update failed", $tool->GetValue('Error'), "\n" if ! $success;
}
$success = $tool->SetNewValue("DateTimeDigitized",$now_time);
if ($success) {
$success = $tool->WriteInfo($jpg);
print "DateTimeDigitized Update failed", $tool->GetValue('Error'), "\n" if ! $success;
}


> Save the program as test1.py
> Execute by
$ ./test.py myimage. jpeg
# Where myimage is the image which you want to update the metadata
(Date and time in this case)

Image grabbing using ubuntu


To make a USB Web-camera to work on linux system you need to Install the webcam driver for web-camera. In most cases, webcam drivers differ according to the model of the webcam attached to your PC and according to the computer's operating system and the on-board video card. The main function of a webcam driver is to allow the operating system and installed webcam software applications to transmit digital images/video from the camera through the PC to an application / steaming connection.

In most cases, advanced operating systems such as Linux, Windows XP and Windows Vista contain default drivers that can detect a webcam on the first instance it is connected to the machine.

In Linux distributions many webcams will "just work" by default.

In Linux there are 2 different drivers which covers the majority of web-cameras available, these are the gspca and linux-uvc driver. You will need to determine which is the correct driver to install. If you are not sure which webcam you have you can make use of the 'lspci' and 'lsusb' commands to print a list of devices on your system.

After determining your webcam type you need to see which driver supports your webcam. Here is a list of webcams supported by the gspca driver (http://mxhaard.free.fr/spca5xx.html) and the Linux-UVC project has a good list of UVC compatible webcams supported by the linux-uvc driver (http://linux-uvc.berlios.de/#devices).

If you webcam doesn't appear on either list then it's possible your webcam isn't supported. If you like you can just try installing both drivers anyway and see how you go.

Linux UVC driver project
The goal of this project is to provide all necessary software components to fully support UVC compliant devices in Linux. The USB Device Class Definition for Video Devices, or USB Video Class (UVC), defines video streaming functionality on the Universal Serial Bus. Much like nearly all mass storage devices (USB flash disks, external IDE disk enclosures, ...) can be managed by a single driver because they conform to the USB Mass Storage specification, UVC compliant peripherals only need a generic driver.

GSPCA project
The gpsca video for linux (v4l) driver, provides support for webcams and digital cameras based on the spca5xx range of chips manufactured by SunPlus, Sonix, Z-star, Vimicro, Conexant, Etoms, Mars-semi, Pixart and Transvision.The gspca driver is a rewrite of the well known spca5xx v4l kernel module from the same author, Michel Xhaard.

Installing UVC driver on Ubuntu

Ensure that you have the header files for building the UVC module with:

# sudo apt-get install linux-headers-`uname -r`

In latest versions of Ubuntu the UVC module has been included which means that some webcams 'just work' but it is recommended that you still download the source code at LinuxTV uvcvideo development repository - (http://linux-uvc.berlios.de/#download)


Navigate to the 'uvcvideo' directory (or some similar name) containing the source. If you want to customize which drivers to compile, run:

# make menuconfig

If you do not know how to customize, just accept the defaults and exit by pressing ESC twice. To compile the drivers, run

# make

then, to install the compiled drivers to the appropriate module directories, run

# sudo make install

followed by

# sudo depmod -a

After that just ensure that you can see the webcam connected to the USB using:

# lsusb

If it is there, then run:

# sudo modprobe uvcvideo

Installing GSPCA driver on Ubuntu

GSPCA drivers are by default provided with ubuntu distribution. Else try the following command to install it.


# sudo aptitude install gspca-source -y

In the /usr/src directory, archive with driver source gspca-source.tar.bz2 will appear. Unpack it and change directory to /usr/src/modules/gspca and execute following:

# make

Module must compile without errors. Next, do this:


# sudo make install


This command will install your module in directory, were other kernel modules are placed. Optionally it can be executed:


# sudo depmode -a

That`s almost all, our goal is to load module of a webcam:

# sudo modprobe gspca

Testing your webcam

Ekiga is installed by default in Ubuntu, and can be used to test your webcam. For UVC devices luvcview is a good program you can use to test that the camera is working. If it doesn't work, you may need to update the UVC driver. Cheese, Camorama, xawtv, VLC, aMSN, and Kopete are all in the Ubuntu repositories. They all can be used to test and use your webcam. In some cases you (VLC, mplayer, amongst others) will need to know the video and audio device files for your webcam. Before you plug in your webcam, try the following two command at a console:

# ls /dev/video*
# ls /dev/audio*

Make a note of the devices appearing. Now plug in your webcam, allow the system a few seconds to register the device, and run the two commands again. The new appearances should belong to your webcam (for instance, /dev/video1 and /dev/audio2).


Command Line Image Grabbing in Linux

Streamer

Streamer (http://linux.bytesex.org/xawtv/) is a versatile program that allows a capture from a webcam or video device using only the command line. It may be offered in your Linux distribution's Xawtv package. To install streamer try

# sudo apt-get install xawtv

To take a standard JPEG picture from the command line where the camera is accessed through /dev/video0:

#streamer -c /dev/video0 -b 16 -o outfile.jpeg

Where > -b is the number of colors (in bpp,whether 15, 16, 24 or 32)
& -o is the output filename in the current directory

If you are going to capture multiple images be sure to append the output file name with zeros, as streamer can name the capture files in sequence, i.e., -o outfile000.jpeg becomes outfile001.jpeg, outfile002.jpeg, and so on.

Motion

Motion (http://www.lavrsen.dk/twiki/bin/view/Motion/WebHome) is a brilliant program that is able to monitor the video signal from one or several webcams. It can record periodic snapshots, and when motion is detected, record an mpeg and/or perform another action such as sending an email or executing a command. It can track and graphically mark the motion it detects, feed files via an http server to your website, stream them to another application and more. The number of command line options may be intimidating; there is however, a Wiki available online (http://www.lavrsen.dk/twiki/bin/view/Motion/MotionGuide) that outlines the various command and configuration file options nicely.

camE


camE is a rewrite of the xawtv webcam application using imlib2. It is a command-line program that works in daemon mode to capture frames from your v4l device for archive or upload (to a webserver, for example) via ftp or scp. You can overlay other graphics, timestamp the frames, or add other dynamic text all by altering the appropriate line in the configuration file.