1/*
2
3Copyright (c) 2000 Curtis Galloway
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be
14included in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24This is a loadable module for the AOLserver web server that provides
25an interface to the EXIF tag parsing library.
26
27It adds one Tcl command into the AOLserver Tcl interpreter:
28
29  ns_exif <file>
30
31It returns the ID of an ns_set that contains the tag names and values
32from the EXIF file.
33
34*/
35
36#include "ns.h"
37
38#include "exif.h"
39
40#define BUFSIZE  1024
41
42static void
43rec_put(Ns_Set *set, exif_record_t *rec)
44{
45  char buf[BUFSIZE];
46  char *str = buf;
47
48  switch (rec->rec_type) {
49  case 's':
50    str = rec->rec_data.s;
51    break;
52  case 'f':
53    snprintf(buf, BUFSIZE, "%f", rec->rec_data.f);
54    break;
55  case 'g':
56    snprintf(buf, BUFSIZE, "%g", rec->rec_data.f);
57    break;
58  case 'l':
59    snprintf(buf, BUFSIZE, "%ld", rec->rec_data.l);
60    break;
61  case 'r':
62    snprintf(buf, BUFSIZE, "%d/%d", rec->rec_data.r.num,
63	    rec->rec_data.r.denom);
64    break;
65  default:
66    snprintf(buf, BUFSIZE, "<Unknown record type '%c'>", rec->rec_type);
67    break;
68  }
69  Ns_SetPut(set, rec->rec_name, str);
70}
71
72static int
73Tcl_ReadExifDataCmd (
74		     ClientData    clientData,
75		     Tcl_Interp   *interp,
76		     int           argc,
77		     char        **argv)
78{
79  exif_data_t *d;
80  int i;
81  Ns_Set *rset;
82
83  d = exif_parse_file(argv[1]);
84  if (d == NULL) {
85    Tcl_AppendResult(interp, "Could not process file '", argv[1], "'", NULL);
86    return TCL_ERROR;
87  }
88  rset = Ns_SetCreate("exif");
89
90  for (i=0; i<d->n_recs; i++) {
91    rec_put(rset, &d->recs[i]);
92  }
93
94  Ns_TclEnterSet(interp, rset, NS_TCL_SET_TEMPORARY | NS_TCL_SET_DYNAMIC);
95  exif_free_data(d);
96  return TCL_OK;
97}
98
99
100/*----------------------------------------------------------------------
101 *
102 *  Tcl_InitExif --
103 *
104 *  Initialize the Tcl command.
105 *
106 *----------------------------------------------------------------------
107 */
108void
109Tcl_InitExif (interp)
110    Tcl_Interp *interp;
111{
112  Tcl_CreateCommand (interp, "ns_exif", Tcl_ReadExifDataCmd,
113		     NULL, NULL);
114}
115
116static int
117nsexif_interp_init (Tcl_Interp *interp, void *dummy)
118{
119  Tcl_InitExif(interp);
120  return TCL_OK;
121}
122
123
124int
125Ns_ModuleInit(char *hServer, char *hModule)
126{
127  char *configPath;
128
129  Ns_Log( Notice, "%s module starting", hModule);
130
131  exif_init((void *(*)(int))Ns_Malloc,
132	    (void (*)(void *))Ns_Free,
133	    (void *(*)(void *, int))Ns_Realloc);
134
135  configPath = Ns_ConfigGetPath(hServer, hModule, NULL);
136  /*  if (!Ns_ConfigGetBool (configPath, "Debug", &debug_p))
137      debug_p = DEFAULT_DEBUG; */
138
139  Ns_TclInitInterps (hServer, nsexif_interp_init, NULL);
140  return NS_OK;
141}
142
143int Ns_ModuleVersion = 1;
144