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