exif-utils.c

Go to the documentation of this file.
00001 /* exif-utils.c
00002  *
00003  * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful, 
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details. 
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the
00017  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA  02110-1301  USA.
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <libexif/exif-utils.h>
00024 
00025 void
00026 exif_array_set_byte_order (ExifFormat f, unsigned char *b, unsigned int n,
00027                 ExifByteOrder o_orig, ExifByteOrder o_new)
00028 {
00029         unsigned int j;
00030         unsigned int fs = exif_format_get_size (f);
00031         ExifShort s;
00032         ExifSShort ss;
00033         ExifLong l;
00034         ExifSLong sl;
00035         ExifRational r;
00036         ExifSRational sr;
00037 
00038         if (!b || !n || !fs) return;
00039 
00040         switch (f) {
00041         case EXIF_FORMAT_SHORT:
00042                 for (j = 0; j < n; j++) {
00043                         s = exif_get_short (b + j * fs, o_orig);
00044                         exif_set_short (b + j * fs, o_new, s);
00045                 }
00046                 break;
00047         case EXIF_FORMAT_SSHORT:
00048                 for (j = 0; j < n; j++) {
00049                         ss = exif_get_sshort (b + j * fs, o_orig);
00050                         exif_set_sshort (b + j * fs, o_new, ss);
00051                 }
00052                 break;
00053         case EXIF_FORMAT_LONG:
00054                 for (j = 0; j < n; j++) {
00055                         l = exif_get_long (b + j * fs, o_orig);
00056                         exif_set_long (b + j * fs, o_new, l);
00057                 }
00058                 break;
00059         case EXIF_FORMAT_RATIONAL:
00060                 for (j = 0; j < n; j++) {
00061                         r = exif_get_rational (b + j * fs, o_orig);
00062                         exif_set_rational (b + j * fs, o_new, r);
00063                 }
00064                 break;
00065         case EXIF_FORMAT_SLONG:
00066                 for (j = 0; j < n; j++) {
00067                         sl = exif_get_slong (b + j * fs, o_orig);
00068                         exif_set_slong (b + j * fs, o_new, sl);
00069                 }
00070                 break;
00071         case EXIF_FORMAT_SRATIONAL:
00072                 for (j = 0; j < n; j++) {
00073                         sr = exif_get_srational (b + j * fs, o_orig);
00074                         exif_set_srational (b + j * fs, o_new, sr);
00075                 }
00076                 break;
00077         case EXIF_FORMAT_UNDEFINED:
00078         case EXIF_FORMAT_BYTE:
00079         case EXIF_FORMAT_ASCII:
00080         default:
00081                 /* Nothing here. */
00082                 break;
00083         }
00084 }
00085 
00086 ExifSShort
00087 exif_get_sshort (const unsigned char *buf, ExifByteOrder order)
00088 {
00089         if (!buf) return 0;
00090         switch (order) {
00091         case EXIF_BYTE_ORDER_MOTOROLA:
00092                 return ((buf[0] << 8) | buf[1]);
00093         case EXIF_BYTE_ORDER_INTEL:
00094                 return ((buf[1] << 8) | buf[0]);
00095         }
00096 
00097         /* Won't be reached */
00098         return (0);
00099 }
00100 
00101 ExifShort
00102 exif_get_short (const unsigned char *buf, ExifByteOrder order)
00103 {
00104         return (exif_get_sshort (buf, order) & 0xffff);
00105 }
00106 
00107 void
00108 exif_set_sshort (unsigned char *b, ExifByteOrder order, ExifSShort value)
00109 {
00110         if (!b) return;
00111         switch (order) {
00112         case EXIF_BYTE_ORDER_MOTOROLA:
00113                 b[0] = (unsigned char) (value >> 8);
00114                 b[1] = (unsigned char) value;
00115                 break;
00116         case EXIF_BYTE_ORDER_INTEL:
00117                 b[0] = (unsigned char) value;
00118                 b[1] = (unsigned char) (value >> 8);
00119                 break;
00120         }
00121 }
00122 
00123 void
00124 exif_set_short (unsigned char *b, ExifByteOrder order, ExifShort value)
00125 {
00126         exif_set_sshort (b, order, value);
00127 }
00128 
00129 ExifSLong
00130 exif_get_slong (const unsigned char *b, ExifByteOrder order)
00131 {
00132         if (!b) return 0;
00133         switch (order) {
00134         case EXIF_BYTE_ORDER_MOTOROLA:
00135                 return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
00136         case EXIF_BYTE_ORDER_INTEL:
00137                 return ((b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]);
00138         }
00139 
00140         /* Won't be reached */
00141         return (0);
00142 }
00143 
00144 void
00145 exif_set_slong (unsigned char *b, ExifByteOrder order, ExifSLong value)
00146 {
00147         if (!b) return;
00148         switch (order) {
00149         case EXIF_BYTE_ORDER_MOTOROLA:
00150                 b[0] = (unsigned char) (value >> 24);
00151                 b[1] = (unsigned char) (value >> 16);
00152                 b[2] = (unsigned char) (value >> 8);
00153                 b[3] = (unsigned char) value;
00154                 break;
00155         case EXIF_BYTE_ORDER_INTEL:
00156                 b[3] = (unsigned char) (value >> 24);
00157                 b[2] = (unsigned char) (value >> 16);
00158                 b[1] = (unsigned char) (value >> 8);
00159                 b[0] = (unsigned char) value;
00160                 break;
00161         }
00162 }
00163 
00164 ExifLong
00165 exif_get_long (const unsigned char *buf, ExifByteOrder order)
00166 {
00167         return (exif_get_slong (buf, order) & 0xffffffff);
00168 }
00169 
00170 void
00171 exif_set_long (unsigned char *b, ExifByteOrder order, ExifLong value)
00172 {
00173         exif_set_slong (b, order, value);
00174 }
00175 
00176 ExifSRational
00177 exif_get_srational (const unsigned char *buf, ExifByteOrder order)
00178 {
00179         ExifSRational r;
00180 
00181         r.numerator   = buf ? exif_get_slong (buf, order) : 0;
00182         r.denominator = buf ? exif_get_slong (buf + 4, order) : 0;
00183 
00184         return (r);
00185 }
00186 
00187 ExifRational
00188 exif_get_rational (const unsigned char *buf, ExifByteOrder order)
00189 {
00190         ExifRational r;
00191 
00192         r.numerator   = buf ? exif_get_long (buf, order) : 0;
00193         r.denominator = buf ? exif_get_long (buf + 4, order) : 0;
00194 
00195         return (r);
00196 }
00197 
00198 void
00199 exif_set_rational (unsigned char *buf, ExifByteOrder order,
00200                    ExifRational value)
00201 {
00202         if (!buf) return;
00203         exif_set_long (buf, order, value.numerator);
00204         exif_set_long (buf + 4, order, value.denominator);
00205 }
00206 
00207 void
00208 exif_set_srational (unsigned char *buf, ExifByteOrder order,
00209                     ExifSRational value)
00210 {
00211         if (!buf) return;
00212         exif_set_slong (buf, order, value.numerator);
00213         exif_set_slong (buf + 4, order, value.denominator);
00214 }
00215 
00219 void
00220 exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen)
00221 {
00222         if (maxlen <= 0) {
00223                 return;
00224         }
00225         while (*in) {
00226                 if (*in < 0x80) {
00227                         if (maxlen > 1) {
00228                                 *out++ = (char)*in++;
00229                                 maxlen--;
00230                         } else {
00231                                 break;
00232                         }
00233                 } else if (*in < 0x800) {
00234                         if (maxlen > 2) {
00235                                 *out++ = ((*in >> 6) & 0x1F) | 0xC0;
00236                                 *out++ = (*in++ & 0x3F) | 0x80;
00237                                 maxlen -= 2;
00238                         } else {
00239                                 break;
00240                         }
00241                 } else {
00242                         if (maxlen > 3) {
00243                                 *out++ = ((*in >> 12) & 0x0F) | 0xE0;
00244                                 *out++ = ((*in >> 6) & 0x3F) | 0x80;
00245                                 *out++ = (*in++ & 0x3F) | 0x80;
00246                                 maxlen -= 3;
00247                         } else {
00248                                 break;
00249                         }
00250                 }
00251         }
00252         *out = 0;
00253 }

SourceForge.net Logo Generated by doxygen