diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..eb8bdea9 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: SonarCloud +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Cache SonarCloud packages + uses: actions/cache@v1 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=refactor-metricas-larios-luna diff --git a/pom.xml b/pom.xml index 4403115e..08bdae8f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,6 +3,10 @@ ImageJ ImageJ 0.0.1-SNAPSHOT + + metricas-refactor-larios-luna + https://sonarcloud.io + src @@ -24,4 +28,4 @@ - \ No newline at end of file + diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 00000000..85487d8b --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,2 @@ +sonar.projectKey=refactor-metricas-larios-luna +sonar.organization=metricas-refactor-larios-luna \ No newline at end of file diff --git a/src/ij/gui/OvalRoi.java b/src/ij/gui/OvalRoi.java index cb4c9aa7..1423a953 100644 --- a/src/ij/gui/OvalRoi.java +++ b/src/ij/gui/OvalRoi.java @@ -147,102 +147,7 @@ protected void moveHandle(int sx, int sy) { } } - - if (constrain) { - if (activeHandle==1 || activeHandle==5) width=height; - else height=width; - - if (x>=x2) { - width=1; - x=x2=xc; - } - if (y>=y2) { - height=1; - y=y2=yc; - } - switch(activeHandle){ - case 0: - x=x2-width; - y=y2-height; - break; - case 1: - x=xc-width/2; - y=y2-height; - break; - case 2: - y=y2-height; - break; - case 3: - y=yc-height/2; - break; - case 5: - x=xc-width/2; - break; - case 6: - x=x2-width; - break; - case 7: - y=yc-height/2; - x=x2-width; - break; - } - if (center){ - x=xc-width/2; - y=yc-height/2; - } - } - - if (aspect && !constrain) { - if (activeHandle==1 || activeHandle==5) width=(int)Math.rint((double)height*asp); - else height=(int)Math.rint((double)width/asp); - - switch (activeHandle) { - case 0: - x=x2-width; - y=y2-height; - break; - case 1: - x=xc-width/2; - y=y2-height; - break; - case 2: - y=y2-height; - break; - case 3: - y=yc-height/2; - break; - case 5: - x=xc-width/2; - break; - case 6: - x=x2-width; - break; - case 7: - y=yc-height/2; - x=x2-width; - break; - } - if (center) { - x=xc-width/2; - y=yc-height/2; - } - // Attempt to preserve aspect ratio when roi very small: - if (width<8) { - if (width<1) width = 1; - height=(int)Math.rint((double)width/asp_bk); - } - if (height<8) { - if (height<1) height =1; - width=(int)Math.rint((double)height*asp_bk); - } - } - - updateClipRect(); - imp.draw(clipX, clipY, clipWidth, clipHeight); - oldX=x; oldY=y; - oldWidth=width; oldHeight=height; - cachedMask = null; - bounds = null; + this.conditionMoveHandle(x2, xc, y2, yc, asp, true); } public void draw(Graphics g) { diff --git a/src/ij/gui/Roi.java b/src/ij/gui/Roi.java index 733ebbed..2fa45ab8 100644 --- a/src/ij/gui/Roi.java +++ b/src/ij/gui/Roi.java @@ -923,104 +923,8 @@ private void growConstrained(int xNew, int yNew) { oldWidth = width; oldHeight = height; } - - protected void moveHandle(int sx, int sy) { - double asp; - if (clipboard!=null) return; - int ox = ic.offScreenX2(sx); - int oy = ic.offScreenY2(sy); - if (ox<0) ox=0; if (oy<0) oy=0; - if (ox>xMax) ox=xMax; if (oy>yMax) oy=yMax; - int x1=x, y1=y, x2=x1+width, y2=y+height, xc=x+width/2, yc=y+height/2; - if (width > 7 && height > 7) { - asp = (double)width/(double)height; - asp_bk = asp; - } else - asp = asp_bk; - - switch (activeHandle) { - case 0: - x=ox; y=oy; - break; - case 1: - y=oy; - break; - case 2: - x2=ox; y=oy; - break; - case 3: - x2=ox; - break; - case 4: - x2=ox; y2=oy; - break; - case 5: - y2=oy; - break; - case 6: - x=ox; y2=oy; - break; - case 7: - x=ox; - break; - } - if (x=x2) { - width=1; - x=x2=xc; - } - if (y>=y2) { - height=1; - y=y2=yc; - } - bounds = null; - } - + + protected void conditionMoveHandle(int x2, int xc, int y2, int yc, double asp, boolean isOval) { if (constrain) { if (activeHandle==1 || activeHandle==5) width=height; @@ -1118,7 +1022,111 @@ protected void moveHandle(int sx, int sy) { oldX=x; oldY=y; oldWidth=width; oldHeight=height; bounds = null; - subPixel = false; + if(!isOval) { + subPixel = false; + }else { + cachedMask = null; + } + + } + + protected void moveHandle(int sx, int sy) { + double asp; + if (clipboard!=null) return; + int ox = ic.offScreenX2(sx); + int oy = ic.offScreenY2(sy); + if (ox<0) ox=0; if (oy<0) oy=0; + if (ox>xMax) ox=xMax; if (oy>yMax) oy=yMax; + int x1=x, y1=y, x2=x1+width, y2=y+height, xc=x+width/2, yc=y+height/2; + if (width > 7 && height > 7) { + asp = (double)width/(double)height; + asp_bk = asp; + } else + asp = asp_bk; + + switch (activeHandle) { + case 0: + x=ox; y=oy; + break; + case 1: + y=oy; + break; + case 2: + x2=ox; y=oy; + break; + case 3: + x2=ox; + break; + case 4: + x2=ox; y2=oy; + break; + case 5: + y2=oy; + break; + case 6: + x=ox; y2=oy; + break; + case 7: + x=ox; + break; + } + if (x=x2) { + width=1; + x=x2=xc; + } + if (y>=y2) { + height=1; + y=y2=yc; + } + bounds = null; + } + this.conditionMoveHandle(x2, xc, y2, yc, asp, false); } void move(int sx, int sy) { diff --git a/src/ij/io/SaveDialog.java b/src/ij/io/SaveDialog.java index 3e4579ab..d5a032e2 100644 --- a/src/ij/io/SaveDialog.java +++ b/src/ij/io/SaveDialog.java @@ -145,39 +145,7 @@ void jSaveInvokeAndWait(final String title, final String defaultDir, final Strin try { EventQueue.invokeAndWait(new Runnable() { public void run() { - JFileChooser fc = new JFileChooser(); - fc.setDialogTitle(title); - fc.setDragEnabled(true); - fc.setTransferHandler(new DragAndDropHandler(fc)); - if (defaultDir!=null) { - File f = new File(defaultDir); - if (f!=null) - fc.setCurrentDirectory(f); - } - if (defaultName!=null) - fc.setSelectedFile(new File(defaultName)); - int returnVal = fc.showSaveDialog(IJ.getInstance()); - if (returnVal!=JFileChooser.APPROVE_OPTION) - {Macro.abort(); return;} - File f = fc.getSelectedFile(); - if(f.exists()) { - int ret = JOptionPane.showConfirmDialog (fc, - "The file "+ f.getName() + " already exists. \nWould you like to replace it?", - "Replace?", - JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - if (ret!=JOptionPane.OK_OPTION) f = null; - } - if (f==null) - Macro.abort(); - else { - dir = fc.getCurrentDirectory().getPath()+File.separator; - name = fc.getName(f); - if (noExtension(name)) { - if (".raw".equals(ext)) - ext = null; - name = setExtension(name, ext); - } - } + jSaveDispatchThread(title, defaultDir, defaultName); } }); } catch (Exception e) {} diff --git a/src/ij/plugin/GifWriter.java b/src/ij/plugin/GifWriter.java index 48026ff6..c03d794b 100644 --- a/src/ij/plugin/GifWriter.java +++ b/src/ij/plugin/GifWriter.java @@ -929,8 +929,8 @@ protected void writePalette() throws IOException { * Encodes and writes pixel data */ protected void writePixels() throws IOException { - LZWEncoder2 encoder = - new LZWEncoder2(width, height, indexedPixels, colorDepth); + LZWEncoder encoder = + new LZWEncoder(width, height, indexedPixels, colorDepth); encoder.encode(out); } @@ -951,326 +951,7 @@ protected void writeString(String s) throws IOException { } } -//============================================================================== -// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott. -// K Weiner 12/00 -class LZWEncoder2 { - - private static final int EOF = -1; - - private int imgW, imgH; - private byte[] pixAry; - private int initCodeSize; - private int remaining; - private int curPixel; - - - // GIFCOMPR.C - GIF Image compression routines - // - // Lempel-Ziv compression based on 'compress'. GIF modifications by - // David Rowley (mgardi@watdcsu.waterloo.edu) - - // General DEFINEs - - static final int BITS = 12; - - static final int HSIZE = 5003; // 80% occupancy - - // GIF Image compression - modified 'compress' - // - // Based on: compress.c - File compression ala IEEE Computer, June 1984. - // - // By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) - // Jim McKie (decvax!mcvax!jim) - // Steve Davies (decvax!vax135!petsd!peora!srd) - // Ken Turkowski (decvax!decwrl!turtlevax!ken) - // James A. Woods (decvax!ihnp4!ames!jaw) - // Joe Orost (decvax!vax135!petsd!joe) - - int n_bits; // number of bits/code - int maxbits = BITS; // user settable max # bits/code - int maxcode; // maximum code, given n_bits - int maxmaxcode = 1 << BITS; // should NEVER generate this code - - int[] htab = new int[HSIZE]; - int[] codetab = new int[HSIZE]; - - int hsize = HSIZE; // for dynamic table sizing - - int free_ent = 0; // first unused entry - - // block compression parameters -- after all codes are used up, - // and compression rate changes, start over. - boolean clear_flg = false; - - // Algorithm: use open addressing double hashing (no chaining) on the - // prefix code / next character combination. We do a variant of Knuth's - // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime - // secondary probe. Here, the modular division first probe is gives way - // to a faster exclusive-or manipulation. Also do block compression with - // an adaptive reset, whereby the code table is cleared when the compression - // ratio decreases, but after the table fills. The variable-length output - // codes are re-sized at this point, and a special CLEAR code is generated - // for the decompressor. Late addition: construct the table according to - // file size for noticeable speed improvement on small files. Please direct - // questions about this implementation to ames!jaw. - - int g_init_bits; - - int ClearCode; - int EOFCode; - - // output - // - // Output the given code. - // Inputs: - // code: A n_bits-bit integer. If == -1, then EOF. This assumes - // that n_bits =< wordsize - 1. - // Outputs: - // Outputs code to the file. - // Assumptions: - // Chars are 8 bits long. - // Algorithm: - // Maintain a BITS character long buffer (so that 8 codes will - // fit in it exactly). Use the VAX insv instruction to insert each - // code in turn. When the buffer fills up empty it and start over. - - int cur_accum = 0; - int cur_bits = 0; - - int masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, - 0x001F, 0x003F, 0x007F, 0x00FF, - 0x01FF, 0x03FF, 0x07FF, 0x0FFF, - 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; - - // Number of characters so far in this 'packet' - int a_count; - - // Define the storage for the packet accumulator - byte[] accum = new byte[256]; - - - //---------------------------------------------------------------------------- - LZWEncoder2(int width, int height, byte[] pixels, int color_depth) - { - imgW = width; - imgH = height; - pixAry = pixels; - initCodeSize = Math.max(2, color_depth); - } - - - // Add a character to the end of the current packet, and if it is 254 - // characters, flush the packet to disk. - void char_out( byte c, OutputStream outs ) throws IOException - { - accum[a_count++] = c; - if ( a_count >= 254 ) - flush_char( outs ); - } - - - // Clear out the hash table - - // table clear for block compress - void cl_block( OutputStream outs ) throws IOException - { - cl_hash( hsize ); - free_ent = ClearCode + 2; - clear_flg = true; - - output( ClearCode, outs ); - } - - - // reset code table - void cl_hash( int hsize ) - { - for ( int i = 0; i < hsize; ++i ) - htab[i] = -1; - } - - - void compress( int init_bits, OutputStream outs ) throws IOException - { - int fcode; - int i /* = 0 */; - int c; - int ent; - int disp; - int hsize_reg; - int hshift; - - // Set up the globals: g_init_bits - initial number of bits - g_init_bits = init_bits; - - // Set up the necessary values - clear_flg = false; - n_bits = g_init_bits; - maxcode = MAXCODE( n_bits ); - - ClearCode = 1 << ( init_bits - 1 ); - EOFCode = ClearCode + 1; - free_ent = ClearCode + 2; - a_count = 0; // clear packet - - ent = nextPixel(); - - hshift = 0; - for ( fcode = hsize; fcode < 65536; fcode *= 2 ) - ++hshift; - hshift = 8 - hshift; // set hash code range bound - - hsize_reg = hsize; - cl_hash( hsize_reg ); // clear hash table - - output( ClearCode, outs ); - - outer_loop: - while ( (c = nextPixel()) != EOF ) - { - fcode = ( c << maxbits ) + ent; - i = ( c << hshift ) ^ ent; // xor hashing - - if ( htab[i] == fcode ) - { - ent = codetab[i]; - continue; - } - else if ( htab[i] >= 0 ) // non-empty slot - { - disp = hsize_reg - i; // secondary hash (after G. Knott) - if ( i == 0 ) - disp = 1; - do - { - if ( (i -= disp) < 0 ) - i += hsize_reg; - - if ( htab[i] == fcode ) - { - ent = codetab[i]; - continue outer_loop; - } - } - while ( htab[i] >= 0 ); - } - output( ent, outs ); - ent = c; - if ( free_ent < maxmaxcode ) - { - codetab[i] = free_ent++; // code -> hashtable - htab[i] = fcode; - } - else - cl_block( outs ); - } - // Put out the final code. - output( ent, outs ); - output( EOFCode, outs ); - } - - - //---------------------------------------------------------------------------- - void encode(OutputStream os) throws IOException - { - os.write(initCodeSize); // write "initial code size" byte - - remaining = imgW * imgH; // reset navigation variables - curPixel = 0; - - compress(initCodeSize + 1, os); // compress and write the pixel data - - os.write(0); // write block terminator - } - - - // Flush the packet to disk, and reset the accumulator - void flush_char( OutputStream outs ) throws IOException - { - if ( a_count > 0 ) - { - outs.write( a_count ); - outs.write( accum, 0, a_count ); - a_count = 0; - } - } - - - final int MAXCODE( int n_bits ) - { - return ( 1 << n_bits ) - 1; - } - - - //---------------------------------------------------------------------------- - // Return the next pixel from the image - //---------------------------------------------------------------------------- - private int nextPixel() - { - if (remaining == 0) - return EOF; - - --remaining; - - byte pix = pixAry[curPixel++]; - - return pix & 0xff; - } - - - void output( int code, OutputStream outs ) throws IOException - { - cur_accum &= masks[cur_bits]; - - if ( cur_bits > 0 ) - cur_accum |= ( code << cur_bits ); - else - cur_accum = code; - - cur_bits += n_bits; - - while ( cur_bits >= 8 ) - { - char_out( (byte) ( cur_accum & 0xff ), outs ); - cur_accum >>= 8; - cur_bits -= 8; - } - - // If the next entry is going to be too big for the code size, - // then increase it, if possible. - if ( free_ent > maxcode || clear_flg ) - { - if ( clear_flg ) - { - maxcode = MAXCODE(n_bits = g_init_bits); - clear_flg = false; - } - else - { - ++n_bits; - if ( n_bits == maxbits ) - maxcode = maxmaxcode; - else - maxcode = MAXCODE(n_bits); - } - } - - if ( code == EOFCode ) - { - // At EOF, write the rest of the buffer. - while ( cur_bits > 0 ) - { - char_out( (byte) ( cur_accum & 0xff ), outs ); - cur_accum >>= 8; - cur_bits -= 8; - } - - flush_char( outs ); - } - } -} /* NeuQuant Neural-Net Quantization Algorithm diff --git a/src/ij/process/AutoThresholder.java b/src/ij/process/AutoThresholder.java index 55fe946c..e8c532c2 100644 --- a/src/ij/process/AutoThresholder.java +++ b/src/ij/process/AutoThresholder.java @@ -443,33 +443,14 @@ int Li(int [] data ) { while ( Math.abs ( new_thresh - old_thresh ) > tolerance ); return threshold; } - - int MaxEntropy(int [] data ) { - // Implements Kapur-Sahoo-Wong (Maximum Entropy) thresholding method - // Kapur J.N., Sahoo P.K., and Wong A.K.C. (1985) "A New Method for - // Gray-Level Picture Thresholding Using the Entropy of the Histogram" - // Graphical Models and Image Processing, 29(3): 273-285 - // M. Emre Celebi - // 06.15.2007 - // Ported to ImageJ plugin by G.Landini from E Celebi's fourier_0.8 routines - int threshold=-1; - int ih, it; - int first_bin; - int last_bin; - double tot_ent; /* total entropy */ - double max_ent; /* max entropy */ - double ent_back; /* entropy of the background pixels at a given threshold */ - double ent_obj; /* entropy of the object pixels at a given threshold */ - double [] norm_histo = new double[256]; /* normalized histogram */ - double [] P1 = new double[256]; /* cumulative normalized histogram */ - double [] P2 = new double[256]; - + + void CommonEntropy(int [] data, int ih, int first_bin, int[] norm_histo, int[] P1, double[] P2, int last_bin){ double total =0; for (ih = 0; ih < 256; ih++ ) total+=data[ih]; for (ih = 0; ih < 256; ih++ ) - norm_histo[ih] = data[ih]/total; + norm_histo[ih] = (int) (data[ih]/total); P1[0]=norm_histo[0]; P2[0]=1.0-P1[0]; @@ -486,8 +467,7 @@ int MaxEntropy(int [] data ) { break; } } - - /* Determine the last non-zero bin */ + last_bin=255; for (ih = 255; ih >= first_bin; ih-- ) { if ( !(Math.abs(P2[ih])<2.220446049250313E-16)) { @@ -495,6 +475,30 @@ int MaxEntropy(int [] data ) { break; } } + } + + int MaxEntropy(int [] data ) { + // Implements Kapur-Sahoo-Wong (Maximum Entropy) thresholding method + // Kapur J.N., Sahoo P.K., and Wong A.K.C. (1985) "A New Method for + // Gray-Level Picture Thresholding Using the Entropy of the Histogram" + // Graphical Models and Image Processing, 29(3): 273-285 + // M. Emre Celebi + // 06.15.2007 + // Ported to ImageJ plugin by G.Landini from E Celebi's fourier_0.8 routines + int threshold=-1; + int ih = 0, it; + int first_bin = 0; + int last_bin = 0; + double tot_ent; /* total entropy */ + double max_ent; /* max entropy */ + double ent_back; /* entropy of the background pixels at a given threshold */ + double ent_obj; /* entropy of the object pixels at a given threshold */ + double [] norm_histo = new double[256]; /* normalized histogram */ + double [] P1 = new double[256]; /* cumulative normalized histogram */ + double [] P2 = new double[256]; + + this.CommonEntropy(data, ih, first_bin, data, data, P2,last_bin); + // Calculate the total entropy each gray-level // and find the threshold that maximizes it @@ -812,9 +816,9 @@ int RenyiEntropy(int [] data ) { int threshold; int opt_threshold; - int ih, it; - int first_bin; - int last_bin; + int ih = 0, it; + int first_bin = 0; + int last_bin = 0; int tmp_var; int t_star1, t_star2, t_star3; int beta1, beta2, beta3; @@ -828,38 +832,9 @@ int RenyiEntropy(int [] data ) { double [] norm_histo = new double[256]; /* normalized histogram */ double [] P1 = new double[256]; /* cumulative normalized histogram */ double [] P2 = new double[256]; - - double total =0; - for (ih = 0; ih < 256; ih++ ) - total+=data[ih]; - - for (ih = 0; ih < 256; ih++ ) - norm_histo[ih] = data[ih]/total; - - P1[0]=norm_histo[0]; - P2[0]=1.0-P1[0]; - for (ih = 1; ih < 256; ih++ ){ - P1[ih]= P1[ih-1] + norm_histo[ih]; - P2[ih]= 1.0 - P1[ih]; - } - - /* Determine the first non-zero bin */ - first_bin=0; - for (ih = 0; ih < 256; ih++ ) { - if ( !(Math.abs(P1[ih])<2.220446049250313E-16)) { - first_bin = ih; - break; - } - } - - /* Determine the last non-zero bin */ - last_bin=255; - for (ih = 255; ih >= first_bin; ih-- ) { - if ( !(Math.abs(P2[ih])<2.220446049250313E-16)) { - last_bin = ih; - break; - } - } + + + this.CommonEntropy(data, ih, first_bin, data, data, P2,last_bin); /* Maximum Entropy Thresholding - BEGIN */ /* ALPHA = 1.0 */ diff --git a/src/ij/process/ByteProcessor.java b/src/ij/process/ByteProcessor.java index 7587558b..2c62d7b7 100644 --- a/src/ij/process/ByteProcessor.java +++ b/src/ij/process/ByteProcessor.java @@ -567,6 +567,72 @@ public void convolve3x3(int[] kernel) { p7 p8 p9 */ + private void minFilter(int sum, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8,int p9) { + sum = p5; + if (p1sum) sum = p1; + if (p2>sum) sum = p2; + if (p3>sum) sum = p3; + if (p4>sum) sum = p4; + if (p6>sum) sum = p6; + if (p7>sum) sum = p7; + if (p8>sum) sum = p8; + if (p9>sum) sum = p9; + } + + private void erodeFilter(int sum, int binaryForeground, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8,int p9) { + int count; + if (p5==binaryBackground) + sum = binaryBackground; + else { + count = 0; + if (p1==binaryBackground) count++; + if (p2==binaryBackground) count++; + if (p3==binaryBackground) count++; + if (p4==binaryBackground) count++; + if (p6==binaryBackground) count++; + if (p7==binaryBackground) count++; + if (p8==binaryBackground) count++; + if (p9==binaryBackground) count++; + if (count>=binaryCount) + sum = binaryBackground; + else + sum = binaryForeground; + } + } + + private void dilateFilter(int sum, int binaryForeground, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8,int p9) { + int count; + if (p5==binaryForeground) + sum = binaryForeground; + else { + count = 0; + if (p1==binaryForeground) count++; + if (p2==binaryForeground) count++; + if (p3==binaryForeground) count++; + if (p4==binaryForeground) count++; + if (p6==binaryForeground) count++; + if (p7==binaryForeground) count++; + if (p8==binaryForeground) count++; + if (p9==binaryForeground) count++; + if (count>=binaryCount) + sum = binaryForeground; + else + sum = binaryBackground; + } + } + public void filter(int type) { int p1, p2, p3, p4, p5, p6, p7, p8, p9; byte[] pixels2 = (byte[])getPixelsCopy(); @@ -578,7 +644,6 @@ public void filter(int type) { int[] values = new int[10]; if (type==MEDIAN_FILTER) values = new int[10]; int rowOffset = width; - int count; int binaryForeground = 255 - binaryBackground; for (int y=yMin; y<=yMax; y++) { offset = xMin + y * width; @@ -613,64 +678,16 @@ public void filter(int type) { sum = findMedian(values); break; case MIN: - sum = p5; - if (p1sum) sum = p1; - if (p2>sum) sum = p2; - if (p3>sum) sum = p3; - if (p4>sum) sum = p4; - if (p6>sum) sum = p6; - if (p7>sum) sum = p7; - if (p8>sum) sum = p8; - if (p9>sum) sum = p9; + this.maxFilter(sum, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; case ERODE: - if (p5==binaryBackground) - sum = binaryBackground; - else { - count = 0; - if (p1==binaryBackground) count++; - if (p2==binaryBackground) count++; - if (p3==binaryBackground) count++; - if (p4==binaryBackground) count++; - if (p6==binaryBackground) count++; - if (p7==binaryBackground) count++; - if (p8==binaryBackground) count++; - if (p9==binaryBackground) count++; - if (count>=binaryCount) - sum = binaryBackground; - else - sum = binaryForeground; - } + this.erodeFilter(sum, binaryForeground, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; case DILATE: - if (p5==binaryForeground) - sum = binaryForeground; - else { - count = 0; - if (p1==binaryForeground) count++; - if (p2==binaryForeground) count++; - if (p3==binaryForeground) count++; - if (p4==binaryForeground) count++; - if (p6==binaryForeground) count++; - if (p7==binaryForeground) count++; - if (p8==binaryForeground) count++; - if (p9==binaryForeground) count++; - if (count>=binaryCount) - sum = binaryForeground; - else - sum = binaryBackground; - } + this.dilateFilter(sum, binaryForeground, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; } @@ -716,64 +733,16 @@ void filterEdge(int type, byte[] pixels2, int n, int x, int y, int xinc, int yin if (sum> 255) sum = 255; break; case MIN: - sum = p5; - if (p1sum) sum = p1; - if (p2>sum) sum = p2; - if (p3>sum) sum = p3; - if (p4>sum) sum = p4; - if (p6>sum) sum = p6; - if (p7>sum) sum = p7; - if (p8>sum) sum = p8; - if (p9>sum) sum = p9; + this.maxFilter(sum, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; case ERODE: - if (p5==binaryBackground) - sum = binaryBackground; - else { - count = 0; - if (p1==binaryBackground) count++; - if (p2==binaryBackground) count++; - if (p3==binaryBackground) count++; - if (p4==binaryBackground) count++; - if (p6==binaryBackground) count++; - if (p7==binaryBackground) count++; - if (p8==binaryBackground) count++; - if (p9==binaryBackground) count++; - if (count>=binaryCount) - sum = binaryBackground; - else - sum = binaryForeground; - } + this.erodeFilter(sum, binaryForeground, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; case DILATE: - if (p5==binaryForeground) - sum = binaryForeground; - else { - count = 0; - if (p1==binaryForeground) count++; - if (p2==binaryForeground) count++; - if (p3==binaryForeground) count++; - if (p4==binaryForeground) count++; - if (p6==binaryForeground) count++; - if (p7==binaryForeground) count++; - if (p8==binaryForeground) count++; - if (p9==binaryForeground) count++; - if (count>=binaryCount) - sum = binaryForeground; - else - sum = binaryBackground; - } + this.dilateFilter(sum, binaryForeground, p1, p2, p3, p4, p5, p6, p7, p8, p9); break; } pixels[x+y*width] = (byte)sum; diff --git a/src/ij/process/FloatProcessor.java b/src/ij/process/FloatProcessor.java index 2ccf5b4f..ec5c2301 100644 --- a/src/ij/process/FloatProcessor.java +++ b/src/ij/process/FloatProcessor.java @@ -161,7 +161,7 @@ public Image createImage() { boolean thresholding = minThreshold!=NO_THRESHOLD && lutUpdateModemaxValue) ivalue = maxValue; - pixels8[i] = (byte)ivalue; - } - return pixels8; - } - @Override - byte[] create8BitImage() { - return create8BitImage(false); - } - - Image createBufferedImage() { - if (raster==null) { - SampleModel sm = getIndexSampleModel(); - DataBuffer db = new DataBufferByte(pixels8, width*height, 0); - raster = Raster.createWritableRaster(sm, db, null); - } - if (image==null || cm!=cm2) { - if (cm==null) cm = getDefaultColorModel(); - image = new BufferedImage(cm, raster, false, null); - cm2 = cm; - } - lutAnimation = false; - return image; - } /** Returns this image as an 8-bit BufferedImage. */ public BufferedImage getBufferedImage() { diff --git a/src/ij/process/ImageProcessor.java b/src/ij/process/ImageProcessor.java index 45cc9081..b58d2413 100644 --- a/src/ij/process/ImageProcessor.java +++ b/src/ij/process/ImageProcessor.java @@ -109,6 +109,9 @@ public abstract class ImageProcessor implements Cloneable { protected static double seed = Double.NaN; protected static Random rnd; protected boolean fillValueSet; + private int[] pixels; + private byte[] pixels8; + protected int min, max; protected void showProgress(double percentDone) { if (progressBar!=null) @@ -207,6 +210,114 @@ public void setLut(LUT lut) { setMinAndMax(lut.min, lut.max); } } + + public void findMinAndMax() { + int size = width*height; + int value; + int min = pixels[0]; + int max = pixels[0]; + for (int i=1; imax) + max = value; + } + this.min = min; + this.max = max; + minMaxSet = true; + } + + public Image createImage() { + if (!minMaxSet) + this.findMinAndMax(); + boolean firstTime = pixels8==null; + boolean thresholding = minThreshold!=NO_THRESHOLD && lutUpdateMode=t1 && value<=t2) + pixels8[i] = (byte)255; + else + pixels8[i] = (byte)0; + } + } else { // threshold red + for (int i=0; i=t1 && value<=t2) + pixels8[i] = (byte)255; + } + } + } + return createBufferedImage(pixels8); + } + + protected byte[] create8BitImage(boolean thresholding, byte[] pixels8, int[] pixels) { + int size = width*height; + if (pixels8==null) + pixels8 = new byte[size]; + double value; + int ivalue; + double min2 = getMin(); + double max2 = getMax(); + double scale = 255.0/(max2-min2); + int maxValue = thresholding?254:255; + for (int i=0; imaxValue) ivalue = maxValue; + pixels8[i] = (byte)ivalue; + } + return pixels8; + } + + protected byte[] create8BitImage(boolean thresholding, byte[] pixels8, float[] pixels) { + thresholding = false; + int size = width*height; + if (pixels8==null) + pixels8 = new byte[size]; + double value; + int ivalue; + double min2 = getMin(); + double max2 = getMax(); + double scale = 255.0/(max2-min2); + int maxValue = thresholding?254:255; + for (int i=0; imaxValue) ivalue = maxValue; + pixels8[i] = (byte)ivalue; + } + return pixels8; + } + + + protected Image createBufferedImage(byte[] pixels8) { + if (raster==null) { + SampleModel sm = getIndexSampleModel(); + DataBuffer db = new DataBufferByte(pixels8, width*height, 0); + raster = Raster.createWritableRaster(sm, db, null); + } + if (image==null || cm!=cm2) { + if (cm==null) cm = getDefaultColorModel(); + image = new BufferedImage(cm, raster, false, null); + cm2 = cm; + } + lutAnimation = false; + return image; + } protected void makeDefaultColorModel() { @@ -2168,8 +2279,6 @@ public void abs() {} /** Pixels greater than 'value' are set to 'value'. */ public void max(double value) {process(MAXIMUM, value);} - /** Returns a copy of this image is the form of an AWT Image. */ - public abstract Image createImage(); /** Returns this image as a BufferedImage. */ public BufferedImage getBufferedImage() { diff --git a/src/ij/process/IntProcessor.java b/src/ij/process/IntProcessor.java index 2dcea189..21c986b7 100644 --- a/src/ij/process/IntProcessor.java +++ b/src/ij/process/IntProcessor.java @@ -20,83 +20,6 @@ public IntProcessor(int width, int height, int[] pixels) { makeDefaultColorModel(); } - /** Create an 8-bit AWT image by scaling pixels in the range min-max to 0-255. */ - @Override - public Image createImage() { - if (!minMaxSet) - findMinAndMax(); - boolean firstTime = pixels8==null; - boolean thresholding = minThreshold!=NO_THRESHOLD && lutUpdateMode=t1 && value<=t2) - pixels8[i] = (byte)255; - else - pixels8[i] = (byte)0; - } - } else { // threshold red - for (int i=0; i=t1 && value<=t2) - pixels8[i] = (byte)255; - } - } - } - return createBufferedImage(); - } - - // creates 8-bit image by linearly scaling from float to 8-bits - private byte[] create8BitImage(boolean thresholding) { - int size = width*height; - if (pixels8==null) - pixels8 = new byte[size]; - double value; - int ivalue; - double min2 = getMin(); - double max2 = getMax(); - double scale = 255.0/(max2-min2); - int maxValue = thresholding?254:255; - for (int i=0; imaxValue) ivalue = maxValue; - pixels8[i] = (byte)ivalue; - } - return pixels8; - } - - @Override - byte[] create8BitImage() { - return create8BitImage(false); - } - - Image createBufferedImage() { - if (raster==null) { - SampleModel sm = getIndexSampleModel(); - DataBuffer db = new DataBufferByte(pixels8, width*height, 0); - raster = Raster.createWritableRaster(sm, db, null); - } - if (image==null || cm!=cm2) { - if (cm==null) cm = getDefaultColorModel(); - image = new BufferedImage(cm, raster, false, null); - cm2 = cm; - } - lutAnimation = false; - return image; - } - /** Returns this image as an 8-bit BufferedImage . */ public BufferedImage getBufferedImage() { return convertToByte(true).getBufferedImage(); diff --git a/src/ij/process/ShortProcessor.java b/src/ij/process/ShortProcessor.java index 01935cfc..9126acb8 100644 --- a/src/ij/process/ShortProcessor.java +++ b/src/ij/process/ShortProcessor.java @@ -67,6 +67,7 @@ public ShortProcessor(int width, int height, boolean unsigned) { this(width, height); } + @Override public void findMinAndMax() { if (fixedScale || pixels==null) return; @@ -86,40 +87,6 @@ else if (value>max) minMaxSet = true; } - /** Create an 8-bit AWT image by scaling pixels in the range min-max to 0-255. */ - public Image createImage() { - if (!minMaxSet) - findMinAndMax(); - boolean firstTime = pixels8==null; - boolean thresholding = minThreshold!=NO_THRESHOLD && lutUpdateMode=t1 && value<=t2) - pixels8[i] = (byte)255; - else - pixels8[i] = (byte)0; - } - } else { // threshold red - for (int i=0; i=t1 && value<=t2) - pixels8[i] = (byte)255; - } - } - } - return createBufferedImage(); - } // create 8-bit image by linearly scaling from 16-bits to 8-bits private byte[] create8BitImage(boolean thresholding) {