📄 blkimgdatasrcimageproducer.java
字号:
public void startProduction(ImageConsumer ic) { int i,k1,k2,k3,k4,l; // counters int tmp1,tmp2,tmp3,tmp4; // temporary storage for sample values int mv1,mv2,mv3,mv4; // max value for each component int ls1,ls2,ls3,ls4; // level shift for each component int fb1,fb2,fb3,fb4; // fractional bits for each component int[] data1,data2,data3,data4; // references to data buffers final ImageConsumer[] cons; // image consumers cache int hints; // hints to image consumers int height; // image height int width; // image width int pixbuf[]; // line buffer for pixel data DataBlkInt db1,db2,db3,db4; // data-blocks to request data from src int tOffx, tOffy; // Active tile offset boolean prog; // Flag for progressive data Coord nT = src.getNumTiles(null); int tIdx = 0; // index of the current tile // Register ic if (ic != null) { addConsumer(ic); } // Set the cache for the consumers synchronized (this) { // synchronized to avoid addition or deletion of consumers while // copying them to cache cons = new ImageConsumer[consumers.size()]; consumers.copyInto(cons); } if (src == null) { // We cant't render with no source for (i=cons.length-1; i>=0; i--) { cons[i].imageComplete(ImageConsumer.IMAGEERROR); } return; // can not continue processing } // Initialize pixbuf = null; // to keep compiler happy ls2 = fb2 = mv2 = 0; // to keep compiler happy ls3 = fb3 = mv3 = 0; // to keep compiler happy ls4 = fb4 = mv4 = 0; // to keep compiler happy db1 = db2 = db3 = db4 = null; // to keep compiler happy switch (type) { case RGBA: db4 = new DataBlkInt(); // Alpha plane ls4 = 1<<(src.getNomRangeBits(3)-1); mv4 = (1<<src.getNomRangeBits(3))-1; fb4 = src.getFixedPoint(3); case RGB: db3 = new DataBlkInt(); // Blue plane ls3 = 1<<(src.getNomRangeBits(2)-1); mv3 = (1<<src.getNomRangeBits(2))-1; fb3 = src.getFixedPoint(2); db2 = new DataBlkInt(); // Green plane ls2 = 1<<(src.getNomRangeBits(1)-1); mv2 = (1<<src.getNomRangeBits(1))-1; fb2 = src.getFixedPoint(1); case GRAY: db1 = new DataBlkInt(); // Gray or Red plane ls1 = 1<<(src.getNomRangeBits(0)-1); mv1 = (1<<src.getNomRangeBits(0))-1; fb1 = src.getFixedPoint(0); break; default: throw new Error("Internal JJ2000 error"); } // Set the hints and info to the cached consumers nT = src.getNumTiles(null); hints = ImageConsumer.SINGLEFRAME|ImageConsumer.SINGLEPASS; if (nT.x == 1) { hints |= ImageConsumer.COMPLETESCANLINES| ImageConsumer.TOPDOWNLEFTRIGHT; } else { hints |= ImageConsumer.RANDOMPIXELORDER; } for (i=cons.length-1; i>=0; i--) { cons[i].setColorModel(cm); cons[i].setDimensions(src.getImgWidth(),src.getImgHeight()); cons[i].setHints(hints); } // Start the data delivery to the cached consumers tile by tile for(int y=0; y<nT.y; y++){ // Loop on horizontal tiles for(int x=0; x<nT.x; x++, tIdx++){ src.setTile(x,y); // Initialize tile height = src.getHeight(); width = src.getWidth(); if(pixbuf == null || pixbuf.length < width){ pixbuf = new int[width]; } // The offset of the active tiles is the same for all // components, // since we don't support different component dimensions. tOffx = src.getULX(0)- (src.getImgULX()+src.getCompSubsX(0)-1)/src.getCompSubsX(0); tOffy = src.getULY(0)- (src.getImgULY()+src.getCompSubsY(0)-1)/src.getCompSubsY(0); // Deliver in lines to reduce memory usage for (l=0; l < height;l++) { // Request line data prog = false; switch (type) { case RGBA: // Request alpha plane db4.ulx = 0; db4.uly = l; db4.w = width; db4.h = 1; src.getInternCompData(db4,3); prog = prog || db4.progressive; case RGB: // Request blue and green planes db2.ulx = db3.ulx = 0; db2.uly = db3.uly = l; db2.w = db3.w = width; db2.h = db3.h = 1; src.getInternCompData(db3,2); prog = prog || db3.progressive; src.getInternCompData(db2,1); prog = prog || db2.progressive; case GRAY: // Request db1.ulx = 0; db1.uly = l; db1.w = width; db1.h = 1; src.getInternCompData(db1,0); prog = prog || db1.progressive; break; } if (prog) { // Progressive data not supported // We use abort since maybe at a later time // the data won't // be progressive anymore // (DSC: this need to be improved of course) for (i=cons.length-1; i>=0; i--) { cons[i].imageComplete(ImageConsumer.IMAGEABORTED); } return; // can not continue processing } // Put pixel data in line buffer switch (type) { case GRAY: data1 = db1.data; k1 = db1.offset+width-1; for (i=width-1; i>=0; i--) { tmp1 = (data1[k1--]>>fb1)+ls1; tmp1 = (tmp1 < 0) ? 0 : ((tmp1 > mv1) ? mv1 : tmp1); pixbuf[i] = (0xFF<<24)|(tmp1<<16)|(tmp1<<8)|tmp1; } break; case RGB: data1 = db1.data; // red data2 = db2.data; // green data3 = db3.data; // blue k1 = db1.offset+width-1; k2 = db2.offset+width-1; k3 = db3.offset+width-1; for (i=width-1; i>=0; i--) { tmp1 = (data1[k1--]>>fb1)+ls1; tmp1 = (tmp1 < 0) ? 0 : ((tmp1 > mv1) ? mv1 : tmp1); tmp2 = (data2[k2--]>>fb2)+ls2; tmp2 = (tmp2 < 0) ? 0 : ((tmp2 > mv2) ? mv2 : tmp2); tmp3 = (data3[k3--]>>fb3)+ls3; tmp3 = (tmp3 < 0) ? 0 : ((tmp3 > mv3) ? mv3 : tmp3); pixbuf[i] = (0xFF<<24)|(tmp1<<16)|(tmp2<<8)|tmp3; } break; case RGBA: data1 = db1.data; // red data2 = db2.data; // green data3 = db3.data; // blue data4 = db4.data; // alpha k1 = db1.offset+width-1; k2 = db2.offset+width-1; k3 = db3.offset+width-1; k4 = db4.offset+width-1; for (i=width-1; i>=0; i--) { tmp1 = (data1[k1--]>>fb1)+ls1; tmp1 = (tmp1 < 0) ? 0 : ((tmp1 > mv1) ? mv1 : tmp1); tmp2 = (data2[k2--]>>fb2)+ls2; tmp2 = (tmp2 < 0) ? 0 : ((tmp2 > mv2) ? mv2 : tmp2); tmp3 = (data3[k3--]>>fb3)+ls3; tmp3 = (tmp3 < 0) ? 0 : ((tmp3 > mv3) ? mv3 : tmp3); tmp4 = (data4[k4--]>>fb4)+ls4; tmp4 = (tmp4 < 0) ? 0 : ((tmp4 > mv4) ? mv4 : tmp4); pixbuf[i] = (tmp4<<24)|(tmp1<<16)|(tmp2<<8)|tmp3; } break; } // Send the line data to the consumers for (i=cons.length-1; i>=0; i--) { cons[i].setPixels(tOffx,tOffy+l,width,1,cm,pixbuf, 0,width); } } } // End loop on horizontal tiles } // End loop on vertical tiles // Go back to first tile (this might free up resources, since it // indicates that we are done with the current tile)// src.setTile(0,0); // Signal that this frame is complete. This is so that display of the // last tile occurs as soon as possible. When calling with // STATICIMAGEDONE the ImageConsumer might do some cleanup that will // take a considerable amount of time on large images, this is why we // first signal the frame as done (even though there is only one). for (i=cons.length-1; i>=0; i--) { cons[i].imageComplete(ImageConsumer.SINGLEFRAMEDONE); } // Signal that image is complete for (i=cons.length-1; i>=0; i--) { cons[i].imageComplete(ImageConsumer.STATICIMAGEDONE); } // Remove the consumers since all the data has been sent synchronized (this) { for (i=cons.length-1; i>=0; i--) { consumers.removeElement(cons[i]); } } } /** * Starts the delivery of pixel data in the top-down letf-right order to * the image consumer 'ic'. The TOPDOWNLEFTRIGHT hint is set in * the image consumer on delivery. * * <P>Currently this call is ignored (which is perfectly legal according * to the ImageProducer interface specification). * * @param ic The image consumer to which the data is sent in top-down, * left-right order. * * * */ public void requestTopDownLeftRightResend(ImageConsumer ic) { }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -