@lodev09/react-native-exify 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,5 +64,5 @@ android {
64
64
 
65
65
  dependencies {
66
66
  implementation "com.facebook.react:react-android"
67
- implementation "androidx.exifinterface:exifinterface:1.3.7"
67
+ implementation "androidx.exifinterface:exifinterface:1.4.2"
68
68
  }
@@ -0,0 +1,245 @@
1
+ package com.lodev09.exify
2
+
3
+ import java.io.InputStream
4
+ import java.nio.ByteBuffer
5
+ import java.nio.ByteOrder
6
+
7
+ /**
8
+ * IFD0 tags that ExifInterface may miss when an image editor
9
+ * (e.g. ON1 Photo RAW) places them inside the ExifIFD instead of IFD0.
10
+ *
11
+ * Maps EXIF tag number → ExifInterface tag name.
12
+ */
13
+ private val FALLBACK_TAGS =
14
+ mapOf(
15
+ 0x010E to "ImageDescription",
16
+ 0x010F to "Make",
17
+ 0x0110 to "Model",
18
+ 0x0112 to "Orientation",
19
+ 0x011A to "XResolution",
20
+ 0x011B to "YResolution",
21
+ 0x0128 to "ResolutionUnit",
22
+ 0x0131 to "Software",
23
+ 0x013B to "Artist",
24
+ 0x8298 to "Copyright",
25
+ )
26
+
27
+ private const val IFD_FORMAT_SHORT = 3
28
+ private const val IFD_FORMAT_LONG = 4
29
+ private const val IFD_FORMAT_RATIONAL = 5
30
+ private const val IFD_FORMAT_STRING = 2
31
+ private const val IFD_FORMAT_UNDEFINED = 7
32
+ private const val EXIF_IFD_POINTER_TAG = 0x8769
33
+
34
+ /**
35
+ * Scans raw JPEG bytes for IFD0 tags that may have been placed in
36
+ * the ExifIFD. Returns a map of tag name → value for any tags found.
37
+ */
38
+ fun readFallbackTags(
39
+ inputStream: InputStream,
40
+ missingTags: Set<String>,
41
+ ): Map<String, Any> {
42
+ if (missingTags.isEmpty()) return emptyMap()
43
+
44
+ val neededTagNumbers = FALLBACK_TAGS.filterValues { it in missingTags }.keys
45
+ if (neededTagNumbers.isEmpty()) return emptyMap()
46
+
47
+ val bytes = readExifSegment(inputStream) ?: return emptyMap()
48
+ val result = mutableMapOf<String, Any>()
49
+
50
+ val app1 = findApp1Exif(bytes) ?: return emptyMap()
51
+ val tiffOffset = app1.tiffOffset
52
+ val buf = ByteBuffer.wrap(bytes)
53
+ buf.order(app1.byteOrder)
54
+
55
+ // Read IFD0 to find ExifIFD offset (offsets are relative to TIFF start)
56
+ val ifd0Offset = buf.getInt(tiffOffset + 4)
57
+ val exifIfdOffset = findExifIfdOffset(buf, tiffOffset, ifd0Offset) ?: return emptyMap()
58
+
59
+ // Scan ExifIFD entries for our missing tags
60
+ scanIfd(buf, tiffOffset, exifIfdOffset, neededTagNumbers, result)
61
+
62
+ return result
63
+ }
64
+
65
+ /**
66
+ * Reads only the JPEG header segments up to and including the EXIF APP1,
67
+ * avoiding reading the full image file into memory.
68
+ */
69
+ private fun readExifSegment(inputStream: InputStream): ByteArray? {
70
+ val dis = java.io.DataInputStream(inputStream)
71
+ val header = ByteArray(2)
72
+ dis.readFully(header)
73
+ if (header[0] != 0xFF.toByte() || header[1] != 0xD8.toByte()) return null
74
+
75
+ val out = java.io.ByteArrayOutputStream(65536)
76
+ out.write(header)
77
+
78
+ val segHeader = ByteArray(4)
79
+ while (true) {
80
+ try {
81
+ dis.readFully(segHeader)
82
+ } catch (_: java.io.EOFException) {
83
+ break
84
+ }
85
+ val marker = segHeader[1].toInt() and 0xFF
86
+ val segLen = ((segHeader[2].toInt() and 0xFF) shl 8) or (segHeader[3].toInt() and 0xFF)
87
+
88
+ if (segHeader[0] != 0xFF.toByte() || segLen < 2) break
89
+
90
+ out.write(segHeader)
91
+ val segData = ByteArray(segLen - 2)
92
+ dis.readFully(segData)
93
+ out.write(segData)
94
+
95
+ // Found EXIF APP1 — we have enough
96
+ if (marker == 0xE1 && segData.size >= 6 &&
97
+ segData[0] == 0x45.toByte() &&
98
+ segData[1] == 0x78.toByte() &&
99
+ segData[2] == 0x69.toByte() &&
100
+ segData[3] == 0x66.toByte()
101
+ ) {
102
+ break
103
+ }
104
+
105
+ // Stop if we hit SOS or image data
106
+ if (marker == 0xDA) break
107
+ }
108
+
109
+ return out.toByteArray()
110
+ }
111
+
112
+ private data class App1Info(
113
+ val tiffOffset: Int,
114
+ val byteOrder: ByteOrder,
115
+ )
116
+
117
+ private fun findApp1Exif(bytes: ByteArray): App1Info? {
118
+ if (bytes.size < 4 || bytes[0] != 0xFF.toByte() || bytes[1] != 0xD8.toByte()) return null
119
+
120
+ var pos = 2
121
+ while (pos + 4 < bytes.size) {
122
+ if (bytes[pos] != 0xFF.toByte()) return null
123
+ val marker = bytes[pos + 1].toInt() and 0xFF
124
+
125
+ // Read segment length (big-endian)
126
+ val segLen = ((bytes[pos + 2].toInt() and 0xFF) shl 8) or (bytes[pos + 3].toInt() and 0xFF)
127
+
128
+ if (marker == 0xE1 && segLen >= 8) {
129
+ // Check for "Exif\0\0"
130
+ if (pos + 10 < bytes.size &&
131
+ bytes[pos + 4] == 0x45.toByte() && // E
132
+ bytes[pos + 5] == 0x78.toByte() && // x
133
+ bytes[pos + 6] == 0x69.toByte() && // i
134
+ bytes[pos + 7] == 0x66.toByte() && // f
135
+ bytes[pos + 8] == 0x00.toByte() &&
136
+ bytes[pos + 9] == 0x00.toByte()
137
+ ) {
138
+ val tiffOffset = pos + 10
139
+ val order =
140
+ if (bytes[tiffOffset] == 0x49.toByte() && bytes[tiffOffset + 1] == 0x49.toByte()) {
141
+ ByteOrder.LITTLE_ENDIAN
142
+ } else {
143
+ ByteOrder.BIG_ENDIAN
144
+ }
145
+ return App1Info(tiffOffset, order)
146
+ }
147
+ }
148
+
149
+ pos += 2 + segLen
150
+ }
151
+ return null
152
+ }
153
+
154
+ private fun findExifIfdOffset(
155
+ buf: ByteBuffer,
156
+ tiffOffset: Int,
157
+ ifdOffset: Int,
158
+ ): Int? {
159
+ if (ifdOffset < 0 || tiffOffset + ifdOffset + 2 > buf.limit()) return null
160
+
161
+ val count = buf.getShort(tiffOffset + ifdOffset).toInt() and 0xFFFF
162
+ for (i in 0 until count) {
163
+ val entryOffset = tiffOffset + ifdOffset + 2 + i * 12
164
+ if (entryOffset + 12 > buf.limit()) return null
165
+
166
+ val tagNumber = buf.getShort(entryOffset).toInt() and 0xFFFF
167
+ if (tagNumber == EXIF_IFD_POINTER_TAG) {
168
+ return buf.getInt(entryOffset + 8)
169
+ }
170
+ }
171
+ return null
172
+ }
173
+
174
+ private fun scanIfd(
175
+ buf: ByteBuffer,
176
+ tiffOffset: Int,
177
+ ifdOffset: Int,
178
+ neededTagNumbers: Set<Int>,
179
+ result: MutableMap<String, Any>,
180
+ ) {
181
+ val absOffset = tiffOffset + ifdOffset
182
+ if (absOffset + 2 > buf.limit()) return
183
+
184
+ val count = buf.getShort(absOffset).toInt() and 0xFFFF
185
+ for (i in 0 until count) {
186
+ val entryOffset = absOffset + 2 + i * 12
187
+ if (entryOffset + 12 > buf.limit()) return
188
+
189
+ val tagNumber = buf.getShort(entryOffset).toInt() and 0xFFFF
190
+ if (tagNumber !in neededTagNumbers) continue
191
+
192
+ val format = buf.getShort(entryOffset + 2).toInt() and 0xFFFF
193
+ val componentCount = buf.getInt(entryOffset + 4)
194
+ if (componentCount <= 0) continue
195
+
196
+ val tagName = FALLBACK_TAGS[tagNumber] ?: continue
197
+
198
+ when (format) {
199
+ IFD_FORMAT_SHORT -> {
200
+ if (componentCount != 1) continue
201
+ val value = buf.getShort(entryOffset + 8).toInt() and 0xFFFF
202
+ if (value == 0) continue
203
+ result[tagName] = value
204
+ }
205
+
206
+ IFD_FORMAT_LONG -> {
207
+ if (componentCount != 1) continue
208
+ val value = buf.getInt(entryOffset + 8).toLong() and 0xFFFFFFFFL
209
+ if (value == 0L) continue
210
+ result[tagName] = value.toInt()
211
+ }
212
+
213
+ IFD_FORMAT_RATIONAL -> {
214
+ if (componentCount != 1) continue
215
+ val dataOffset = tiffOffset + buf.getInt(entryOffset + 8)
216
+ if (dataOffset < 0 || dataOffset + 8 > buf.limit()) continue
217
+ val numerator = buf.getInt(dataOffset).toLong() and 0xFFFFFFFFL
218
+ val denominator = buf.getInt(dataOffset + 4).toLong() and 0xFFFFFFFFL
219
+ if (denominator == 0L) continue
220
+ result[tagName] = numerator.toDouble() / denominator.toDouble()
221
+ }
222
+
223
+ IFD_FORMAT_STRING, IFD_FORMAT_UNDEFINED -> {
224
+ if (componentCount > 1024) continue
225
+ val dataOffset =
226
+ if (componentCount <= 4) {
227
+ entryOffset + 8
228
+ } else {
229
+ tiffOffset + buf.getInt(entryOffset + 8)
230
+ }
231
+ if (dataOffset < 0 || dataOffset + componentCount > buf.limit()) continue
232
+
233
+ val strBytes = ByteArray(componentCount)
234
+ buf.position(dataOffset)
235
+ buf.get(strBytes)
236
+
237
+ var len = strBytes.size
238
+ while (len > 0 && strBytes[len - 1] == 0.toByte()) len--
239
+ if (len == 0) continue
240
+
241
+ result[tagName] = String(strBytes, 0, len, Charsets.UTF_8).trim()
242
+ }
243
+ }
244
+ }
245
+ }
@@ -16,6 +16,7 @@ import com.facebook.react.modules.core.PermissionAwareActivity
16
16
  import com.facebook.react.modules.core.PermissionListener
17
17
  import com.facebook.react.util.RNLog
18
18
  import com.lodev09.exify.ExifyUtils.formatTags
19
+ import java.io.File
19
20
  import java.io.IOException
20
21
 
21
22
  private const val ERROR_TAG = "E_EXIFY_ERROR"
@@ -72,35 +73,77 @@ class ExifyModule(
72
73
  promise: Promise,
73
74
  ) {
74
75
  try {
75
- val inputStream =
76
- if (scheme == "http" || scheme == "https") {
77
- java.net.URL(uri).openStream()
78
- } else if (scheme == "content" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
79
- try {
80
- context.contentResolver.openInputStream(MediaStore.setRequireOriginal(photoUri))
81
- } catch (e: SecurityException) {
82
- context.contentResolver.openInputStream(photoUri)
83
- }
76
+ val exif =
77
+ if (scheme == "file") {
78
+ ExifInterface(photoUri.path!!)
84
79
  } else {
85
- context.contentResolver.openInputStream(photoUri)
80
+ val inputStream =
81
+ if (scheme == "content" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
82
+ try {
83
+ context.contentResolver.openInputStream(MediaStore.setRequireOriginal(photoUri))
84
+ } catch (_: SecurityException) {
85
+ context.contentResolver.openInputStream(photoUri)
86
+ }
87
+ } else if (scheme == "http" || scheme == "https") {
88
+ java.net.URL(uri).openStream()
89
+ } else {
90
+ context.contentResolver.openInputStream(photoUri)
91
+ }
92
+
93
+ if (inputStream == null) {
94
+ RNLog.w(context, "Exify: Could not open URI: $uri")
95
+ promise.reject(ERROR_TAG, "Could not open URI: $uri")
96
+ return
97
+ }
98
+
99
+ inputStream.use { ExifInterface(it) }
86
100
  }
87
101
 
88
- if (inputStream == null) {
89
- RNLog.w(context, "Exify: Could not open URI: $uri")
90
- promise.reject(ERROR_TAG, "Could not open URI: $uri")
91
- return
92
- }
102
+ val tags = formatTags(exif)
93
103
 
94
- inputStream.use {
95
- val tags = formatTags(ExifInterface(it))
96
- promise.resolve(tags)
104
+ // ExifInterface ignores IFD0 tags placed in ExifIFD (non-standard but common
105
+ // with some image editors). Fall back to raw EXIF parsing for missing tags.
106
+ val missingTags =
107
+ IFD0_FALLBACK_TAGS
108
+ .filter {
109
+ if (!tags.hasKey(it)) return@filter true
110
+ val type = tags.getType(it)
111
+ (type == ReadableType.Number && tags.getDouble(it) == 0.0)
112
+ }.toSet()
113
+ if (missingTags.isNotEmpty()) {
114
+ val fallback =
115
+ try {
116
+ openInputStream(uri, photoUri, scheme)?.use { readFallbackTags(it, missingTags) }
117
+ } catch (_: Exception) {
118
+ null
119
+ }
120
+ fallback?.forEach { (tag, value) ->
121
+ when (value) {
122
+ is String -> tags.putString(tag, value)
123
+ is Int -> tags.putInt(tag, value)
124
+ is Double -> tags.putDouble(tag, value)
125
+ }
126
+ }
97
127
  }
128
+
129
+ promise.resolve(tags)
98
130
  } catch (e: Exception) {
99
131
  RNLog.w(context, "Exify: ${e.message}")
100
132
  promise.reject(ERROR_TAG, e.message, e)
101
133
  }
102
134
  }
103
135
 
136
+ private fun openInputStream(
137
+ uri: String,
138
+ photoUri: Uri,
139
+ scheme: String,
140
+ ): java.io.InputStream? =
141
+ when (scheme) {
142
+ "file" -> File(photoUri.path!!).inputStream()
143
+ "content" -> context.contentResolver.openInputStream(photoUri)
144
+ else -> java.net.URL(uri).openStream()
145
+ }
146
+
104
147
  @Throws(IOException::class)
105
148
  override fun write(
106
149
  uri: String,
@@ -141,7 +184,10 @@ class ExifyModule(
141
184
  exif.setAttribute(tag, value.toBigDecimal().toPlainString())
142
185
  }
143
186
  }
144
- else -> exif.setAttribute(tag, tags.getDouble(tag).toInt().toString())
187
+
188
+ else -> {
189
+ exif.setAttribute(tag, tags.getDouble(tag).toInt().toString())
190
+ }
145
191
  }
146
192
  }
147
193
 
@@ -150,7 +196,9 @@ class ExifyModule(
150
196
  }
151
197
 
152
198
  ReadableType.Array -> {
153
- exif.setAttribute(tag, tags.getArray(tag).toString())
199
+ val arr = tags.getArray(tag)!!
200
+ val values = (0 until arr.size()).joinToString(", ") { arr.getInt(it).toString() }
201
+ exif.setAttribute(tag, values)
154
202
  }
155
203
 
156
204
  else -> {
@@ -2,6 +2,24 @@ package com.lodev09.exify
2
2
 
3
3
  import androidx.exifinterface.media.ExifInterface
4
4
 
5
+ /**
6
+ * IFD0 tags that ExifInterface may fail to read when they are
7
+ * incorrectly placed inside the ExifIFD by some image editors.
8
+ */
9
+ val IFD0_FALLBACK_TAGS =
10
+ setOf(
11
+ ExifInterface.TAG_MAKE,
12
+ ExifInterface.TAG_MODEL,
13
+ ExifInterface.TAG_ARTIST,
14
+ ExifInterface.TAG_COPYRIGHT,
15
+ ExifInterface.TAG_IMAGE_DESCRIPTION,
16
+ ExifInterface.TAG_SOFTWARE,
17
+ ExifInterface.TAG_ORIENTATION,
18
+ ExifInterface.TAG_X_RESOLUTION,
19
+ ExifInterface.TAG_Y_RESOLUTION,
20
+ ExifInterface.TAG_RESOLUTION_UNIT,
21
+ )
22
+
5
23
  /**
6
24
  * Supported Exif Tags
7
25
  * Note: Latitude, Longitude and Altitude tags are updated separately
@@ -64,13 +82,14 @@ val EXIFY_TAGS =
64
82
  arrayOf("double", ExifInterface.TAG_FOCAL_LENGTH),
65
83
  arrayOf("string", ExifInterface.TAG_LENS_MAKE),
66
84
  arrayOf("string", ExifInterface.TAG_LENS_MODEL),
85
+ arrayOf("string", ExifInterface.TAG_BODY_SERIAL_NUMBER),
67
86
  arrayOf("array", ExifInterface.TAG_LENS_SPECIFICATION),
68
87
  arrayOf("int", ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM),
69
88
  arrayOf("int", ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT),
70
89
  arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION),
71
90
  arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION),
72
91
  arrayOf("int", ExifInterface.TAG_GAIN_CONTROL),
73
- arrayOf("string", ExifInterface.TAG_ISO_SPEED_RATINGS),
92
+ arrayOf("int_array", ExifInterface.TAG_ISO_SPEED_RATINGS),
74
93
  arrayOf("string", ExifInterface.TAG_IMAGE_UNIQUE_ID),
75
94
  arrayOf("int", ExifInterface.TAG_LIGHT_SOURCE),
76
95
  arrayOf("string", ExifInterface.TAG_MAKER_NOTE),
@@ -2,11 +2,11 @@ package com.lodev09.exify
2
2
 
3
3
  import androidx.exifinterface.media.ExifInterface
4
4
  import com.facebook.react.bridge.Arguments
5
- import com.facebook.react.bridge.ReadableMap
5
+ import com.facebook.react.bridge.WritableMap
6
6
 
7
7
  object ExifyUtils {
8
8
  @JvmStatic
9
- fun formatTags(exif: ExifInterface): ReadableMap {
9
+ fun formatTags(exif: ExifInterface): WritableMap {
10
10
  val tags = Arguments.createMap()
11
11
 
12
12
  for ((type, tag) in EXIFY_TAGS) {
@@ -18,13 +18,23 @@ object ExifyUtils {
18
18
  }
19
19
 
20
20
  "int" -> {
21
- tags.putInt(tag, exif.getAttributeInt(tag, 0))
21
+ val intVal = exif.getAttributeInt(tag, 0)
22
+ if (tag == ExifInterface.TAG_ORIENTATION && intVal == 0) continue
23
+ tags.putInt(tag, intVal)
22
24
  }
23
25
 
24
26
  "double" -> {
25
27
  tags.putDouble(tag, exif.getAttributeDouble(tag, 0.0))
26
28
  }
27
29
 
30
+ "int_array" -> {
31
+ val array = Arguments.createArray()
32
+ attribute.split(", ").forEach { part ->
33
+ part.trim().toIntOrNull()?.let { array.pushInt(it) }
34
+ }
35
+ if (array.size() > 0) tags.putArray(tag, array)
36
+ }
37
+
28
38
  "array" -> {
29
39
  val array = Arguments.createArray()
30
40
  exif.getAttributeRange(tag)?.forEach { value ->
package/ios/Exify.mm CHANGED
@@ -43,6 +43,17 @@ static NSDictionary *getExifTags(NSDictionary *metadata) {
43
43
  if (![value isKindOfClass:[NSDictionary class]] &&
44
44
  ![key isEqualToString:compressionKey]) {
45
45
  tags[key] = value;
46
+
47
+ // Also emit standard EXIF names for CGImageSource-specific keys
48
+ if ([key isEqualToString:@"PixelWidth"]) {
49
+ tags[@"PixelXDimension"] = value;
50
+ } else if ([key isEqualToString:@"PixelHeight"]) {
51
+ tags[@"PixelYDimension"] = value;
52
+ } else if ([key isEqualToString:@"DPIWidth"]) {
53
+ tags[@"XResolution"] = value;
54
+ } else if ([key isEqualToString:@"DPIHeight"]) {
55
+ tags[@"YResolution"] = value;
56
+ }
46
57
  }
47
58
  }
48
59
 
@@ -63,13 +63,14 @@ export interface ExifTags {
63
63
  LightSource?: number;
64
64
  UserComment?: string;
65
65
  GainControl?: number;
66
- ISOSpeedRatings?: string;
66
+ ISOSpeedRatings?: number[];
67
67
  FocalPlaneResolutionUnit?: number;
68
68
  FocalPlaneXResolution?: number;
69
69
  YCbCrCoefficients?: number;
70
70
  FocalLengthIn35mmFilm?: number;
71
71
  LensMake?: string;
72
72
  LensModel?: string;
73
+ BodySerialNumber?: string;
73
74
  LensSpecification?: number[];
74
75
  ISO?: number;
75
76
  FlashpixVersion?: number[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-exify",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Read and write exif data from/into an image",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
package/src/types.ts CHANGED
@@ -63,13 +63,14 @@ export interface ExifTags {
63
63
  LightSource?: number;
64
64
  UserComment?: string;
65
65
  GainControl?: number;
66
- ISOSpeedRatings?: string;
66
+ ISOSpeedRatings?: number[];
67
67
  FocalPlaneResolutionUnit?: number;
68
68
  FocalPlaneXResolution?: number;
69
69
  YCbCrCoefficients?: number;
70
70
  FocalLengthIn35mmFilm?: number;
71
71
  LensMake?: string;
72
72
  LensModel?: string;
73
+ BodySerialNumber?: string;
73
74
  LensSpecification?: number[];
74
75
  ISO?: number;
75
76
  FlashpixVersion?: number[];