Source Code Cross Referenced for TIFFDirectory.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » imageio » plugins » tiff » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » com.sun.media.imageio.plugins.tiff 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: TIFFDirectory.java,v $
003:         *
004:         * 
005:         * Copyright (c) 2006 Sun Microsystems, Inc. All  Rights Reserved.
006:         * 
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met: 
010:         * 
011:         * - Redistribution of source code must retain the above copyright 
012:         *   notice, this  list of conditions and the following disclaimer.
013:         * 
014:         * - Redistribution in binary form must reproduce the above copyright
015:         *   notice, this list of conditions and the following disclaimer in 
016:         *   the documentation and/or other materials provided with the
017:         *   distribution.
018:         * 
019:         * Neither the name of Sun Microsystems, Inc. or the names of 
020:         * contributors may be used to endorse or promote products derived 
021:         * from this software without specific prior written permission.
022:         * 
023:         * This software is provided "AS IS," without a warranty of any 
024:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 
025:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 
026:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027:         * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 
028:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
029:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 
031:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035:         * POSSIBILITY OF SUCH DAMAGES. 
036:         * 
037:         * You acknowledge that this software is not designed or intended for 
038:         * use in the design, construction, operation or maintenance of any 
039:         * nuclear facility. 
040:         *
041:         * $Revision: 1.4 $
042:         * $Date: 2006/08/25 00:16:49 $
043:         * $State: Exp $
044:         */
045:        package com.sun.media.imageio.plugins.tiff;
046:
047:        import java.util.ArrayList;
048:        import java.util.Arrays;
049:        import java.util.Iterator;
050:        import java.util.List;
051:        import java.util.Map;
052:        import java.util.NoSuchElementException;
053:        import java.util.Set;
054:        import java.util.TreeMap;
055:        import javax.imageio.metadata.IIOInvalidTreeException;
056:        import javax.imageio.metadata.IIOMetadata;
057:        import javax.imageio.metadata.IIOMetadataFormatImpl;
058:        import org.w3c.dom.Node;
059:        import com.sun.media.imageioimpl.plugins.tiff.TIFFIFD;
060:        import com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata;
061:
062:        /**
063:         * A convenience class for simplifying interaction with TIFF native
064:         * image metadata. A TIFF image metadata tree represents an Image File
065:         * Directory (IFD) from a TIFF 6.0 stream. An IFD consists of a number of
066:         * IFD Entries each of which associates an identifying tag number with
067:         * a compatible value. A <code>TIFFDirectory</code> instance corresponds
068:         * to an IFD and contains a set of {@link TIFFField}s each of which
069:         * corresponds to an IFD Entry in the IFD.
070:         *
071:         * <p>When reading, a <code>TIFFDirectory</code> may be created by passing
072:         * the value returned by {@link javax.imageio.ImageReader#getImageMetadata
073:         * ImageReader.getImageMetadata()} to {@link #createFromMetadata
074:         * createFromMetadata()}. The {@link TIFFField}s in the directory may then
075:         * be obtained using the accessor methods provided in this class.</p>
076:         *
077:         * <p>When writing, an {@link IIOMetadata} object for use by one of the
078:         * <core>write()</code> methods of {@link javax.imageio.ImageWriter} may be
079:         * created from a <code>TIFFDirectory</code> by {@link #getAsMetadata()}.
080:         * The <code>TIFFDirectory</code> itself may be created by construction or
081:         * from the <code>IIOMetadata</code> object returned by
082:         * {@link javax.imageio.ImageWriter#getDefaultImageMetadata
083:         * ImageWriter.getDefaultImageMetadata()}. The <code>TIFFField</code>s in the
084:         * directory may be set using the mutator methods provided in this class.</p>
085:         *
086:         * <p>A <code>TIFFDirectory</code> is aware of the tag numbers in the
087:         * group of {@link TIFFTagSet}s associated with it. When
088:         * a <code>TIFFDirectory</code> is created from a native image metadata
089:         * object, these tag sets are derived from the <tt>tagSets</tt> attribute
090:         * of the <tt>TIFFIFD</tt> node.</p>
091:         *
092:         * <p>A <code>TIFFDirectory</code> might also have a parent {@link TIFFTag}.
093:         * This will occur if the directory represents an IFD other than the root
094:         * IFD of the image. The parent tag is the tag of the IFD Entry which is a
095:         * pointer to the IFD represented by this <code>TIFFDirectory</code>. The
096:         * {@link TIFFTag#isIFDPointer} method of this parent <code>TIFFTag</code>
097:         * must return <code>true</code>.  When a <code>TIFFDirectory</code> is
098:         * created from a native image metadata object, the parent tag set is set
099:         * from the <tt>parentTagName</tt> attribute of the corresponding
100:         * <tt>TIFFIFD</tt> node. Note that a <code>TIFFDirectory</code> instance
101:         * which has a non-<code>null</code> parent tag will be contained in the
102:         * data field of a <code>TIFFField</code> instance which has a tag field
103:         * equal to the contained directory's parent tag.</p>
104:         * 
105:         * <p>As an example consider an EXIF image. The <code>TIFFDirectory</code>
106:         * instance corresponding to the EXIF IFD in the EXIF stream would have parent
107:         * tag {@link EXIFParentTIFFTagSet#TAG_EXIF_IFD_POINTER TAG_EXIF_IFD_POINTER}
108:         * and would include {@link EXIFTIFFTagSet} in its group of known tag sets.
109:         * The <code>TIFFDirectory</code> corresponding to this EXIF IFD will be
110:         * contained in the data field of a <code>TIFFField</code> which will in turn
111:         * be contained in the <code>TIFFDirectory</code> corresponding to the primary
112:         * IFD of the EXIF image which will itself have a <code>null</code>-valued
113:         * parent tag.</p>
114:         *
115:         * <p><b>Note that this implementation is not synchronized.</b> If multiple
116:         * threads use a <code>TIFFDirectory</code> instance concurrently, and at
117:         * least one of the threads modifies the directory, for example, by adding
118:         * or removing <code>TIFFField</code>s or <code>TIFFTagSet</code>s, it
119:         * <i>must</i> be synchronized externally.</p>
120:         *
121:         * @see IIOMetadata
122:         * @see TIFFField
123:         * @see TIFFTag
124:         * @see TIFFTagSet
125:         *
126:         * @since 1.1-beta
127:         */
128:        // XXX doc: not thread safe
129:        public class TIFFDirectory implements  Cloneable {
130:
131:            /** The largest low-valued tag number in the TIFF 6.0 specification. */
132:            private static final int MAX_LOW_FIELD_TAG_NUM = BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE;
133:
134:            /** The <code>TIFFTagSets</code> associated with this directory. */
135:            private List tagSets;
136:
137:            /** The parent <code>TIFFTag</code> of this directory. */
138:            private TIFFTag parentTag;
139:
140:            /**
141:             * The fields in this directory which have a low tag number. These are
142:             * managed as an array for efficiency as they are the most common fields.
143:             */
144:            private TIFFField[] lowFields = new TIFFField[MAX_LOW_FIELD_TAG_NUM + 1];
145:
146:            /** The number of low tag numbered fields in the directory. */
147:            private int numLowFields = 0;
148:
149:            /**
150:             * A mapping of <code>Integer</code> tag numbers to <code>TIFFField</code>s
151:             * for fields which are not low tag numbered.
152:             */
153:            private Map highFields = new TreeMap();
154:
155:            /**
156:             * Creates a <code>TIFFDirectory</code> instance from the contents of
157:             * an image metadata object. The supplied object must support an image
158:             * metadata format supported by the TIFF {@link javax.imageio.ImageWriter}
159:             * plug-in. This will usually be either the TIFF native image metadata
160:             * format <tt>com_sun_media_imageio_plugins_tiff_1.0</tt> or the Java
161:             * Image I/O standard metadata format <tt>javax_imageio_1.0</tt>.
162:             *
163:             * @param tiffImageMetadata A metadata object which supports a compatible
164:             * image metadata format.
165:             * 
166:             * @return A <code>TIFFDirectory</code> populated from the contents of
167:             * the supplied metadata object.
168:             *
169:             * @throws IllegalArgumentException if <code>tiffImageMetadata</code>
170:             * is <code>null</code>.
171:             * @throws IllegalArgumentException if <code>tiffImageMetadata</code>
172:             * does not support a compatible image metadata format.
173:             * @throws IIOInvalidTreeException if the supplied metadata object
174:             * cannot be parsed.
175:             */
176:            public static TIFFDirectory createFromMetadata(
177:                    IIOMetadata tiffImageMetadata)
178:                    throws IIOInvalidTreeException {
179:
180:                if (tiffImageMetadata == null) {
181:                    throw new IllegalArgumentException(
182:                            "tiffImageMetadata == null");
183:                }
184:
185:                TIFFImageMetadata tim;
186:                if (tiffImageMetadata instanceof  TIFFImageMetadata) {
187:                    tim = (TIFFImageMetadata) tiffImageMetadata;
188:                } else {
189:                    // Create a native metadata object.
190:                    ArrayList l = new ArrayList(1);
191:                    l.add(BaselineTIFFTagSet.getInstance());
192:                    tim = new TIFFImageMetadata(l);
193:
194:                    // Determine the format name to use.
195:                    String formatName = null;
196:                    if (TIFFImageMetadata.nativeMetadataFormatName
197:                            .equals(tiffImageMetadata
198:                                    .getNativeMetadataFormatName())) {
199:                        formatName = TIFFImageMetadata.nativeMetadataFormatName;
200:                    } else {
201:                        String[] extraNames = tiffImageMetadata
202:                                .getExtraMetadataFormatNames();
203:                        if (extraNames != null) {
204:                            for (int i = 0; i < extraNames.length; i++) {
205:                                if (TIFFImageMetadata.nativeMetadataFormatName
206:                                        .equals(extraNames[i])) {
207:                                    formatName = extraNames[i];
208:                                    break;
209:                                }
210:                            }
211:                        }
212:
213:                        if (formatName == null) {
214:                            if (tiffImageMetadata
215:                                    .isStandardMetadataFormatSupported()) {
216:                                formatName = IIOMetadataFormatImpl.standardMetadataFormatName;
217:                            } else {
218:                                throw new IllegalArgumentException(
219:                                        "Parameter does not support required metadata format!");
220:                            }
221:                        }
222:                    }
223:
224:                    // Set the native metadata object from the tree.
225:                    tim.setFromTree(formatName, tiffImageMetadata
226:                            .getAsTree(formatName));
227:                }
228:
229:                return tim.getRootIFD();
230:            }
231:
232:            /**
233:             * Converts a <code>TIFFDirectory</code> to a <code>TIFFIFD</code>.
234:             */
235:            private static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) {
236:                if (dir instanceof  TIFFIFD) {
237:                    return (TIFFIFD) dir;
238:                }
239:
240:                TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()), dir
241:                        .getParentTag());
242:                TIFFField[] fields = dir.getTIFFFields();
243:                int numFields = fields.length;
244:                for (int i = 0; i < numFields; i++) {
245:                    TIFFField f = fields[i];
246:                    TIFFTag tag = f.getTag();
247:                    if (tag.isIFDPointer()) {
248:                        TIFFDirectory subIFD = getDirectoryAsIFD((TIFFDirectory) f
249:                                .getData());
250:                        f = new TIFFField(tag, f.getType(), f.getCount(),
251:                                subIFD);
252:                    }
253:                    ifd.addTIFFField(f);
254:                }
255:
256:                return ifd;
257:            }
258:
259:            /**
260:             * Constructs a <code>TIFFDirectory</code> which is aware of a given
261:             * group of {@link TIFFTagSet}s. An optional parent {@link TIFFTag}
262:             * may also be specified.
263:             *
264:             * @param tagSets The <code>TIFFTagSets</code> associated with this
265:             * directory.
266:             * @param parentTag The parent <code>TIFFTag</code> of this directory;
267:             * may be <code>null</code>.
268:             * @throws IllegalArgumentException if <code>tagSets</code> is
269:             * <code>null</code>.
270:             */
271:            public TIFFDirectory(TIFFTagSet[] tagSets, TIFFTag parentTag) {
272:                if (tagSets == null) {
273:                    throw new IllegalArgumentException("tagSets == null!");
274:                }
275:                this .tagSets = new ArrayList(tagSets.length);
276:                int numTagSets = tagSets.length;
277:                for (int i = 0; i < numTagSets; i++) {
278:                    this .tagSets.add(tagSets[i]);
279:                }
280:                this .parentTag = parentTag;
281:            }
282:
283:            /**
284:             * Returns the {@link TIFFTagSet}s of which this directory is aware.
285:             *
286:             * @return The <code>TIFFTagSet</code>s associated with this
287:             * <code>TIFFDirectory</code>.
288:             */
289:            public TIFFTagSet[] getTagSets() {
290:                return (TIFFTagSet[]) tagSets.toArray(new TIFFTagSet[tagSets
291:                        .size()]);
292:            }
293:
294:            /**
295:             * Adds an element to the group of {@link TIFFTagSet}s of which this
296:             * directory is aware.
297:             *
298:             * @param tagSet The <code>TIFFTagSet</code> to add.
299:             * @throws IllegalArgumentException if <code>tagSet</code> is
300:             * <code>null</code>.
301:             */
302:            public void addTagSet(TIFFTagSet tagSet) {
303:                if (tagSet == null) {
304:                    throw new IllegalArgumentException("tagSet == null");
305:                }
306:
307:                if (!tagSets.contains(tagSet)) {
308:                    tagSets.add(tagSet);
309:                }
310:            }
311:
312:            /**
313:             * Removes an element from the group of {@link TIFFTagSet}s of which this
314:             * directory is aware.
315:             *
316:             * @param tagSet The <code>TIFFTagSet</code> to remove.
317:             * @throws IllegalArgumentException if <code>tagSet</code> is
318:             * <code>null</code>.
319:             */
320:            public void removeTagSet(TIFFTagSet tagSet) {
321:                if (tagSet == null) {
322:                    throw new IllegalArgumentException("tagSet == null");
323:                }
324:
325:                if (tagSets.contains(tagSet)) {
326:                    tagSets.remove(tagSet);
327:                }
328:            }
329:
330:            /**
331:             * Returns the parent {@link TIFFTag} of this directory if one
332:             * has been defined or <code>null</code> otherwise.
333:             *
334:             * @return The parent <code>TIFFTag</code> of this
335:             * <code>TIFFDiectory</code> or <code>null</code>.
336:             */
337:            public TIFFTag getParentTag() {
338:                return parentTag;
339:            }
340:
341:            /**
342:             * Returns the {@link TIFFTag} which has tag number equal to
343:             * <code>tagNumber</code> or <code>null</code> if no such tag
344:             * exists in the {@link TIFFTagSet}s associated with this
345:             * directory.
346:             *
347:             * @param tagNumber The tag number of interest.
348:             * @return The corresponding <code>TIFFTag</code> or <code>null</code>.
349:             */
350:            public TIFFTag getTag(int tagNumber) {
351:                return TIFFIFD.getTag(tagNumber, tagSets);
352:            }
353:
354:            /**
355:             * Returns the number of {@link TIFFField}s in this directory.
356:             *
357:             * @return The number of <code>TIFFField</code>s in this
358:             * <code>TIFFDirectory</code>.
359:             */
360:            public int getNumTIFFFields() {
361:                return numLowFields + highFields.size();
362:            }
363:
364:            /**
365:             * Determines whether a TIFF field with the given tag number is
366:             * contained in this directory.
367:             *
368:             * @return Whether a {@link TIFFTag} with tag number equal to
369:             * <code>tagNumber</code> is present in this <code>TIFFDirectory</code>.
370:             */
371:            public boolean containsTIFFField(int tagNumber) {
372:                return (tagNumber >= 0 && tagNumber <= MAX_LOW_FIELD_TAG_NUM && lowFields[tagNumber] != null)
373:                        || highFields.containsKey(new Integer(tagNumber));
374:            }
375:
376:            /**
377:             * Adds a TIFF field to the directory.
378:             *
379:             * @param f The field to add.
380:             * @throws IllegalArgumentException if <code>f</code> is <code>null</code>.
381:             */
382:            public void addTIFFField(TIFFField f) {
383:                if (f == null) {
384:                    throw new IllegalArgumentException("f == null");
385:                }
386:                int tagNumber = f.getTagNumber();
387:                if (tagNumber >= 0 && tagNumber <= MAX_LOW_FIELD_TAG_NUM) {
388:                    if (lowFields[tagNumber] == null) {
389:                        numLowFields++;
390:                    }
391:                    lowFields[tagNumber] = f;
392:                } else {
393:                    highFields.put(new Integer(tagNumber), f);
394:                }
395:            }
396:
397:            /**
398:             * Retrieves a TIFF field from the directory.
399:             *
400:             * @param tagNumber The tag number of the tag associated with the field.
401:             * @return A <code>TIFFField</code> with the requested tag number of
402:             * <code>null</code> if no such field is present.
403:             */
404:            public TIFFField getTIFFField(int tagNumber) {
405:                TIFFField f;
406:                if (tagNumber >= 0 && tagNumber <= MAX_LOW_FIELD_TAG_NUM) {
407:                    f = lowFields[tagNumber];
408:                } else {
409:                    f = (TIFFField) highFields.get(new Integer(tagNumber));
410:                }
411:                return f;
412:            }
413:
414:            /**
415:             * Removes a TIFF field from the directory.
416:             *
417:             * @param tagNumber The tag number of the tag associated with the field.
418:             */
419:            public void removeTIFFField(int tagNumber) {
420:                if (tagNumber >= 0 && tagNumber <= MAX_LOW_FIELD_TAG_NUM) {
421:                    if (lowFields[tagNumber] != null) {
422:                        numLowFields--;
423:                        lowFields[tagNumber] = null;
424:                    }
425:                } else {
426:                    highFields.remove(new Integer(tagNumber));
427:                }
428:            }
429:
430:            /**
431:             * Retrieves all TIFF fields from the directory.
432:             *
433:             * @return An array of all TIFF fields in order of numerically increasing
434:             * tag number.
435:             */
436:            public TIFFField[] getTIFFFields() {
437:                // Allocate return value.
438:                TIFFField[] fields = new TIFFField[numLowFields
439:                        + highFields.size()];
440:
441:                // Copy any low-index fields.
442:                int nextIndex = 0;
443:                for (int i = 0; i <= MAX_LOW_FIELD_TAG_NUM; i++) {
444:                    if (lowFields[i] != null) {
445:                        fields[nextIndex++] = lowFields[i];
446:                        if (nextIndex == numLowFields)
447:                            break;
448:                    }
449:                }
450:
451:                // Copy any high-index fields.
452:                if (!highFields.isEmpty()) {
453:                    Iterator keys = highFields.keySet().iterator();
454:                    while (keys.hasNext()) {
455:                        fields[nextIndex++] = (TIFFField) highFields.get(keys
456:                                .next());
457:                    }
458:                }
459:
460:                return fields;
461:            }
462:
463:            /**
464:             * Removes all TIFF fields from the directory.
465:             */
466:            public void removeTIFFFields() {
467:                Arrays.fill(lowFields, (Object) null);
468:                numLowFields = 0;
469:                highFields.clear();
470:            }
471:
472:            /**
473:             * Converts the directory to a metadata object.
474:             *
475:             * @return A metadata instance initialized from the contents of this
476:             * <code>TIFFDirectory</code>.
477:             */
478:            public IIOMetadata getAsMetadata() {
479:                return new TIFFImageMetadata(getDirectoryAsIFD(this ));
480:            }
481:
482:            /**
483:             * Clones the directory and all the fields contained therein.
484:             *
485:             * @return A clone of this <code>TIFFDirectory</code>.
486:             */
487:            public Object clone() {
488:                TIFFDirectory dir = new TIFFDirectory(getTagSets(),
489:                        getParentTag());
490:                TIFFField[] fields = getTIFFFields();
491:                int numFields = fields.length;
492:                for (int i = 0; i < numFields; i++) {
493:                    dir.addTIFFField(fields[i]);
494:                }
495:
496:                return dir;
497:            }
498:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.