home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 January / PCO0198.ISO / 1&1 / java.z / java_301 / sun / awt / image / InputStreamImageSource.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-10-20  |  9.5 KB  |  503 lines

  1. package sun.awt.image;
  2.  
  3. import java.awt.image.ColorModel;
  4. import java.awt.image.ImageConsumer;
  5. import java.awt.image.ImageProducer;
  6. import java.io.BufferedInputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.util.Hashtable;
  10.  
  11. abstract class InputStreamImageSource implements ImageProducer, ImageFetchable {
  12.    PixelStore pixelstore;
  13.    private ConsumerQueue consumers;
  14.    private boolean awaitingFetch = false;
  15.    private Thread latestFetcher;
  16.    private ImageDecoder decoder;
  17.  
  18.    abstract boolean checkSecurity(Object var1, boolean var2);
  19.  
  20.    synchronized int countConsumers() {
  21.       ConsumerQueue cq = this.consumers;
  22.  
  23.       int i;
  24.       for(i = 0; cq != null; cq = cq.next) {
  25.          ++i;
  26.       }
  27.  
  28.       return i;
  29.    }
  30.  
  31.    public void addConsumer(ImageConsumer ic) {
  32.       this.addConsumer(ic, false);
  33.    }
  34.  
  35.    synchronized void addConsumer(ImageConsumer ic, boolean produce) {
  36.       this.checkSecurity((Object)null, false);
  37.  
  38.       ConsumerQueue cq;
  39.       for(cq = this.consumers; cq != null && cq.consumer != ic; cq = cq.next) {
  40.       }
  41.  
  42.       if (cq == null) {
  43.          cq = new ConsumerQueue(this, ic);
  44.          cq.next = this.consumers;
  45.          this.consumers = cq;
  46.       } else {
  47.          if (!cq.secure) {
  48.             Object context = System.getSecurityManager().getSecurityContext();
  49.             if (cq.securityContext == null) {
  50.                cq.securityContext = context;
  51.             } else if (cq.securityContext != context) {
  52.                this.errorConsumer(cq);
  53.                throw new SecurityException("Applets are trading image data!");
  54.             }
  55.          }
  56.  
  57.          cq.interested = true;
  58.       }
  59.  
  60.       if (produce && cq.feeder == null && !this.awaitingFetch && this.latestFetcher == null) {
  61.          this.startProduction();
  62.       }
  63.  
  64.    }
  65.  
  66.    public synchronized boolean isConsumer(ImageConsumer ic) {
  67.       for(ConsumerQueue cq = this.consumers; cq != null; cq = cq.next) {
  68.          if (cq.consumer == ic) {
  69.             return true;
  70.          }
  71.       }
  72.  
  73.       return false;
  74.    }
  75.  
  76.    synchronized void errorConsumer(ConsumerQueue cq) {
  77.       cq.consumer.imageComplete(1);
  78.       this.removeConsumer(cq.consumer);
  79.    }
  80.  
  81.    public synchronized void removeConsumer(ImageConsumer ic) {
  82.       ConsumerQueue cq = this.consumers;
  83.  
  84.       for(ConsumerQueue cqprev = null; cq != null; cq = cq.next) {
  85.          if (cq.consumer == ic) {
  86.             if (cqprev == null) {
  87.                this.consumers = cq.next;
  88.             } else {
  89.                cqprev.next = cq.next;
  90.             }
  91.  
  92.             cq.interested = false;
  93.             return;
  94.          }
  95.  
  96.          cqprev = cq;
  97.       }
  98.  
  99.    }
  100.  
  101.    public void startProduction(ImageConsumer ic) {
  102.       this.addConsumer(ic, true);
  103.    }
  104.  
  105.    private synchronized void startProduction() {
  106.       if (!this.awaitingFetch) {
  107.          ImageFetcher.add(this);
  108.          this.awaitingFetch = true;
  109.       }
  110.  
  111.    }
  112.  
  113.    public void requestTopDownLeftRightResend(ImageConsumer ic) {
  114.       synchronized(this){}
  115.  
  116.       PixelStore store;
  117.       try {
  118.          store = this.pixelstore;
  119.       } catch (Throwable var5) {
  120.          throw var5;
  121.       }
  122.  
  123.       if (store != null) {
  124.          store.replay(this, ic, false);
  125.       }
  126.  
  127.    }
  128.  
  129.    protected abstract ImageDecoder getDecoder();
  130.  
  131.    protected ImageDecoder decoderForType(InputStream is, String content_type) {
  132.       if (content_type.equals("image/gif")) {
  133.          return new GifImageDecoder(this, is);
  134.       } else if (content_type.equals("image/jpeg")) {
  135.          return new JPEGImageDecoder(this, is);
  136.       } else {
  137.          return content_type.equals("image/x-xbitmap") ? new XbmImageDecoder(this, is) : null;
  138.       }
  139.    }
  140.  
  141.    protected ImageDecoder getDecoder(InputStream is) {
  142.       if (!is.markSupported()) {
  143.          is = new BufferedInputStream(is);
  144.       }
  145.  
  146.       try {
  147.          is.mark(1000);
  148.          int c1 = is.read();
  149.          int c2 = is.read();
  150.          int c3 = is.read();
  151.          int c4 = is.read();
  152.          is.read();
  153.          is.read();
  154.          is.reset();
  155.          if (c1 == 71 && c2 == 73 && c3 == 70 && c4 == 56) {
  156.             return new GifImageDecoder(this, is);
  157.          }
  158.  
  159.          if (c1 == 255 && c2 == 216 && c3 == 255 && c4 == 224 || c1 == 255 && c2 == 216 && c3 == 255 && c4 == 238) {
  160.             return new JPEGImageDecoder(this, is);
  161.          }
  162.  
  163.          if (c1 == 35 && c2 == 100 && c3 == 101 && c4 == 102) {
  164.             return new XbmImageDecoder(this, is);
  165.          }
  166.       } catch (IOException var6) {
  167.       }
  168.  
  169.       return null;
  170.    }
  171.  
  172.    public void doFetch() {
  173.       Thread me = Thread.currentThread();
  174.       ImageDecoder imgd = null;
  175.  
  176.       try {
  177.          if (this.latchConsumers(me) <= 0) {
  178.             return;
  179.          }
  180.  
  181.          if (!this.updateFromStore(me)) {
  182.             imgd = this.getDecoder();
  183.             if (imgd != null) {
  184.                this.setDecoder(imgd, me);
  185.  
  186.                try {
  187.                   imgd.produceImage();
  188.                } catch (IOException e) {
  189.                   ((Throwable)e).printStackTrace();
  190.                } catch (ImageFormatException e) {
  191.                   ((Throwable)e).printStackTrace();
  192.                }
  193.  
  194.                return;
  195.             }
  196.  
  197.             return;
  198.          }
  199.       } finally {
  200.          this.imageComplete(1);
  201.          this.unlatchConsumers(imgd, me);
  202.       }
  203.  
  204.    }
  205.  
  206.    private boolean updateFromStore(Thread me) {
  207.       synchronized(this){}
  208.  
  209.       PixelStore store;
  210.       ConsumerQueue cq;
  211.       try {
  212.          store = this.pixelstore;
  213.          if (store == null) {
  214.             boolean var6 = false;
  215.             return var6;
  216.          }
  217.  
  218.          cq = this.consumers;
  219.       } catch (Throwable var18) {
  220.          throw var18;
  221.       }
  222.  
  223.       while(cq != null) {
  224.          synchronized(this){}
  225.  
  226.          try {
  227.             if (cq.feeder == null) {
  228.                if (!this.checkSecurity(cq.securityContext, true)) {
  229.                   this.errorConsumer(cq);
  230.                } else {
  231.                   cq.feeder = me;
  232.                }
  233.             }
  234.  
  235.             if (cq.feeder != me) {
  236.                cq = cq.next;
  237.                continue;
  238.             }
  239.          } catch (Throwable var17) {
  240.             throw var17;
  241.          }
  242.  
  243.          if (!store.replay(this, cq.consumer)) {
  244.             return false;
  245.          }
  246.  
  247.          synchronized(this){}
  248.  
  249.          try {
  250.             cq = cq.next;
  251.          } catch (Throwable var16) {
  252.             throw var16;
  253.          }
  254.       }
  255.  
  256.       return true;
  257.    }
  258.  
  259.    private synchronized void setDecoder(ImageDecoder decoder, Thread me) {
  260.       for(ConsumerQueue cq = this.consumers; cq != null; cq = cq.next) {
  261.          if (cq.feeder == me) {
  262.             if (!this.checkSecurity(cq.securityContext, true)) {
  263.                this.errorConsumer(cq);
  264.             } else {
  265.                cq.decoder = decoder;
  266.             }
  267.          }
  268.       }
  269.  
  270.       if (this.latestFetcher == me) {
  271.          this.decoder = decoder;
  272.       }
  273.  
  274.    }
  275.  
  276.    private synchronized int latchConsumers(Thread me) {
  277.       this.latestFetcher = me;
  278.       this.awaitingFetch = false;
  279.       ConsumerQueue cq = this.consumers;
  280.  
  281.       int count;
  282.       for(count = 0; cq != null; cq = cq.next) {
  283.          if (cq.feeder == null) {
  284.             if (!this.checkSecurity(cq.securityContext, true)) {
  285.                this.errorConsumer(cq);
  286.             } else {
  287.                cq.feeder = me;
  288.                ++count;
  289.             }
  290.          }
  291.       }
  292.  
  293.       return count;
  294.    }
  295.  
  296.    private synchronized void unlatchConsumers(ImageDecoder imgd, Thread me) {
  297.       if (this.latestFetcher == me) {
  298.          this.latestFetcher = null;
  299.       }
  300.  
  301.       ConsumerQueue cq = this.consumers;
  302.  
  303.       for(ConsumerQueue cqprev = null; cq != null; cq = cq.next) {
  304.          if (cq.feeder == me) {
  305.             if (cqprev == null) {
  306.                this.consumers = cq.next;
  307.             } else {
  308.                cqprev.next = cq.next;
  309.             }
  310.          } else {
  311.             cqprev = cq;
  312.          }
  313.       }
  314.  
  315.    }
  316.  
  317.    private ConsumerQueue nextConsumer(ConsumerQueue cq, Thread me) {
  318.       synchronized(this){}
  319.  
  320.       try {
  321.          if (cq == null) {
  322.             cq = this.consumers;
  323.          } else {
  324.             cq = cq.next;
  325.          }
  326.  
  327.          while(cq != null) {
  328.             if (cq.interested) {
  329.                if (cq.feeder == me) {
  330.                   ConsumerQueue var5 = cq;
  331.                   return var5;
  332.                }
  333.  
  334.                if (cq.feeder == null && this.latestFetcher == me) {
  335.                   break;
  336.                }
  337.  
  338.                cq = cq.next;
  339.             }
  340.          }
  341.       } catch (Throwable var17) {
  342.          throw var17;
  343.       }
  344.  
  345.       if (cq != null) {
  346.          if (this.decoder != null && this.decoder.catchupConsumer(this, cq.consumer)) {
  347.             synchronized(this){}
  348.  
  349.             ConsumerQueue var19;
  350.             try {
  351.                if (!cq.interested) {
  352.                   return this.nextConsumer(cq, me);
  353.                }
  354.  
  355.                if (!this.checkSecurity(cq.securityContext, true)) {
  356.                   this.errorConsumer(cq);
  357.                   return this.nextConsumer(cq, me);
  358.                }
  359.  
  360.                cq.feeder = me;
  361.                cq.decoder = this.decoder;
  362.                var19 = cq;
  363.             } catch (Throwable var16) {
  364.                throw var16;
  365.             }
  366.  
  367.             return var19;
  368.          }
  369.  
  370.          synchronized(this){}
  371.  
  372.          try {
  373.             this.latestFetcher = null;
  374.             this.startProduction();
  375.          } catch (Throwable var15) {
  376.             throw var15;
  377.          }
  378.       }
  379.  
  380.       return cq;
  381.    }
  382.  
  383.    synchronized void flush() {
  384.       ConsumerQueue cq = this.consumers;
  385.  
  386.       for(this.consumers = null; cq != null; cq = cq.next) {
  387.          cq.interested = false;
  388.  
  389.          try {
  390.             if (cq.feeder != null) {
  391.                cq.feeder.interrupt();
  392.             }
  393.          } catch (NoSuchMethodError var2) {
  394.             break;
  395.          }
  396.  
  397.          if (cq.decoder != null) {
  398.             cq.decoder.close();
  399.          }
  400.       }
  401.  
  402.       this.pixelstore = null;
  403.    }
  404.  
  405.    synchronized void setPixelStore(PixelStore storage) {
  406.       this.pixelstore = storage;
  407.    }
  408.  
  409.    int setDimensions(int w, int h) {
  410.       ConsumerQueue cq = null;
  411.       Thread me = Thread.currentThread();
  412.  
  413.       int count;
  414.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  415.          cq.consumer.setDimensions(w, h);
  416.       }
  417.  
  418.       return count;
  419.    }
  420.  
  421.    int setProperties(Hashtable props) {
  422.       ConsumerQueue cq = null;
  423.       Thread me = Thread.currentThread();
  424.  
  425.       int count;
  426.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  427.          cq.consumer.setProperties(props);
  428.       }
  429.  
  430.       return count;
  431.    }
  432.  
  433.    int setColorModel(ColorModel model) {
  434.       ConsumerQueue cq = null;
  435.       Thread me = Thread.currentThread();
  436.  
  437.       int count;
  438.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  439.          cq.consumer.setColorModel(model);
  440.       }
  441.  
  442.       return count;
  443.    }
  444.  
  445.    int setHints(int hints) {
  446.       ConsumerQueue cq = null;
  447.       Thread me = Thread.currentThread();
  448.  
  449.       int count;
  450.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  451.          cq.consumer.setHints(hints);
  452.       }
  453.  
  454.       return count;
  455.    }
  456.  
  457.    int setPixels(int x, int y, int w, int h, ColorModel model, byte[] pix, int off, int scansize) {
  458.       ConsumerQueue cq = null;
  459.       Thread me = Thread.currentThread();
  460.       if (me.getPriority() > 3) {
  461.          SecurityManager.setScopePermission();
  462.          me.setPriority(3);
  463.          SecurityManager.resetScopePermission();
  464.       }
  465.  
  466.       int count;
  467.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  468.          cq.consumer.setPixels(x, y, w, h, model, pix, off, scansize);
  469.       }
  470.  
  471.       return count;
  472.    }
  473.  
  474.    int setPixels(int x, int y, int w, int h, ColorModel model, int[] pix, int off, int scansize) {
  475.       ConsumerQueue cq = null;
  476.       Thread me = Thread.currentThread();
  477.       if (me.getPriority() > 3) {
  478.          SecurityManager.setScopePermission();
  479.          me.setPriority(3);
  480.          SecurityManager.resetScopePermission();
  481.       }
  482.  
  483.       int count;
  484.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  485.          cq.consumer.setPixels(x, y, w, h, model, pix, off, scansize);
  486.       }
  487.  
  488.       return count;
  489.    }
  490.  
  491.    int imageComplete(int status) {
  492.       ConsumerQueue cq = null;
  493.       Thread me = Thread.currentThread();
  494.  
  495.       int count;
  496.       for(count = 0; (cq = this.nextConsumer(cq, me)) != null; ++count) {
  497.          cq.consumer.imageComplete(status);
  498.       }
  499.  
  500.       return count;
  501.    }
  502. }
  503.