Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java
41155 views
1
/*
2
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.imageio.spi;
27
28
import java.io.IOException;
29
import java.lang.reflect.Constructor;
30
import java.lang.reflect.Method;
31
import java.security.AccessController;
32
import java.security.PrivilegedAction;
33
import java.util.Arrays;
34
import java.util.Iterator;
35
import javax.imageio.ImageReader;
36
import javax.imageio.metadata.IIOMetadata;
37
import javax.imageio.metadata.IIOMetadataFormat;
38
import javax.imageio.metadata.IIOMetadataFormatImpl;
39
import javax.imageio.stream.ImageInputStream;
40
41
/**
42
* A superclass containing instance variables and methods common to
43
* {@code ImageReaderSpi} and {@code ImageWriterSpi}.
44
*
45
* @see IIORegistry
46
* @see ImageReaderSpi
47
* @see ImageWriterSpi
48
*
49
*/
50
public abstract class ImageReaderWriterSpi extends IIOServiceProvider {
51
52
/**
53
* An array of strings to be returned from
54
* {@code getFormatNames}, initially {@code null}.
55
* Constructors should set this to a non-{@code null} value.
56
*/
57
protected String[] names = null;
58
59
/**
60
* An array of strings to be returned from
61
* {@code getFileSuffixes}, initially {@code null}.
62
*/
63
protected String[] suffixes = null;
64
65
/**
66
* An array of strings to be returned from
67
* {@code getMIMETypes}, initially {@code null}.
68
*/
69
protected String[] MIMETypes = null;
70
71
/**
72
* A {@code String} containing the name of the associated
73
* plug-in class, initially {@code null}.
74
*/
75
protected String pluginClassName = null;
76
77
/**
78
* A boolean indicating whether this plug-in supports the
79
* standard metadata format for stream metadata, initially
80
* {@code false}.
81
*/
82
protected boolean supportsStandardStreamMetadataFormat = false;
83
84
/**
85
* A {@code String} containing the name of the native stream
86
* metadata format supported by this plug-in, initially
87
* {@code null}.
88
*/
89
protected String nativeStreamMetadataFormatName = null;
90
91
/**
92
* A {@code String} containing the class name of the native
93
* stream metadata format supported by this plug-in, initially
94
* {@code null}.
95
*/
96
protected String nativeStreamMetadataFormatClassName = null;
97
98
/**
99
* An array of {@code String}s containing the names of any
100
* additional stream metadata formats supported by this plug-in,
101
* initially {@code null}.
102
*/
103
protected String[] extraStreamMetadataFormatNames = null;
104
105
/**
106
* An array of {@code String}s containing the class names of
107
* any additional stream metadata formats supported by this plug-in,
108
* initially {@code null}.
109
*/
110
protected String[] extraStreamMetadataFormatClassNames = null;
111
112
/**
113
* A boolean indicating whether this plug-in supports the
114
* standard metadata format for image metadata, initially
115
* {@code false}.
116
*/
117
protected boolean supportsStandardImageMetadataFormat = false;
118
119
/**
120
* A {@code String} containing the name of the
121
* native stream metadata format supported by this plug-in,
122
* initially {@code null}.
123
*/
124
protected String nativeImageMetadataFormatName = null;
125
126
/**
127
* A {@code String} containing the class name of the
128
* native stream metadata format supported by this plug-in,
129
* initially {@code null}.
130
*/
131
protected String nativeImageMetadataFormatClassName = null;
132
133
/**
134
* An array of {@code String}s containing the names of any
135
* additional image metadata formats supported by this plug-in,
136
* initially {@code null}.
137
*/
138
protected String[] extraImageMetadataFormatNames = null;
139
140
/**
141
* An array of {@code String}s containing the class names of
142
* any additional image metadata formats supported by this
143
* plug-in, initially {@code null}.
144
*/
145
protected String[] extraImageMetadataFormatClassNames = null;
146
147
/**
148
* Constructs an {@code ImageReaderWriterSpi} with a given
149
* set of values.
150
*
151
* @param vendorName the vendor name, as a non-{@code null}
152
* {@code String}.
153
* @param version a version identifier, as a non-{@code null}
154
* {@code String}.
155
* @param names a non-{@code null} array of
156
* {@code String}s indicating the format names. At least one
157
* entry must be present.
158
* @param suffixes an array of {@code String}s indicating the
159
* common file suffixes. If no suffixes are defined,
160
* {@code null} should be supplied. An array of length 0
161
* will be normalized to {@code null}.
162
* @param MIMETypes an array of {@code String}s indicating
163
* the format's MIME types. If no MIME types are defined,
164
* {@code null} should be supplied. An array of length 0
165
* will be normalized to {@code null}.
166
* @param pluginClassName the fully-qualified name of the
167
* associated {@code ImageReader} or {@code ImageWriter}
168
* class, as a non-{@code null String}.
169
* @param supportsStandardStreamMetadataFormat a
170
* {@code boolean} that indicates whether a stream metadata
171
* object can use trees described by the standard metadata format.
172
* @param nativeStreamMetadataFormatName a
173
* {@code String}, or {@code null}, to be returned from
174
* {@code getNativeStreamMetadataFormatName}.
175
* @param nativeStreamMetadataFormatClassName a
176
* {@code String}, or {@code null}, to be used to instantiate
177
* a metadata format object to be returned from
178
* {@code getNativeStreamMetadataFormat}.
179
* @param extraStreamMetadataFormatNames an array of
180
* {@code String}s, or {@code null}, to be returned from
181
* {@code getExtraStreamMetadataFormatNames}. An array of length
182
* 0 is normalized to {@code null}.
183
* @param extraStreamMetadataFormatClassNames an array of
184
* {@code String}s, or {@code null}, to be used to instantiate
185
* a metadata format object to be returned from
186
* {@code getStreamMetadataFormat}. An array of length
187
* 0 is normalized to {@code null}.
188
* @param supportsStandardImageMetadataFormat a
189
* {@code boolean} that indicates whether an image metadata
190
* object can use trees described by the standard metadata format.
191
* @param nativeImageMetadataFormatName a
192
* {@code String}, or {@code null}, to be returned from
193
* {@code getNativeImageMetadataFormatName}.
194
* @param nativeImageMetadataFormatClassName a
195
* {@code String}, or {@code null}, to be used to instantiate
196
* a metadata format object to be returned from
197
* {@code getNativeImageMetadataFormat}.
198
* @param extraImageMetadataFormatNames an array of
199
* {@code String}s to be returned from
200
* {@code getExtraImageMetadataFormatNames}. An array of length 0
201
* is normalized to {@code null}.
202
* @param extraImageMetadataFormatClassNames an array of
203
* {@code String}s, or {@code null}, to be used to instantiate
204
* a metadata format object to be returned from
205
* {@code getImageMetadataFormat}. An array of length
206
* 0 is normalized to {@code null}.
207
*
208
* @exception IllegalArgumentException if {@code vendorName}
209
* is {@code null}.
210
* @exception IllegalArgumentException if {@code version}
211
* is {@code null}.
212
* @exception IllegalArgumentException if {@code names}
213
* is {@code null} or has length 0.
214
* @exception IllegalArgumentException if {@code pluginClassName}
215
* is {@code null}.
216
*/
217
public ImageReaderWriterSpi(String vendorName,
218
String version,
219
String[] names,
220
String[] suffixes,
221
String[] MIMETypes,
222
String pluginClassName,
223
boolean supportsStandardStreamMetadataFormat,
224
String nativeStreamMetadataFormatName,
225
String nativeStreamMetadataFormatClassName,
226
String[] extraStreamMetadataFormatNames,
227
String[] extraStreamMetadataFormatClassNames,
228
boolean supportsStandardImageMetadataFormat,
229
String nativeImageMetadataFormatName,
230
String nativeImageMetadataFormatClassName,
231
String[] extraImageMetadataFormatNames,
232
String[] extraImageMetadataFormatClassNames) {
233
super(vendorName, version);
234
if (names == null) {
235
throw new IllegalArgumentException("names == null!");
236
}
237
if (names.length == 0) {
238
throw new IllegalArgumentException("names.length == 0!");
239
}
240
if (pluginClassName == null) {
241
throw new IllegalArgumentException("pluginClassName == null!");
242
}
243
244
this.names = names.clone();
245
// If length == 0, leave it null
246
if (suffixes != null && suffixes.length > 0) {
247
this.suffixes = suffixes.clone();
248
}
249
// If length == 0, leave it null
250
if (MIMETypes != null && MIMETypes.length > 0) {
251
this.MIMETypes = MIMETypes.clone();
252
}
253
this.pluginClassName = pluginClassName;
254
255
this.supportsStandardStreamMetadataFormat =
256
supportsStandardStreamMetadataFormat;
257
this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
258
this.nativeStreamMetadataFormatClassName =
259
nativeStreamMetadataFormatClassName;
260
// If length == 0, leave it null
261
if (extraStreamMetadataFormatNames != null &&
262
extraStreamMetadataFormatNames.length > 0) {
263
this.extraStreamMetadataFormatNames =
264
extraStreamMetadataFormatNames.clone();
265
}
266
// If length == 0, leave it null
267
if (extraStreamMetadataFormatClassNames != null &&
268
extraStreamMetadataFormatClassNames.length > 0) {
269
this.extraStreamMetadataFormatClassNames =
270
extraStreamMetadataFormatClassNames.clone();
271
}
272
this.supportsStandardImageMetadataFormat =
273
supportsStandardImageMetadataFormat;
274
this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
275
this.nativeImageMetadataFormatClassName =
276
nativeImageMetadataFormatClassName;
277
// If length == 0, leave it null
278
if (extraImageMetadataFormatNames != null &&
279
extraImageMetadataFormatNames.length > 0) {
280
this.extraImageMetadataFormatNames =
281
extraImageMetadataFormatNames.clone();
282
}
283
// If length == 0, leave it null
284
if (extraImageMetadataFormatClassNames != null &&
285
extraImageMetadataFormatClassNames.length > 0) {
286
this.extraImageMetadataFormatClassNames =
287
extraImageMetadataFormatClassNames.clone();
288
}
289
}
290
291
/**
292
* Constructs a blank {@code ImageReaderWriterSpi}. It is up
293
* to the subclass to initialize instance variables and/or
294
* override method implementations in order to provide working
295
* versions of all methods.
296
*/
297
public ImageReaderWriterSpi() {
298
}
299
300
/**
301
* Returns an array of {@code String}s containing
302
* human-readable names for the formats that are generally usable
303
* by the {@code ImageReader} or {@code ImageWriter}
304
* implementation associated with this service provider. For
305
* example, a single {@code ImageReader} might be able to
306
* process both PBM and PNM files.
307
*
308
* @return a non-{@code null} array of {@code String}s
309
* or length at least 1 containing informal format names
310
* associated with this reader or writer.
311
*/
312
public String[] getFormatNames() {
313
return names.clone();
314
}
315
316
/**
317
* Returns an array of {@code String}s containing a list of
318
* file suffixes associated with the formats that are generally
319
* usable by the {@code ImageReader} or
320
* {@code ImageWriter} implementation associated with this
321
* service provider. For example, a single
322
* {@code ImageReader} might be able to process files with
323
* '.pbm' and '.pnm' suffixes, or both '.jpg' and '.jpeg'
324
* suffixes. If there are no known file suffixes,
325
* {@code null} will be returned.
326
*
327
* <p> Returning a particular suffix does not guarantee that files
328
* with that suffix can be processed; it merely indicates that it
329
* may be worthwhile attempting to decode or encode such files
330
* using this service provider.
331
*
332
* @return an array of {@code String}s or length at least 1
333
* containing common file suffixes associated with this reader or
334
* writer, or {@code null}.
335
*/
336
public String[] getFileSuffixes() {
337
return suffixes == null ? null : suffixes.clone();
338
}
339
340
/**
341
* Returns an array of {@code String}s containing a list of
342
* MIME types associated with the formats that are generally
343
* usable by the {@code ImageReader} or
344
* {@code ImageWriter} implementation associated with this
345
* service provider.
346
*
347
* <p> Ideally, only a single MIME type would be required in order
348
* to describe a particular format. However, for several reasons
349
* it is necessary to associate a list of types with each service
350
* provider. First, many common image file formats do not have
351
* standard MIME types, so a list of commonly used unofficial
352
* names will be required, such as {@code image/x-pbm} and
353
* {@code image/x-portable-bitmap}. Some file formats have
354
* official MIME types but may sometimes be referred to using
355
* their previous unofficial designations, such as
356
* {@code image/x-png} instead of the official
357
* {@code image/png}. Finally, a single service provider may
358
* be capable of parsing multiple distinct types from the MIME
359
* point of view, for example {@code image/x-xbitmap} and
360
* {@code image/x-xpixmap}.
361
*
362
* <p> Returning a particular MIME type does not guarantee that
363
* files claiming to be of that type can be processed; it merely
364
* indicates that it may be worthwhile attempting to decode or
365
* encode such files using this service provider.
366
*
367
* @return an array of {@code String}s or length at least 1
368
* containing MIME types associated with this reader or writer, or
369
* {@code null}.
370
*/
371
public String[] getMIMETypes() {
372
return MIMETypes == null ? null : MIMETypes.clone();
373
}
374
375
/**
376
* Returns the fully-qualified class name of the
377
* {@code ImageReader} or {@code ImageWriter} plug-in
378
* associated with this service provider.
379
*
380
* @return the class name, as a non-{@code null}
381
* {@code String}.
382
*/
383
public String getPluginClassName() {
384
return pluginClassName;
385
}
386
387
/**
388
* Returns {@code true} if the standard metadata format is
389
* among the document formats recognized by the
390
* {@code getAsTree} and {@code setFromTree} methods on
391
* the stream metadata objects produced or consumed by this
392
* plug-in.
393
*
394
* @return {@code true} if the standard format is supported
395
* for stream metadata.
396
*/
397
public boolean isStandardStreamMetadataFormatSupported() {
398
return supportsStandardStreamMetadataFormat;
399
}
400
401
/**
402
* Returns the name of the "native" stream metadata format for
403
* this plug-in, which typically allows for lossless encoding and
404
* transmission of the stream metadata stored in the format handled by
405
* this plug-in. If no such format is supported,
406
* {@code null} will be returned.
407
*
408
* <p> The default implementation returns the
409
* {@code nativeStreamMetadataFormatName} instance variable,
410
* which is typically set by the constructor.
411
*
412
* @return the name of the native stream metadata format, or
413
* {@code null}.
414
*
415
*/
416
public String getNativeStreamMetadataFormatName() {
417
return nativeStreamMetadataFormatName;
418
}
419
420
/**
421
* Returns an array of {@code String}s containing the names
422
* of additional document formats, other than the native and
423
* standard formats, recognized by the
424
* {@code getAsTree} and {@code setFromTree} methods on
425
* the stream metadata objects produced or consumed by this
426
* plug-in.
427
*
428
* <p> If the plug-in does not handle metadata, null should be
429
* returned.
430
*
431
* <p> The set of formats may differ according to the particular
432
* images being read or written; this method should indicate all
433
* the additional formats supported by the plug-in under any
434
* circumstances.
435
*
436
* <p> The default implementation returns a clone of the
437
* {@code extraStreamMetadataFormatNames} instance variable,
438
* which is typically set by the constructor.
439
*
440
* @return an array of {@code String}s, or null.
441
*
442
* @see IIOMetadata#getMetadataFormatNames
443
* @see #getExtraImageMetadataFormatNames
444
* @see #getNativeStreamMetadataFormatName
445
*/
446
public String[] getExtraStreamMetadataFormatNames() {
447
return extraStreamMetadataFormatNames == null ?
448
null : extraStreamMetadataFormatNames.clone();
449
}
450
451
/**
452
* Returns {@code true} if the standard metadata format is
453
* among the document formats recognized by the
454
* {@code getAsTree} and {@code setFromTree} methods on
455
* the image metadata objects produced or consumed by this
456
* plug-in.
457
*
458
* @return {@code true} if the standard format is supported
459
* for image metadata.
460
*/
461
public boolean isStandardImageMetadataFormatSupported() {
462
return supportsStandardImageMetadataFormat;
463
}
464
465
/**
466
* Returns the name of the "native" image metadata format for
467
* this plug-in, which typically allows for lossless encoding and
468
* transmission of the image metadata stored in the format handled by
469
* this plug-in. If no such format is supported,
470
* {@code null} will be returned.
471
*
472
* <p> The default implementation returns the
473
* {@code nativeImageMetadataFormatName} instance variable,
474
* which is typically set by the constructor.
475
*
476
* @return the name of the native image metadata format, or
477
* {@code null}.
478
*
479
* @see #getExtraImageMetadataFormatNames
480
*/
481
public String getNativeImageMetadataFormatName() {
482
return nativeImageMetadataFormatName;
483
}
484
485
/**
486
* Returns an array of {@code String}s containing the names
487
* of additional document formats, other than the native and
488
* standard formats, recognized by the
489
* {@code getAsTree} and {@code setFromTree} methods on
490
* the image metadata objects produced or consumed by this
491
* plug-in.
492
*
493
* <p> If the plug-in does not handle image metadata, null should
494
* be returned.
495
*
496
* <p> The set of formats may differ according to the particular
497
* images being read or written; this method should indicate all
498
* the additional formats supported by the plug-in under any circumstances.
499
*
500
* <p> The default implementation returns a clone of the
501
* {@code extraImageMetadataFormatNames} instance variable,
502
* which is typically set by the constructor.
503
*
504
* @return an array of {@code String}s, or null.
505
*
506
* @see IIOMetadata#getMetadataFormatNames
507
* @see #getExtraStreamMetadataFormatNames
508
* @see #getNativeImageMetadataFormatName
509
*/
510
public String[] getExtraImageMetadataFormatNames() {
511
return extraImageMetadataFormatNames == null ?
512
null : extraImageMetadataFormatNames.clone();
513
}
514
515
/**
516
* Returns an {@code IIOMetadataFormat} object describing the
517
* given stream metadata format, or {@code null} if no
518
* description is available. The supplied name must be the native
519
* stream metadata format name, the standard metadata format name,
520
* or one of those returned by
521
* {@code getExtraStreamMetadataFormatNames}.
522
*
523
* @param formatName the desired stream metadata format.
524
*
525
* @return an {@code IIOMetadataFormat} object.
526
*
527
* @exception IllegalArgumentException if {@code formatName}
528
* is {@code null} or is not a supported name.
529
*/
530
public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
531
return getMetadataFormat(formatName,
532
supportsStandardStreamMetadataFormat,
533
nativeStreamMetadataFormatName,
534
nativeStreamMetadataFormatClassName,
535
extraStreamMetadataFormatNames,
536
extraStreamMetadataFormatClassNames);
537
}
538
539
/**
540
* Returns an {@code IIOMetadataFormat} object describing the
541
* given image metadata format, or {@code null} if no
542
* description is available. The supplied name must be the native
543
* image metadata format name, the standard metadata format name,
544
* or one of those returned by
545
* {@code getExtraImageMetadataFormatNames}.
546
*
547
* @param formatName the desired image metadata format.
548
*
549
* @return an {@code IIOMetadataFormat} object.
550
*
551
* @exception IllegalArgumentException if {@code formatName}
552
* is {@code null} or is not a supported name.
553
*/
554
public IIOMetadataFormat getImageMetadataFormat(String formatName) {
555
return getMetadataFormat(formatName,
556
supportsStandardImageMetadataFormat,
557
nativeImageMetadataFormatName,
558
nativeImageMetadataFormatClassName,
559
extraImageMetadataFormatNames,
560
extraImageMetadataFormatClassNames);
561
}
562
563
private IIOMetadataFormat getMetadataFormat(String formatName,
564
boolean supportsStandard,
565
String nativeName,
566
String nativeClassName,
567
String [] extraNames,
568
String [] extraClassNames) {
569
if (formatName == null) {
570
throw new IllegalArgumentException("formatName == null!");
571
}
572
if (supportsStandard && formatName.equals
573
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
574
575
return IIOMetadataFormatImpl.getStandardFormatInstance();
576
}
577
String formatClassName = null;
578
if (formatName.equals(nativeName)) {
579
formatClassName = nativeClassName;
580
} else if (extraNames != null) {
581
for (int i = 0; i < extraNames.length; i++) {
582
if (formatName.equals(extraNames[i])) {
583
formatClassName = extraClassNames[i];
584
break; // out of for
585
}
586
}
587
}
588
if (formatClassName == null) {
589
throw new IllegalArgumentException("Unsupported format name");
590
}
591
try {
592
// Try to load from the same location as the module of the SPI
593
final String className = formatClassName;
594
PrivilegedAction<Class<?>> pa = () -> { return getMetadataFormatClass(className); };
595
@SuppressWarnings("removal")
596
Class<?> cls = AccessController.doPrivileged(pa);
597
Method meth = cls.getMethod("getInstance");
598
return (IIOMetadataFormat) meth.invoke(null);
599
} catch (Exception e) {
600
RuntimeException ex =
601
new IllegalStateException ("Can't obtain format");
602
ex.initCause(e);
603
throw ex;
604
}
605
}
606
607
// If updating this method also see the same in IIOMetadata.java
608
private Class<?> getMetadataFormatClass(String formatClassName) {
609
Module thisModule = ImageReaderWriterSpi.class.getModule();
610
Module targetModule = this.getClass().getModule();
611
Class<?> c = null;
612
try {
613
ClassLoader cl = this.getClass().getClassLoader();
614
c = Class.forName(formatClassName, false, cl);
615
if (!IIOMetadataFormat.class.isAssignableFrom(c)) {
616
return null;
617
}
618
} catch (ClassNotFoundException e) {
619
}
620
if (thisModule.equals(targetModule) || c == null) {
621
return c;
622
}
623
if (targetModule.isNamed()) {
624
int i = formatClassName.lastIndexOf(".");
625
String pn = i > 0 ? formatClassName.substring(0, i) : "";
626
if (!targetModule.isExported(pn, thisModule)) {
627
throw new IllegalStateException("Class " + formatClassName +
628
" in named module must be exported to java.desktop module.");
629
}
630
}
631
return c;
632
}
633
}
634
635