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 Examples HistogramViewer</a> &gt; <a href="../index.html" class="el_bundle">image-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
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>