Content of file ImageModel.java.html

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>ImageModel.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Mistral Core</a> &gt; <a href="index.source.html" class="el_package">it.tidalwave.image</a> &gt; <span class="el_source">ImageModel.java</span></div><h1>ImageModel.java</h1><pre class="source lang-java linenums">/*
 * *********************************************************************************************************************
 *
 * Mistral: open source imaging engine
 * http://tidalwave.it/projects/mistral
 *
 * Copyright (C) 2003 - 2023 by Tidalwave s.a.s. (http://tidalwave.it)
 *
 * *********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 *
 * *********************************************************************************************************************
 *
 * git clone https://bitbucket.org/tidalwave/mistral-src
 * git clone https://github.com/tidalwave-it/mistral-src
 *
 * *********************************************************************************************************************
 */
package it.tidalwave.image;

import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import java.io.Serializable;
import javax.imageio.ImageIO;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import it.tidalwave.image.op.ImplementationFactory;

/***********************************************************************************************************************
 *
 * @author Fabrizio Giudici
 *
 **********************************************************************************************************************/
public abstract class ImageModel implements Externalizable
  {
    private Serializable id;
    private String nickName;
    protected transient Object model;

    /*******************************************************************************************************************
     *
     * Default constructor for serialization. DO NOT CALL.
     *
     ******************************************************************************************************************/
    public ImageModel()
<span class="nc" id="L58">      {</span>
        // Just deserialized. There's no model, so it should not go in cache
<span class="nc" id="L60">      }</span>

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public ImageModel (final Object model)
<span class="fc" id="L67">      {</span>
<span class="pc bpc" id="L68" title="1 of 2 branches missed.">        if (model == null)</span>
          {
<span class="nc" id="L70">            throw new IllegalArgumentException(&quot;model is null&quot;);</span>
          }

<span class="fc" id="L73">        id = &quot;&quot; + (System.nanoTime() - 1182021416080087000L); // FIXME: use UUID</span>
//        System.err.println(&quot;CREATED ImageModel &quot; + id);
<span class="fc" id="L75">        this.model = model;</span>
//        ImageModelCache.getInstance().add(this);
<span class="fc" id="L77">      }</span>

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void dispose()
      {
<span class="nc" id="L85">        ImageModelCache.getInstance().remove(id, true);</span>
        // model = null; FIXME??
??
<span class="nc" id="L87"> }</span> /******************************************************************************************************************* * * ******************************************************************************************************************/ public final Serializable getId() { <span class="fc" id="L95"> return id;</span> } public void setNickName (final String nickName) { <span class="nc" id="L100"> this.nickName = nickName;</span> <span class="nc" id="L101"> }</span> public String getNickName() { <span class="nc" id="L105"> return nickName;</span> } /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override public final int hashCode() { <span class="nc bnc" id="L115" title="All 2 branches missed."> return (id != null) ? id.hashCode() : 0;</span> } /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override public final boolean equals (final Object object) { <span class="nc bnc" id="L125" title="All 2 branches missed."> if (!(object instanceof ImageModel))</span> { <span class="nc" id="L127"> return false;</span> } <span class="nc" id="L130"> final var imageModel = (ImageModel)object;</span> <span class="nc bnc" id="L132" title="All 4 branches missed."> if ((id == null) || (imageModel.id == null))</span> { <span class="nc" id="L134"> return false;</span> } <span class="nc" id="L137"> return id.equals(imageModel.id);</span> } /******************************************************************************************************************* * * ******************************************************************************************************************/ public void setImage (final Object image) { <span class="fc" id="L146"> ImageModelCache.getInstance().update(this);</span> <span class="fc" id="L147"> }</span> /******************************************************************************************************************* * * ******************************************************************************************************************/ public final Object getImage() { <span class="fc" id="L155"> return model;</span> } /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract int getWidth(); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract int getHeight(); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract EditableImage.DataType getDataType(); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract int getBandCount(); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract ImplementationFactory getFactory(); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract ColorModel getColorModel(); /******************************************************************************************************************* * * Creates a similar image, that is a blank image with the same characteristics * of this image (width, height, data type, sample model, color model). * * @return a new, similar image * ******************************************************************************************************************/ public abstract EditableImage createCopy (boolean copyContents); /******************************************************************************************************************* * * ******************************************************************************************************************/ public abstract &lt;T&gt; T getInnerProperty (Class&lt;T&gt; propertyClass); /******************************************************************************************************************* * * Returns an estimate of the memory allocated by this image. The default * implementation returns the number of pixels multiplied by the number of bands * multiplied the size in bytes of each pixel. Can be overridden for more * accurate implementations. * * @return the memory allocated for this image * ******************************************************************************************************************/ public long getMemorySize() { <span class="nc" id="L222"> final var dataType = getDataType();</span> <span class="nc bnc" id="L223" title="All 2 branches missed."> return (dataType == null) ? 0 : ((long)dataType.getSize() * getWidth() * getHeight() * getBandCount()) / 8;</span> } /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override public final void writeExternal (final ObjectOutput out) throws IOException { <span class="nc" id="L234"> out.writeObject(id);</span> <span class="nc bnc" id="L235" title="All 2 branches missed."> out.writeObject((nickName != null) ? nickName : &quot;NULL&quot;); // FIXME: needed? Can writeObject(null)?</span> <span class="nc bnc" id="L237" title="All 2 branches missed."> final var notNull = model != null;</span> <span class="nc" id="L238"> out.writeBoolean(notNull);</span> <span class="nc bnc" id="L240" title="All 2 branches missed."> if (notNull)</span> { <span class="nc" id="L242"> writeRaster(new OutputStream()</span> <span class="nc" id="L243"> {</span> @Override public void write (final byte[] buffer, final int off, final int len) throws IOException { <span class="nc" id="L248"> out.write(buffer, off, len);</span> <span class="nc" id="L249"> }</span> @Override public void write (final int b) throws IOException { <span class="nc" id="L255"> out.write(b);</span> <span class="nc" id="L256"> }</span> }); } <span class="nc" id="L259"> }</span> /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override public final void readExternal (final ObjectInput in) throws IOException, ClassNotFoundException { <span class="nc" id="L269"> id = (Serializable)in.readObject();</span> <span class="nc" id="L270"> nickName = (String)in.readObject();</span> <span class="nc bnc" id="L272" title="All 2 branches missed."> if (nickName.equals(&quot;NULL&quot;))</span> { <span class="nc" id="L274"> nickName = null;</span> } <span class="nc bnc" id="L277" title="All 2 branches missed."> if (in.readBoolean())</span> { <span class="nc" id="L279"> readRaster(new InputStream()</span> <span class="nc" id="L280"> {</span> @Override public int read (final byte[] b, final int off, final int len) throws IOException { <span class="nc" id="L285"> return in.read(b, off, len);</span> } @Override public int read() throws IOException { <span class="nc" id="L292"> return in.read();</span> } }); } <span class="nc" id="L296"> }</span> /******************************************************************************************************************* * * ******************************************************************************************************************/ protected abstract RenderedImage toRenderedImageForSerialization(); /******************************************************************************************************************* * * ******************************************************************************************************************/ protected abstract Object toObjectForDeserialization (final RenderedImage renderedImage); /******************************************************************************************************************* * * TODO: check performance * ******************************************************************************************************************/ protected void writeRaster (final OutputStream out) throws IOException { // System.err.println(CLASS + &quot;.writeExternal() - model: &quot; + model); /* ImageWriter imageWriter = null; for (final Iterator&lt;ImageWriter&gt; i = ImageIO.getImageWritersByFormatName(&quot;TIFF&quot;); i.hasNext(); ) { final ImageWriter testImageWriter = i.next(); if ((testImageWriter != null) &amp;&amp; testImageWriter.getClass().getName().equals(&quot;com.sun.media .imageioimpl.plugins.tiff.TIFFImageWriter&quot;)) { imageWriter = testImageWriter; break; } } if (imageWriter == null) { throw new RuntimeException(&quot;No JAI ImageIO ImageWriter for TIFF format! Can't serialize ImageModel&quot;); } System.err.println(&quot;SERIALIZING WITH &quot; + imageWriter); final ImageOutputStream ios = ImageIO.createImageOutputStream(out); imageWriter.setOutput(ios); imageWriter.write(toRenderedImageForSerialization()); imageWriter.dispose();*/ <span class="nc" id="L343"> ImageIO.write(toRenderedImageForSerialization(), &quot;TIFF&quot;, out);</span> <span class="nc" id="L344"> }</span> /******************************************************************************************************************* * * TODO: check performance * ******************************************************************************************************************/ protected void readRaster (final InputStream in) throws IOException { try { <span class="nc" id="L356"> Class.forName(&quot;com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter&quot;);</span> } <span class="nc" id="L358"> catch (ClassNotFoundException ex)</span> { <span class="nc" id="L360"> throw new RuntimeException(&quot;Can't deserialize ImageModels since JAI ImageIO is not in the classpath&quot;);</span> <span class="nc" id="L361"> }</span> <span class="nc" id="L363"> model = toObjectForDeserialization(ImageIO.read(in));</span> <span class="nc" id="L364"> }</span> /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override public final String toString() { <span class="fc" id="L373"> return getClass().getName() + &quot;[id: &quot; + getId() +</span> <span class="pc bpc" id="L374" title="1 of 2 branches missed."> ((nickName != null) ? (&quot;, nickName: &quot; + nickName) : &quot;&quot;) +</span> //&quot;, model: &quot; + model + &quot;]&quot;; } /******************************************************************************************************************* * * ******************************************************************************************************************/ @Override protected void finalize() { // FIXME: not sure about this - for sure should only remove from the local cache <span class="fc" id="L387"> }</span> } </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.7.202105040129</span></div></body></html>