Friday, 21 September 2007

CSS study ------> part 2 ------> W3School

This is a very helpful place for you to study CSS. It has almost everything you need for CSS. And examples are very useful.

In your HTML page, you need to have style.css imported, which will help you to format your page properly, like
<head>
<link rel="stylesheet" type="text/css" href="mystyle.css" />
</head>

This tells the browser to look for the style sheet for the web pages.
Generally the style sheet starts with some basic format definitions of the page,like h1, h2, h3, p and a etc.

Saturday, 15 September 2007

CSS study ------> part 1 ------> warm up

I just finished a Java-based tool for radiation beam modelling. Later I will put some GUI codes in this blog.


Recently I am trying to build website by myself. I know some simple CSS for web coding, but to make a beautiful website I have to study it again.

From W3C, you can have some idea about it.

There is class in style sheet, but it is not the class as in C++/Java. It starts with '.' (dot) and follows the name of the class, for example,

p.right {text-align: right}
p.center {text-align: center}

Used in HTML,
< p class="right" >
This paragraph will be right-aligned.
</p>
<p class="center">
This paragraph will be center-aligned.
</p>

If a class has no tag name, it could be used by any tag. If '#' starts before a name, it is an id selector and used with id in HTML.

Wednesday, 29 August 2007

Frondeg Guest House - An unpleasant experience

I was planning to have a bank holiday weekend in Harlech Wales. I booked a room from this B&B a month in advance.

I found this B&B from the Internet and I emailed the owner. On the same day I got the reply.

"
Hi,
I have reserved the twin ensuite for you for the 25 and 25 August. My house is 9 miles up the A496 from Barmouth 1 mile before Harlech you will see village sign called Llanfair 500yds from that sign you will see my house on the cross road on your right it is covered in green leaves. Hope you can make it I have your phone number if the weather looks bad I will phone you to see if you are coming.
"

From this email, which was sent on 8th August, I found the owner was very kind. And to correct her mistake of the dates I emailed her again on 8th August. Here is her reply.

"Hi,
Sorry my mistake 25 and 26 are reserved for you.
"

On 22th August, I received another email from her for confirmation.

"
Hi,
Just checking that you are coming to stay B&B at the weekend the weather promises to be good but I need a definite confirmation that you are coming as there is a big demand for the room. I cannot guarantee that I can keep the room for you unless you answer this email or phone me.
"

Once I received this email, I replied her immediately and asked her to keep the room for me. I was so happy to have a trip to Snowdonia.

In the evening of 24th August, I called her for asking the detail of check-in time etc., and she told me there would not be B&B for me, because her daughter was ill. She told me she'd sent an email to me for the cancellation.

I was shocked. I have never had this kind experience before.

A business woman can be just so easy to break her promise.

I've NEVER received the cancellation email she sent.

An email sent by her mentioned about large demanding for the room just 2 days ago makes me suspect about her excuse. I could not believe she just shut down B&B for every booked customer.

If this is really an emergency, she has not even tried to make sure I know the case. This ends up I could not find anywhere to stay. If I went there, the thing could be even worse!

In the telephone, she has not even made an apology for the cancellation!

This is just a very bad experience to me.

Conclusions for everyone:
Frondeg Guest House is not a B&B you can trust. To book it, it will be on your own risk, because it could be cancelled without letting you know. You might end up with nowhere to stay!

For me, I won't try it again.

Plan for next month

Do not have much time this month. I plan to keep on writing in September.

There will be some practical examples of Java. The C# will be the new content in my blog.

Monday, 30 July 2007

Image Display

JAI uses the Java 2D BufferedImage model for displaying images. The BufferedImage manages an image in memory and provides ways to store pixel data, interpret pixel data, and to render the pixel data to a Graphics2D context.

The display of images in JAI may be accomplished in several ways. First, the drawRenderedImage() call on Graphics2D may be used to produce an immediate rendering. Another method is to instantiate a display widget that responds to user requests such as scrolling and panning, as well as expose events, and requests image data from a RenderedImage source. This technique allows image data to be computed on demand.

* int getWidth()
returns the width of the rendered image.

* int getHeight()
returns the height of the rendered image.

* ScrollingImagePanel(RenderedImage im, int width, int height)
constructs a ScrollingImagePanel of a given size for a given RenderedImage.

* void setOrigin(int x, int y)
sets the image origin to a given (x, y) position. The scrollbars are updated appropriately.

* void setCenter(int x, int y)
sets the image center to a given (x, y) position. The scrollbars are updated appropriately.

* ImageCanvas(RenderedImage im, boolean drawBorder)
constructs an ImageCanvas to display a RenderedImage.

* ImageCanvas(java.awt.image.RenderedImage im)
constructs an ImageCanvas to display a RenderedImage.

* void set(RenderedImage im)
changes the source image to a new RenderedImage.

* void paint(java.awt.Graphics g)
paint the image onto a Graphics object.

* void setOrigin(int x, int y)
sets the origin of the image at x,y.

* int getXOrigin()
returns the x coordinate of the image origin.

* int getYOrigin()
returns the y coordinate of the image origin.

Tuesday, 24 July 2007

Reading Image Files

JAI directly supports several of the most common image file formats, BMP, FPX, GIF, JPEG, PNG, PNM, TIFF.

An image file usually has at least two parts: a file header and the image data. The header contains fields of pertinent information regarding the following image data. At the very least, the header must provide all the information necessary to reconstruct the original image from the stored image data. The image data itself may or may not be compressed.

For most image types, JAI offers the option of reading an image data file as a java.io.File object or as one of the subclasses of java.io.InputStream.

The Stream operation reads an image from a SeekableStream.
// Load the source image from a Stream.
RenderedImage im = JAI.create("stream", stream);


The FileLoad operation reads an image from a file.
// Load the source image from a file.
RenderedImage src = (RenderedImage)JAI.create("fileload", fileName);


The TIFF operation reads TIFF data from a TIFF SeekableStream.

For TIFF Palette color images, the colorMap always has entries of short data type, the color black being represented by 0,0,0 and white by 65536,65536,65536. To display these images, the default behavior is to dither the short values down to 8 bits. The dithering is done by calling the decode16BitsTo8Bit method for each short value that needs to be dithered.

A TIFF file may contain more than one Image File Directory (IFD). Each IFD defines a subfile, which may be used to describe related images. To determine the number of images in a TIFF file, use the TIFFDirectory.getNumDirectories() method.

API: com.sun.media.jai.codec.TIFFDecodeParam
* void setDecodePaletteAsShorts(boolean decodePaletteAsShorts)
if set, the entries in the palette will be decoded as shorts and no short-to-byte lookup will be applied to them.

* boolean getDecodePaletteAsShorts()
returns true if palette entries will be decoded as shorts, resulting in a output image with short datatype.

* byte decode16BitsTo8Bits(int s)
returns an unsigned 8-bit value computed by dithering the unsigned 16-bit value.

API: com.sun.media.jai.codec.TIFFDirectory
* static int getNumDirectories(SeekableStream stream)
returns the number of image directories (subimages) stored in a given TIFF file, represented by a SeekableStream.

API: com.sun.media.jai.codec.TIFFField
* int getTag()
returns the tag number, between 0 and 65535.

* int getType()
returns the type of the data stored in the IFD.

* int getCount()
returns the number of elements in the IFD.

API: com.sun.media.jai.codec.TIFFDirectory
* TIFFDirectory(SeekableStream stream, int directory)
constructs a TIFFDirectory from a SeekableStream.

* TIFFDirectory(SeekableStream stream, long ifd_offset)
constructs a TIFFDirectory by reading a SeekableStream.

* int getNumEntries()
returns the number of directory entries.

* TIFFField getField(int tag)
returns the value of a given tag as a TIFFField, or null if the tag is not present.

* boolean isTagPresent(int tag)
returns true if a tag appears in the directory.

* int[] getTags()
returns an ordered array of ints indicating the tag values.

* TIFFField[] getFields()
returns an array of TIFFFields containing all the fields in this directory.

* byte getFieldAsByte(int tag, int index)
returns the value of a particular index of a given tag as a byte.

* byte getFieldAsByte(int tag)
returns the value of index 0 of a given tag as a byte.

* long getFieldAsLong(int tag, int index)
returns the value of a particular index of a given tag as a long.

* long getFieldAsLong(int tag)
returns the value of index 0 of a given tag as a long.

* float getFieldAsFloat(int tag, int index)
returns the value of a particular index of a given tag as a float.

* float getFieldAsFloat(int tag)
returns the value of a index 0 of a given tag as a float.

* double getFieldAsDouble(int tag, int index)
returns the value of a particular index of a given tag as a double.

* double getFieldAsDouble(int tag)
returns the value of index 0 of a given tag as a double.


Example of Reading a BMP Image

// Wrap the InputStream in a SeekableStream.
InputStream is = new FileInputStream(filename);
SeekableStream s = SeekableStream.wrapInputStream(is, false);

// Create the ParameterBlock and add the SeekableStream to it.
ParameterBlock pb = new ParameterBlock();
pb.add(s);

// Perform the BMP operation
op = JAI.create("BMP", pb);


Example of Reading a PNM Image

// Create the ParameterBlock.
InputStream image = new FileInputStream(filename);
ParameterBlock pb = new ParameterBlock();
pb.add(image);

// Create the PNM operation.
op = JAI.create("PNM", pb);


Example of Reading an AWT Image

// Create the ParameterBlock.
ParameterBlock pb = new ParameterBlock();
pb.add(image);

// Create the AWTImage operation.
PlanarImage im = (PlanarImage)JAI.create("awtImage", pb);


Example of Reading a URL Image

// Define the URL to the image.
url = new URL("http://webstuff/images/duke.gif");

// Read the image from the designated URL.
RenderedOp src = JAI.create("url", url);


Example of Converting a Rendered Image to Renderable

// Derive the RenderableImage from the source RenderedImage.
ParameterBlock pb = new ParameterBlock();
pb.addSource(src);
pb.add(null).add(null).add(null).add(null).add(null);

// Create the Renderable operation.
RenderableImage ren = JAI.createRenderable("renderable", pb);


Example Constant Operation

// Create the ParameterBlock.
Byte[] bandValues = new Byte[1];
bandValues[0] = alpha1;
pb = new ParameterBlock();
pb.add(new Float(src1.getWidth())); // The width
pb.add(new Float(src1.getHeight())); // The height
pb.add(bandValues); // The band values

// Create the constant operation.
PlanarImage afa1 = (PlanarImage)JAI.create("constant", pb);

Streams

The new seekable classes are used to cache the image data being read so that methods can be used to seek backwards and forwards through the data without having to re-read the data. This is especially important for image data types that are segmented or that cannot be easily re-read to locate important information.

Class: SeekableStream
Extends: InputStream
Implements: DataInput
An abstract class that combines the functionality of InputStream and RandomAccessFile, along with the ability to read primitive data types in little-endian format.

Class: FileSeekableStream
Extends: SeekableStream
Implements SeekableStream functionality on data stored in a File.

Class: ByteArraySeekableStream
Extends: SeekableStream
Implements SeekableStream functionality on data stored in an array of bytes.

Class: SegmentedSeekableStream
Extends: SeekableStream
Provides a view of a subset of another SeekableStream consisting of a series of segments with given starting positions in the source stream and lengths. The resulting stream behaves like an ordinary SeekableStream.

Class: ForwardSeekableStream
Extends: SeekableStream
Provides SeekableStream functionality on data from an InputStream with minimal overhead, but does not allow seeking backwards. ForwardSeekableStream may be used with input formats that support streaming, avoiding the need to cache the input data.

Class: FileCacheSeekableStream
Extends: SeekableStream
Provides SeekableStream functionality on data from an InputStream with minimal overhead, but does not allow seeking backwards. ForwardSeekableStream may be used with input formats that support streaming, avoiding the need to cache the input data. In circumstances that do not allow the creation of a temporary file (for example, due to security consideration or the absence of local disk), the MemoryCacheSeekableStream class may be used.

Class: MemoryCacheSeekableStream
Extends: SeekableStream
Provides SeekableStream functionality on data from an InputStream, using an in-memory cache to allow seeking backwards. MemoryCacheSeekableStream should be used when security or lack of access to local disk precludes the use of FileCacheSeekableStream.

A complete list of the methods to read data:
readInt: Reads a signed 32-bit integer
readIntLE: Reads a signed 32-bit integer in little-endian order
readShort: Reads a signed 16-bit number
readShortLE: Reads a 16-bit number in little-endian order
readLong: Reads a signed 64-bit integer
readLongLE: Reads a signed 64-bit integer in little-endian order
readFloat: Reads a 32-bit float
readFloatLE: Reads a 32-bit float in little-endian order
readDouble: Reads a 64-bit double
readDoubleLE: Reads a 64-bit double in little-endian order
readChar: Reads a 16-bit Unicode character
readCharLE: Reads a 16-bit Unicode character in little-endian order
readByte: Reads an signed 8-bit byte
readBoolean: Reads a Boolean value
readUTF: Reads a string of characters in UTF (Unicode Text Format)
readUnsignedShort: Reads an unsigned 16-bit short integer
readUnsignedShortLE: Reads an unsigned 16-bit short integer in little-endian order
readUnsignedInt: Reads an unsigned 32-bit integer
readUnsignedIntLE: Reads an unsigned 32-bit integer in little-endian order
readUnsignedByte: Reads an unsigned 8-bit byte
readLine: Reads in a line that has been terminated by a line-termination character.
readFully: Reads a specified number of bytes, starting at the current stream pointer
read(): Reads the next byte of data from the input stream.

In addition to the familiar methods from InputStream, the methods getFilePointer() and seek(), are defined as in the RandomAccessFile class. The canSeekBackwards() method returns true if it is permissible to seek to a position earlier in the stream than the current value of getFilePointer(). Some subclasses of SeekableStream guarantee the ability to seek backwards while others may not offer this feature in the interest of efficiency for those users who do not require backward seeking.

Several concrete subclasses of SeekableStream are supplied in the com.sun.media.jai.codec package. Three classes are provided for the purpose of adapting a standard InputStream to the SeekableStream interface. The ForwardSeekableStream class does not allow seeking backwards, but is inexpensive to use. The FileCacheSeekableStream class maintains a copy of all of the data read from the input in a temporary file; this file will be discarded automatically when the FileSeekableStream is finalized, or when the JVM exits normally.

The FileCacheSeekableStream class is intended to be reasonably efficient apart from the unavoidable use of disk space. In circumstances where the creation of a temporary file is not possible, the MemoryCacheSeekableStream class may be used. The MemoryCacheSeekableStream class creates a potentially large in-memory buffer to store the stream data and so should be avoided when possible. The FileSeekableStream class wraps a File or RandomAccessFile. It forwards requests to the real underlying file. FileSeekableStream performs a limited amount of caching to avoid excessive I/O costs.

A convenience method, wrapInputStream is provided to construct a suitable SeekableStream instance whose data is supplied by a given InputStream. The caller, by means of the canSeekBackwards parameter, determines whether support for seeking backwards is required.

Multi-resolution Renderable Images

The MultiResolutionRenderableImage class produces renderings based on a set of supplied RenderedImages at various resolutions.

* public MultiResolutionRenderableImage(Vector renderedSources, float minX, float minY, float height)
constructs a MultiResolutionRenderableImage with given dimensions from a Vector of progressively lower resolution versions of a RenderedImage.

* RenderedImage createScaledRendering(int width, int height, RenderingHints hints)
returns a rendering with a given width, height, and rendering hints.

* RenderedImage createDefaultRendering()
returns a 100-pixel high rendering with no rendering hints.

* RenderedImage createRendering(RenderContext renderContext)
returns a rendering based on a RenderContext.

* Object getProperty(String name)
gets a property from the property set of this image.

* String[] getPropertyNames()
returns a list of the properties recognized by this image.

* float getWidth()
returns the floating-point width of the RenderableImage.

* float getHeight()
returns the floating-point height of the RenderableImage.

* float getMinX()
returns the floating-point minimum x coordinate of the RenderableImage.

* float getMaxX()
returns the floating-point maximum x coordinate of the RenderableImage.

* float getMinY()
returns the floating-point minimum y coordinate of the RenderableImage.

* float getMaxY()
returns the floating-point maximum y coordinate of the RenderableImage.

Image Pyramid

The ImagePyramid class implements a pyramid operation on a RenderedImage. Supposing that we have a RenderedImage of 1024 x 1024, we could generate ten additional images by successively averaging 2 x 2 pixel blocks, each time discarding every other row and column of pixels. We would be left with images of 512 x 512, 256 x 256, and so on down to 1 x 1.

The downSampler is a chain of operations used to derive the image at the next lower resolution level from the image at the current resolution level.

The upSampler is a chain of operations used to derive the image at the next higher resolution level from the image at the current resolution level.

The differencer is a chain of operations used to find the difference between an image at a particular resolution level and the image obtained by first down sampling that image then up sampling the result image of the down sampling operations.

The combiner is a chain of operations used to combine the resulting image of the up sampling operations and the different image saved to retrieve an image at a higher resolution level.

* ImagePyramid(RenderedImage image, RenderedOp downsampler, RenderedOp upSampler, RenderedOp differencer, RenderedOp combiner)
constructs an ImagePyramid object. The parameters point to the last operation in each chain. The first operation in each chain must not have any source images specified; that is, its number of sources must be 0.

* ImagePyramid(RenderedOp downSampler, RenderedOp upSampler, RenderedOp differencer, RenderedOp combiner)
constructs an ImagePyramid object.

* public RenderedImage getImage(int level)
returns the image at the specified resolution level.

* public RenderedImage getDownImage()
returns the image at the next lower resolution level, obtained by applying the downSampler on the image at the current resolution level.

* public RenderedImage getUpImage()
returns the image at the previous higher resolution level.

* public RenderedImage getDiffImage()
returns the difference image between the current image and the image obtained by first down sampling the current image then up sampling the result image of down sampling.

Other Image classes

A RemoteImage is a sub-class of PlanarImage which represents an image on a remote server.

The CollectionImage class is an abstract superclass for classes representing groups of images. Examples of groups of images include pyramids (ImagePyramid), time sequences (ImageSequence), and planar slices stacked to form a volume (ImageStack).

* CollectionImage()
the default constructor.

* CollectionImage(java.util.Collection images)
constructs a CollectionImage object from a Vector of ImageJAI objects.

The ImageSequence class represents a sequence of images with associated timestamps and a camera position. It can be used to represent video or time-lapse photography.

* ImageSequence(Collection images)
constructs a class that represents a sequence of images from a collection of SequentialImage.

The ImageStack class represents a stack of images, each with a defined spatial orientation in a common coordinate system. This class can be used to represent CT scans or seismic volumes.

* ImageStack(Collection images)
constructs an ImageStack object from a collection of CoordinateImage.

* ImageJAI getImage(Coordinate coordinate)
returns the image associated with the specified coordinate.

* Coordinate getCoordinate(ImageJAI image)
returns the coordinate associated with the specified image.

An image MIP map is a stack of images with a fixed operational relationship between adjacent slices. Given the highest-resolution slice, the others may be derived in turn by performing a particular operation. Data may be extracted slice by slice or by special iterators.

The ImageMIPMap class takes the original source image at the highest resolution level, considered to be level 0, and a RenderedOp chain that defines how the image at the next lower resolution level is derived from the current resolution level.

* ImageMIPMap(RenderedImage image, AffineTransform transform, Interpolation interpolation)
This constructor assumes that the operation used to derive the next lower resolution is a standard affine operation.

* ImageMIPMap(RenderedImage image, RenderedOp downSampler)
This constructor specifies the downSampler, which points to the RenderedOp chain used to derive the next lower resolution level.

* ImageMIPMap(RenderedOp downSampler)
This constructor specifies only the downSampler.

Snapshot Image

The SnapshotImage class represents the main component of the deferred execution engine. A SnapshotImage provides an arbitrary number of synchronous views of a possibly changing WritableRenderedImage. SnapshotImage is responsible for stabilizing changing sources to allow deferred execution of operations dependent on such sources.

This implementation of SnapshotImage makes use of a doubly-linked list of Snapshot objects. A new Snapshot is added to the tail of the list whenever createSnapshot() is called.

* SnapshotImage(PlanarImage source)
constructs a SnapshotImage from a PlanarImage source.

* Raster getTile(int tileX, int tileY)
returns a non-snapshotted tile from the source.

* void tileUpdate(java.awt.image.WritableRenderedImage source, int tileX, int tileY, boolean willBeWritable)
receives the information that a tile is either about to become writable, or is about to become no longer writable.

* PlanarImage createSnapshot()
creates a snapshot of this image.

* void dispose()
provides a hint that an image will no longer be accessed from a reference in user space.

Tiled Image

A tile represents all of the storage for its spatial region of the image. If an image contains three bands, every tile represents all three bands of storage. The use of tiled images improves application performance by allowing the application to process an image region within a single tile without bringing the entire image into memory.

TiledImage provides a straightforward implementation of the WritableRenderedImage interface, taking advantage of that interface's ability to describe images with multiple tiles. The tiles of a WritableRenderedImage must share a SampleModel, which determines their width, height, and pixel format.

The contents of a TiledImage are defined by a single PlanarImage source, provided either at construction time or by means of the set() method.

TiledImage also supports direct manipulation of pixels by means of the getWritableTile method. This method returns a WritableRaster that can be modified directly. Such changes become visible to readers according to the regular thread synchronization rules of the Java virtual machine; JAI makes no additional guarantees. When a writer is finished modifying a tile, it should call the releaseWritableTile method. A shortcut is to call the setData() method, which copies a rectangular region from a supplied Raster directly into the TiledImage.

A final way to modify the contents of a TiledImage is through calls to the createGraphics() method. This method returns a GraphicsJAI object that can be used to draw line art, text, and images in the usual AWT manner.

TiledImage does not actually cause its tiles to be computed until their contents are demanded. Once a tile has been computed, its contents may be discarded if it can be determined that it can be recomputed identically from the source. The lockTile() method forces a tile to be computed and maintained for the lifetime of the TiledImage.

* TiledImage(Point origin, SampleModel sampleModel, int tileWidth, int tileHeight)
constructs a TiledImage with a SampleModel that is compatible with a given SampleModel, and given tile dimensions. The width and height are taken from the SampleModel, and the image begins at a specified point.

* TiledImage(SampleModel sampleModel, int tileWidth, int tileHeight)
constructs a TiledImage starting at the global coordinate origin.

* TiledImage(int minX, int minY, int width, int height, int tileGridXOffset, int tileGridYOffset, SampleModel sampleModel, ColorModel colorModel)
constructs a TiledImage of a specified width and height.

* void setData(Raster r)
sets a region of a TiledImage to be a copy of a supplied Raster. The Raster's coordinate system is used to position it within the image.

* void setData(Raster r, ROI roi)
sets a region of a TiledImage to be a copy of a supplied Raster. The Raster's coordinate system is used to position it within the image.

* WritableRaster getWritableTile(int tileX, int tileY)
retrieves a particular tile from the image for reading and writing.

* Raster getTile(int tileX, int tileY)
retrieves a particular tile from the image for reading only.

* boolean isTileWritable(int tileX, int tileY)
returns true if a tile has writers.

* boolean hasTileWriters()
returns true if any tile is being held by a writer, false otherwise.

* void releaseWritableTile(int tileX, int tileY)
indicates that a writer is done updating a tile.

* void set(RenderedImage im)
overlays a given RenderedImage on top of the current contents of the TiledImage.

* void set(RenderedImage im, ROI roi)
overlays a given RenderedImage on top of the current contents of the TiledImage.

* Graphics2D createGraphics()
creates a Graphics2D object that can be used to paint text and graphics onto the TiledImage.

The TileCache interface provides a central place for OpImages to cache tiles they have computed. The tile cache is created with a given capacity (measured in tiles). By default, the tile capacity for a new tile cache is 300 tiles. The default memory capacity reserved for tile cache is 20M bytes.

* static TileCache createTileCache(int tileCapacity, long memCapacity)
constructs a TileCache with the given tile capacity in tiles and memory capacity in bytes.

* static TileCache createTileCache()
constructs a TileCache with the default tile capacity in tiles and memory capacity in bytes.

* void setTileCache(TileCache tileCache)
sets the TileCache to be used by this JAI instance. The tileCache parameter will be added to the RenderingHints of this JAI instance.

* TileCache getTileCache()
returns the TileCache being used by this JAI instance.

A pattern tile consists of a repeated pattern. The pattern operation defines a pattern tile by specifying the width and height; all other layout parameters are optional, and when not specified are set to default values. Each tile of the destination image will be defined by a reference to a shared instance of the pattern.

Planar Image

The PlanarImage class is the main class for defining two-dimensional images. The PlanarImage implements the java.awt.image.RenderedImage interface, which describes a tiled, read-only image with a pixel layout described by a SampleModel and a DataBuffer. The TiledImage and OpImage subclasses manipulate the instance variables they inherit from PlanarImage, such as the image size, origin, tile dimensions, and tile grid offsets, as well as the Vectors containing the sources and sinks of the image.

All non-JAI RenderedImages that are to be used in JAI must be converted into PlanarImages by means of the RenderedImageAdapter class and the WriteableRenderedImageAdapter class. The wrapRenderedImage() method provides a convenient interface to both add a wrapper and take a snapshot if the image is writable. The standard PlanarImage constructor used by OpImages performs this wrapping automatically. Images that already extend PlanarImage will be returned unchanged by wrapRenderedImage().

* PlanarImage()
creates a PlanarImage.

* static PlanarImage wrapRenderedImage(RenderedImage im)
wraps an arbitrary RenderedImage to produce a PlanarImage.

* PlanarImage createSnapshot()
creates a snapshot, that is, a virtual copy of the image's current contents.

* Raster getData(Rectangle region)
returns a specified region of this image in a Raster.

* int getWidth()
returns the width of the image.

* int getHeight()
returns the height of the image.

* int getMinXCoord()
returns the X coordinate of the leftmost column of the image.

* int getMaxXCoord()
returns the X coordinate of the rightmost column of the image.

* int getMinYCoord()
returns the X coordinate of the uppermost row of the image.

* int getMaxYCoord()
returns the X coordinate of the bottom row of the image.

* Rectangle getBounds()
returns a Rectangle indicating the image bounds.

* int getTileWidth()
returns the width of a tile.

* int getTileHeight()
returns the height of a tile.

* int tilesAcross()
returns the number of tiles along the tile grid in the horizontal direction. Equivalent to getMaxTileX() - getMinTileX() + 1.

* int tilesDown()
returns the number of tiles along the tile grid in the vertical direction. Equivalent to getMaxTileY() - getMinTileY() + 1.

Monday, 23 July 2007

Image Load --- 1

The example in JAI program needs WindowContainer, which I downloaded from
http://swjscmail1.java.sun.com/cgi-bin/wa?A2=ind0104&L=jai-interest&D=0&P=28364

JAI supports several image data types, so the DataBuffer class has the following subclasses,
* DataBufferByte - stores data internally as bytes (8-bit values)
* DataBufferShort - stores data internally as shorts (16-bit values)
* DataBufferUShort - stores data internally as unsigned shorts (16-bit values)
* DataBufferInt - stores data internally as integers (32-bit values)
* DataBufferFloat - stores data internally as single-precision floating-point values.
* DataBufferDouble - stores data internally as double-precision floating-point values.

JAI also supports a large number of image data formats, so the SampleModel class provides the following types of sample models:
* ComponentSampleModel - used to extract pixels from images that store sample data in separate data array elements in one bank of a DataBuffer object.
* ComponentSampleModelJAI - used to extract pixels from images that store sample data such that each sample of a pixel occupies one data element of the DataBuffer.
* BandedSampleModel - used to extract pixels from images that store each sample in a separate data element with bands stored in a sequence of data elements.
* PixelInterleavedSampleModel - used to extract pixels from images that store each sample in a separate data element with pixels stored in a sequence of data elements.
* MultiPixelPackedSampleModel - used to extract pixels from single-banded images that store multiple one-sample pixels in one data element.
* SinglePixelPackedSampleModel - used to extract samples from images that store sample data for a single pixel in one data array element in the first bank of a DataBuffer object.
* FloatComponentSampleModel - stores n samples that make up a pixel in n separate data array elements, all of which are in the same bank in a DataBuffer object. This class supports different kinds of interleaving.

The combination of a DataBuffer object, a SampleModel object, and an origin constitute a meaningful multi-pixel image storage unit called a Raster. The Raster class has methods that directly return pixel data for the image data it contains.

There are two basic Raster types:
* Raster - represents a rectangular array of pixels. This is a "read-only" class that only has get methods.
* WritableRaster - extends Raster to provide pixel writing capabilities.

There are separate interfaces for dealing with each raster type:
* The RenderedImage interface assumes the data is read-only and, therefore, does not contain methods for writing a Raster.
* The WriteableRenderedImage interfaces assumes that the image data can be modified.

A ColorModel class provides a color interpretation of pixel data provided by the image's sample model. The combination of a Raster and a ColorModel define a BufferedImage.

Rendering Hints

The rendering hints contain a set of hints that describe how objects are to be rendered. The rendering hints are always optional in any operation.

There are two separate classes for specifying rendering hints:
* java.awt.RenderingHints - contains rendering hints that can be used by the Graphics2D class, and classes that implement BufferedImageOp and Raster.
* javax.media.jai.JAI - provides methods to define the RenderingHints keys specific to JAI.

Creating Operations

There are four variations on methods for creating operations in the Renderable mode,
* createRenderable
* createRenderableNS
* createRenderable-Collection
* createRenderable-CollectionNS

Example:
RenderedOp im = JAI.createNS("operationName", source, param1, param2);

The operation name is always enclosed in quotation marks. The operation name parsing is case-insensitive.

The parameter block contains the source of the operation and a set parameters used by the operation.

These controlling parameters and sources can be edited through the setParameterBlock method to affect specific operations or even the structure of the rendering chain itself.

There are two separate classes for specifying parameter blocks:
* java.awt.image.renderable.ParameterBlock - the main class for specifying and changing parameter blocks.
* javax.media.jai.ParameterBlockJAI - extends ParameterBlock by allowing the use of default parameter values and the use of parameter names.

Adding Sources to a Parameter BlocK
Example:
ParameterBlock pb = new ParameterBlock();
pb.addSource(im0);
pb.addSource(im1);

There are two separate classes for specifying parameter blocks: ParameterBlock and ParameterBlockJAI.
ParameterBlockJAI automatically provides default parameter values and allows setting parameters by name; ParameterBlock does not.

API: java.awt.image.renderable.ParameterBlock
The operation parameters are added to a ParameterBlock with the ParameterBlock.add() method.

Since the ParameterBlockJAI object already contains default values for the parameters at the time of construction, the parameters must be changed (or set) with the ParameterBlockJAI.set(value, index) methods rather than the add() method.

JAI API Operators

The general categories of image processing operators supported include:
* Point Operators
* Area Operators
* Geometric Operators
* Color Quantization Operators
* File Operators
* Frequency Operators
* Statistical Operators
* Edge Extraction Operators
* Miscellaneous Operators

Basic JAI API Classes

JAI consists of several classes grouped into four packages:
* javax.media.jai - contains the "core" JAI interfaces and classes
* javax.media.jai.iterator - contains special iterator interfaces and classes, which are useful for writing extension operations
* javax.media.jai.operator - contains classes that describe all of the image operators
* javax.media.jai.widget - contains interfaces and classes for creating simple image canvases and scrolling windows for image display

The PlanarImage class is the main class for describing two-dimensional images in JAI. PlanarImage implements the RenderedImage interface from the Java 2D API. TiledImage and OpImage, described later, are subclasses of PlanarImage.

The RenderedImage interface describes a tiled, read-only image with a pixel layout described by a SampleModel and a DataBuffer. Each tile is a rectangle of identical dimensions, laid out on a regular grid pattern. All tiles share a common SampleModel.

In addition to the capabilities offered by RenderedImage, PlanarImage maintains source and sink connections between the nodes of rendered graphs. Since graph nodes are connected bidirectionally, the garbage collector requires assistance to detect when a portion of a graph is no longer referenced from user code and may be discarded. PlanarImage takes care of this by using the Weak References API of Java 2.

Any RenderedImages from outside the API are "wrapped" to produce an instance of PlanarImage. This allows the API to make use of the extra functionality of PlanarImage for all images.

CollectionImage is the abstract superclass for four classes representing collections of PlanarImages:
* ImageStack - represents a set of two-dimensional images lying in a common three-dimensional space, such as CT scans or seismic volumes. The images need not lie parallel to one another.
* ImageSequence - represents a sequence of images with associated time stamps and camera positions. This class can be used to represent video or time-lapse photography.
* ImagePyramid - represents a series of images of progressively lesser resolution, each derived from the last by means of an imaging operator.
* ImageMIPMap - represents a stack of images with a fixed operational relationship between adjacent slices.

The TiledImage class represents images containing multiple tiles arranged into a grid.
TiledImage implements the WritableRenderedImage interface from the Java 2D API, as well as extending PlanarImage. A TiledImage allows its tiles to be checked out for writing, after which their pixel data may be accessed directly. TiledImage also has a createGraphics method that allows its contents to be altered using Java 2D API drawing calls.

The OpImage class is the parent class for all imaging operations, such as:
* AreaOpImage - for image operators that require only a fixed rectangular source region around a source pixel to compute each destination pixel
* PointOpImage - for image operators that require only a single source pixel to compute each destination pixel
* SourcelessOpImage - for image operators that have no image sources
* StatisticsOpImage - for image operators that compute statistics on a given region of an image, and with a given sampling rate
* UntiledOpimage - for single-source operations in which the values of all pixels in the source image contribute to the value of each pixel in the destination image
* WarpOpImage - for image operators that perform an image warp
* ScaleOpImage - for extension operators that perform image scaling requiring rectilinear backwards mapping and padding by the resampling filter dimensions
The OpImage is able to determine what source areas are sufficient for the computation of a given area of the destination by means of a user-supplied mapDestRect method. For most operations, this method as well as a suitable implementation of getTile is supplied by a standard subclass of OpImage, such as PointOpImage or AreaOpImage.
An OpImage is effectively a PlanarImage that is defined computationally. In PlanarImage, the getTile method of RenderedImage is left abstract, and OpImage subclasses override it to perform their operation. Since it may be awkward to produce a tile of output at a time, due to the fact that source tile boundaries may need to be crossed, the OpImage class defines a getTile method to cobble (copy) source data as needed and to call a user-supplied computeRect method. This method then receives contiguous source Rasters that are guaranteed to contain sufficient data to produce the desired results. By calling computeRect on subareas of the desired tile, OpImage is able to minimize the amount of data that must be cobbled.

The RenderableOp class provides a lightweight representation of an operation in the Renderable space. RenderableOps are typically created using the createRenderable method of the JAI class, and may be edited at will. RenderableOp implements the RenderableImage interface, and so may be queried for its rendering-independent dimensions.

The RenderedOp is a lightweight object similar to RenderableOp that stores an operation name, ParameterBlock, and RenderingHints, and can be joined into a Rendered graph

Wednesday, 18 July 2007

Start of JAI programming

Four steps of JAI programming:
1. Get the image data from file or data source;
2. Define the imaging graph;
3. Evaluate the graph using one of three execution models: Rendered execution model, Renderable execution model and Remote execution model;
4. Process the result: save, display, print or send.

Monday, 9 July 2007

Java Advanced Imaging API

The JAI API builds on the foundation of the Java 2D API. The JAI API adds the following concepts:
* Multi-tiled images
* Deferred execution
* Networked images
* Image property management
* Image operators with multiple sources
* Three-dimensional image data

The JAI API is heavily dependent on the abstractions defined in the Java 2D API.

JAI introduces two new data classes,

Class: DataBufferFloat
Extends: DataBuffer

Class: DataBufferDouble
Extends: DataBuffer

DataBufferFloat Class
DataBufferFloat(int size)
DataBufferFloat(int size, int numBanks)
ataBufferFloat(float[] dataArray, int size) //The array must be large enough to hold size elements.
DataBufferFloat(float[] dataArray, int size, int offset) //Only the elements between offset and (offset + size - 1) are available for use by this DataBuffer. The array must be large enough to hold (offset + size) elements.
DataBufferFloat(float[][] dataArray, int size)
DataBufferFloat(float[][] dataArray, int size, int[] offsets)

DataBufferDouble Class
DataBufferDouble(int size)
DataBufferDouble(int size, int numBanks)
DataBufferDouble(double[] dataArray, int size)
DataBufferDouble(double[] dataArray, int size, int offset)
DataBufferDouble(double[][] dataArray, int size)
DataBufferDouble(double[][] dataArray, int size, int[] offsets)

Java Image Data

Image Data Classes,

Class: DataBuffer
Extends: Object

Class: Raster
Extends: Object

Class: SampleModel
Extends: Object

Class: WriteableRaster
Extends: Raster

The basic unit of image data storage is the DataBuffer. The DataBuffer is a kind of raw storage that contains all of the samples for the image data but does not maintain a notion of how those samples can be put together as pixels. The information about how the samples are put together as pixels is contained in a SampleModel. The SampleModel class contains methods for deriving pixel data from a DataBuffer. Together, a DataBuffer and a SampleModel constitute a meaningful multi-pixel image storage unit called a Raster.

A Raster has methods that directly return pixel data for the image data it contains.
* Raster - a read-only object that has only accessors
* WritableRaster - A writable object that has a variety of mutators

There are separate interfaces for dealing with each raster type. The RenderedImage interface assumes that the data is read-only and does not contain methods for writing a Raster. The WritableRenderedImage interface assumes that the image data is writeable and can be modified.

Data from a tile is returned in a Raster object. A tile is not a class in the architecture; it is a concept. In the Java 2D API, the implementation of the WritableRenderedImage (BufferedImage) is defined to have a single tile. This, the getWritableTile method will return all the image data. Other methods that relate to tiling will return the correct degenerative results.

RenderedImages do not necessarily maintain a Raster internally. Rather, they can return requested rectangles of image data in the form of a (Writable)Raster (through the getData, getRect, and get(Writable)Tile methods). This distinction allows RenderedImages to be virtual images, producing data only when needed. RenderedImages do, however, have an associated SampleModel, implying that data returned in Rasters from the same image will always be written to the associated DataBuffer in the same way.

The Java 2D BufferedImage also adds an associated ColorModel, which is different from the SampleModel. The ColorModel determines how the bands are interpreted in a colorimetric sense.

Sunday, 8 July 2007

Java 2D API --- the rendereds

The Rendered layer is designed to work in concert with the Renderable layer. The Rendered layer is comprised of sources and operations for device-specific representations of images or renderings. The Rendered layer is primarily defined by the RenderedImage interface. Sources such as BufferedImage implement this interface.

Operators in this layer are simply RenderedImages that take other RenderedImages as sources. Chains, therefore, can be constructed in much the same manner as those of the Renderable layer. A sequence of RenderedImages is instantiated, each taking the last RenderedImage as a source.

Interface: RenderedImage

Class: BufferedImage
Extends: Image
Implements: WritableRenderedImage

Class: WritableRenderedImage
Extends: RenderedImage

A rendered image represents a virtual image with a coordinate system that maps directly to pixels. A Rendered image does not have to have image data associated with it, only that it be able to produce image data when requested. The BufferedImage class, which is the Java 2D API's implementation of RenderedImage, however, maintains a full page buffer that can be accessed and written to. Data can be accessed in a variety of ways, each with different properties.

Java 2D API --- the renderables

Renderable layer is for simplified image manipulation and it won't directly process image pixels. However, in many cases it is either necessary or desirable to work with pixels and the Rendered layer is used for this purpose.

The renderable layer is primarily defined by the RenderableImage interface. A chain in this layer is a chain of RenderableImages. Specifically, it is a chain of RenderableImageOps (a class that implements RenderableImage), ultimately sourced by a RenderableImage.

There is only one RenderableImageOp class. It is a lightweight, general purpose class that takes on the functionality of a specific operation through a parameter provided at instantiation time. That parameter is the name of a class that implements a ContextualRenderedImageFactory (known as a CRIF, for short). Each instantiation of RenderableImageOp derives its specific functionality from the named class. In this way, the Renderable layer is heavily dependent on the Rendered layer.

Interface: RenderableImage
OR ContextualRenderedImage-Factory
Extends: RenderedImageFactory

Class: ParameterBlock
Extends: Object
Implements: Cloneable, Serializable

Class: RenderableImageOp
Extends: Object
Implements: RenderableImage

Class: RenderableImageProducer
Extends: Object
Implements: ImageProducer, Runnable

Class: RenderContext
Extends: Object
Implements: Cloneable

A Renderable chain is constructed by instantiating each successive RenderableImageOp, passing in the last RenderableImage as the source in the ParameterBlock. This chain can then be requested to provide a number of renderings to specific device spaces through the getImage method. This chain, once constructed, remains editable.

Saturday, 7 July 2007

Java 2D API --- the beginning

The Java 2D API extends AWT's capabilities for both two-dimensional graphics and imaging. The concepts of rendered and renderable images contained in the Java 2D API are essential to JAI.

Rendering independence for images is a poorly understood topic because it is poorly named. The more general problem is "resolution independence," the ability to describe an image as you want it to appear, but independent of any specific instance of it. Resolution is but one feature of any such rendering. Others are the physical size, output device type, color quality, tonal quality, and rendering speed. A rendering-independent description is concerned with none of these.

The Java AWT API architecture provides for two integrated imaging layers: renderable and rendered.

Structurally, the Renderable layer is lightweight. It does not directly handle pixel processing. Rather, it makes use of operator objects from the Rendered layer. This is possible because the operator classes from the Rendered layer can implement an interface (the ContextualRenderedImageFactory interface) that allows them to adapt to different contexts.Many programmers will directly employ the Rendered layer, but the Renderable layer provides advantages that greatly simplify imaging tasks.

The renderable layer allows for the construction of a chain of operators (RenderableImageOps) connected to a RenderableImage source. The end of this chain represents a new RenderableImage source. The implication of this is that RenderableImageOps must implement the same interface as sources: RenderableImageOp implements RenderableImage.

Friday, 6 July 2007

AWT for images --- Push Model

I almost forgot why I use bsc. To remind myself, I put a note here. BSC = Budget SuperComputer.

AWT push model I do not understand why it is called push model. Anyway, let me carry on, here are some major classes, Image, ImageProducer, ImageConsumer, and ImageObserver.

It is from java.awt class package. An Image object is obtained from some source.

Image im = getToolkit().getImage(ImageFileName);

The ultimate destination for a filtered image is an AWT Image object, created by a call to, for example, Component.createImage(). Once this consumer image has been created, it can by drawn upon the screen by calling Image.getGraphics() to obtain a Graphics object (such as a screen device), followed by Graphics.drawImage().

AWT Imaging was largely designed to facilitate the display of images in a browser environment. In this context, an image resides somewhere on the network. There is no guarantee that the image will be available when required, so the AWT model does not force image filtering or display to completion. The model is entirely a push model. An ImageConsumer can never ask for data; it must wait for the ImageProducer to "push" the data to it. Similarly, an ImageConsumer has no guarantee about when the data will be completely delivered; it must wait for a call to its ImageComplete() method to know that it has the complete image. An application can also instantiate an ImageObserver object if it wishes to be notified about completion of imaging operations.

Cake club

I could not reject the nice taste cake, so I joined the cake club. It is not possible to be a taster all the time, so I have to look for some recipe to make a nice cake or relative product for others.

Search for cake ......
http://www.sofeminine.co.uk/m/food/chocolate-cake-recipe.html

sofeminine, I just cannot believe this. So many good names, why it chose to use this. So many different names for cake, make me completely lost.

Now I have to add a TAG of bakery.

Java programming

C, I've used it in my PhD and most of my study. I like it and I think it is quite good. Now it is time to have a look another option, Java. Is it good? Let me try.

It is quite simliar as C/C++, so it is no point to introduce it here. A good book to read is The Complete Reference Java. If you do not know C/C++, again The Complete Reference C and The Complete Reference C++.

My reference for JAI is http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/

Tuesday, 12 June 2007

Some C tutorials

There are a few tutorials of C programming. They are quite old but still very useful. Not every link has been tested. Since they are old, there might be some links not working.

http://www.faqs.org/faqs/C-faq/learn-c-cpp-today/
ftp://rtfm.mit.edu/pub/usenet/news.answers/C-faq/learn-c-cpp-today

Tuesday, 5 June 2007

Run EGSnrc in Parallel (2)

If there are two hosts are availeble for NQS.

Add .rhosts under home directory of user for hosts identification.

<hostname1> <username1>

<hostname2> <username1>

NFS is needed for Parallel EGSnrc.

There are three batch processing options in BEAMnrc, short 20 min, medium 2 hours, and long 40 days. Here is the configuration for short. Host host1 runs as server and also as processing node. Its configuraion is,

# for short, run limit is 2 because only 2 processors on each host
qmgr create batch short-dest pipeonly run_limit=2 user_limit=2
qmgr set per_process cpu_limit = \( 0:20:0 \) short-dest

# highest priority for short-dest
qmgr set priority = 40 short-dest
########running part of nqs ##########

###### gate of short #######
qmgr create pipe short-in pipeonly run_limit=2 destination=short-dest
qmgr set lb_in short-in
###### end of gate ########

qmgr set scheduler host1

qmgr create pipe short destination=short-scheduler@host1
####### pipe of short #########

####### server side ########
# under Mgr As Server, add two destinations
create pipe short-scheduler run_limit=20 destination=(short-in@host1,short-in@host2)
qmgr set lb_out short-scheduler

For host2, which runs a processing node, it does not need to have the server side configuration. For medium and long, just change the name and parameters.

Run EGSnrc in Parallel (1)

EGSnrc and BEAMnrc could be run in parallel as described in their documentations. One of the options is using NQS, Network Queuing System.

Here is the brief guide about how to install and configure Generic NQS.

First of all download the package.

Follow the instructions to install NQS locally. It is installed as standalone version.

Use nmapmgr to add host node,

> add host node

> add alias name node

> list

> exit

Use root to start NQS, qmgr start nqs

Create batch queues:

> qmgr create batch_queue short
> qmgr create batch_queue medium
> qmgr create batch_queue long

Specify CPU time:

> qmgr set per_process cpu_limit = \( 2:0:0 \) short
> qmgr set per_process cpu_limit = \( 8:0:0 \) medium
> qmgr set per_process cpu_limit = \( 24:0:0 \) long

Set up priority and runlimits:

> qmgr set priority = 40 short
> qmgr set priority = 30 medium
> qmgr set priority = 20 long

> qmgr set run_limit = 5 short
> qmgr set run_limit = 4 medium
> qmgr set run_limit = 2 long

Set up user limit:

> qmgr set user_limit = 2 short
> qmgr set user_limit = 1 medium
> qmgr set user_limit = 1 long

So far the configuration is done. Queues need to be enabled and started.

qmgr enable queue

qmgr start queue

Now we can submit tasks to the system.

qsub -eo -r what -q short something.sh

The tasks will start to run on the processor(s) if there is any available.

If you are running at a dual-processor or dual-core system, you could see the change of the performance.

Monday, 4 June 2007

EGSnrc and BeamNRC Installation

OS: Ubuntu 7.04

Install EGSnrc and BeamNRC:
  1. Install required software via Synaptic Package Manager;
  2. Install QT3.3.3; (Note GUI of EGSnrc was written under QT3, so it is incompatible with QT4) [add QTDIR=/usr/local/qt; MANPATH=$QTDIR/doc/man:$MANPATH; LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH; into /etc/bash.bashrc]
  3. Install EGSnrc and then BeamNRC using the method1 (the easiest method); [add HEN_HOUSE=/usr/local/EGSnrc; EGS_HOME=/usr/local/EGS_HOME; EGS_CONFIG="/usr/local/EGSnrc/specs/i686-pc-linux-gnu-g77.conf"; PATH=${HEN_HOUSE}/bin/i686-pc-linux-gnu-g77:${QTDIR}/bin:${PATH}; export QTDIR HEN_HOUSE EGS_HOME PATH MANPATH LD_LIBRARY_PATH EGS_CONFIG; into /etc/bash.bashrc before installation]
Addition: QT3.3.3 installation
  • Modify configure and find freetype and switch it off;
  • Add qt.conf under /etc/ld.so.conf.d with contents “/usr/local/qt/lib“;
  • Use ldconfig to reload;
After installation of EGSnrc and BEAMnrc, run script /usr/local/EGSnrc/scripts/finalize_egs_foruser and /usr/local/EGSnrc/scripts/finalize_beam_foruser
and add
EGS_HOME=/home/userhome/egsnrc/
EGS_CONFIG=/usr/local/EGSnrc/specs/i686-pc-linux-gnu-g77.conf
export EGS_HOME EGS_CONFIG

export OMEGA_HOME=/usr/local/EGSnrc/omega
. /usr/local/EGSnrc/scripts/egsnrc_bashrc_additions
. /usr/local/EGSnrc/scripts/beamnrc_bashrc_additions
into ~/.bashrc

Now installation is finished.

Thursday, 31 May 2007

NFS quick guide

NFS - Network File System

Get NFS installed via Synaptic Package Manager on 2 PCs, sourcePC and destPC.

/nfsdir is created on both PCs and /nfsdir contains files on sourcePC which need to be shared.

Edit /etc/exports file on sourcePC:

# two machines which share files under /nfsdir

/nfsdir sourcePC(rw) destPC(rw)

sourcePC is the PC which runs NFS server and shared files are stored under /nfsdir.

For security, add two files under /etc, hosts.deny and hosts.allow:

#hosts.deny

portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL

#hosts.allow

service: sourcePC , destPC

#sourcePC 192.168.10.2; destPC 192.168.10.3
portmap: 192.168.10.2 , 192.168.10.3
lockd: 192.168.10.2 , 192.168.10.3
rquotad: 192.168.10.2 , 192.168.10.3
mountd: 192.168.10.2 , 192.168.10.3
statd: 192.168.10.2 , 192.168.10.3

Start NFS server by /etc/init.d/nfs-kernel-server start

Check the status of NFS, rpcinfo -p.

Go to destPC. To view the contents of /nfsdir on sourcePC, mount remote directory first.

sudo mount sourcePC:/nfsdir /nfsdir

Now the contents of /nfsdir on sourcePC could be available on destPC.

Here is a link about NFS.

Wednesday, 30 May 2007

NoMachine NX and FreeNX

NXServer and NXClient are very good software to log into Linux system remotely. You could download the free edition from NoMachine. The free edition limits the number of users, so only 2 users can use the NX.

There is another option to use NX, which is FreeNX. How to install FreeNX could be found at Ubuntu help. FreeNX is an open source software and has no limitation on number of users.

FreeNX has the problem of colour missing. This could be solved by add a symbolic link.

ln -s /etc/X11/rgb.txt /usr/X11R6/lib/X11/rgb.txt

Because nxagent is looking for rgb.txt in /usr/X11R6/lib/X11, which does not exist.

LAMP under Ubuntu

Installation is really easy. Just use Synapitc Package Manager to choose the packages you need, like Apache2, php5, MySQL server/client, etc. If you like to add more features for your LAMP, just add more packages.

For seucrity purpose, it is necessary to add root password for MySQL. (Initially the root password is blank. When it asks password, just press the return key and it log into the MySQL directly.)

Log into mysql as root:

fish@pool:~$mysql -u root -p
Enter password:

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>set password for 'root'@'localhost'=password('newpassword');
mysql>flush priviledges;

If root needs log into the MySQL from other machine, add a line,
mysql>set password for 'root'@'hostname'=password('newpassword');

If root needs log into the MySQL from any remote host, add a line,
mysql>set password for 'root'@'%'=password('newpassword');

END of MySQL root setting.

After Apache2 installation, the default Apache2 directory is
/var/www/apache2-default
You could save your HTML, php documents under this directory and view from other machine. If you like to have it from other directory, some changes need to be done on file
/etc/apache2/sites-available/default
OR generate a new file
/etc/apache2/sites-available/newsite

The contents of the file should be,

##############################
NameVirtualHost *
<VirtualHost *>

    ServerAdmin webmaster@localhost
    DocumentRoot /path/dirname/
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory /path/dirname/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        allow from all
        # This directive allows us to have apache2's default start page
        # in /apache2-default/, but still have / go to the right place
        #RedirectMatch ^/$ /apache2-default/
    </Directory>

    ScriptAlias /cgi-bin/ /path/dirname/cgi-bin/
    <Directory "/path/dirname/cgi-bin">
        AllowOverride None
        Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog /var/log/apache2/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/apache2/access.log combined
    ServerSignature On

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>

#################################################

To make the new site work, a symbolic link needs to be created under
/etc/apache2/sites-enabled
And you can remove the default-000 under this directory and then restart Apache,
sudo apache2ctl restart

To test php, a short php file could be saved under /path/dirname. (test.php)


Use browser to view the file. (http://localhost/test.php)

Tuesday, 29 May 2007

Ubuntu Installation

There is really no much to talk about. Download ISO from www.ubuntu.com and burn the image onto a CD.

Reboot the computer and then set "boot from CD" in your computer's BIOS, and insert the Ubuntu CD into the CD-ROM.

Click installation icon and keep on click 'next', 'next', 'next' ......

It is done!

Monday, 28 May 2007

Red hot Rainbow Trout (Szechuan)

Prepare:

Whole Rainbow trout with head and tail, cleaned and scaled
1 tablespoons white wine
1 cloves garlic, coarsely chopped
3 teaspoons sugar
3 teaspoons salt
5 tablespoons vegetable oil
1 tablespoons soy sauce
2 teaspoons red hot chili sauce

Cooking:

Heat the oil in a wok or saucepan, and when it is hot (light smoke comes out) put garlic into the wok. (Smell so good. If you do not like, you can use spring onion.)

Once the garlic turns into golden, put the fish into the wok. Turn it gently to make sure both sides cooked.

When the skin of fish starts peeling off, add wine, soy sauce, sugar, salt and red hot chili sauce. Finally add 3 tablespoons cold water and put the cover on the wok, and using medium fire to cook it for 10 minutes. DONE and EAT.

(If you do not have the chili sauce, it is so easy to make it. Buy 2 or 3 small and red chili from Tesco. YES, the hottest one if you want to have real Szechuan dish. Chop it coarsely and keep all the seeds. Put all chopped chili into the hot oil in the wok or pan. Cook 2 minutes and you could have the sauce with red oil. NOTE, it is really spicy.)

Sunday, 27 May 2007

My old Skoda

I just said good-bye to my old and reliable friend Skoda Felicia yesterday and had a 2004 Citroen Xsara. Unfortunately I just own it for one day and it stops working.

Called a pal from AA and he told me Skoda is really a good and reliable car. I told him I was happy with Skoda and the reason I changed it is that it does not have air-conditioning. He told me only two months in a year maybe I need to use air-conditioning. Now I start to regret to let my Skoda go.

Love Ubuntu

I started to use Linux from 2001. I was using Redhat 6.0, then I tried Redhat 7.2, Redhat 9.0, Fedora 1, Fedora 2, Fedora 3. Every time I was trying to install some software, it took me ages to find the dependant packages from the Internet.

From 2005, one of my colleagues told me about Ubuntu. I found it is really easy to use and manage. Software installation becomes more convenient. Using APT, you can install the software you need and it looks for dependant packages automatically. If you have not tried, I can tell you it is worth to have a go.

Using Linux

Why use Linux? Is Microsoft not good?

To be honest, Microsoft provides good and quality products but they are not cheap and unfortunately due to the long history of its operating system most viruses are developed for making Microsoft system crash.

If you are going to have a system with Microsoft products, you need to buy Microsoft Windows, Microsoft Office, and some anti-virus software. How much does it cost? I am sure it could be more expensive than the computer you've built.


Why not try Linux? It is free. It is completely free. You can get support from all Linux users. You can have OpenOffice which has similar functions as MS-Office. You can have everything free under Linux.