Lesson 4 : PNM Files | Lesson 6 : MPEG Basic | Contents
In this lesson, you will learn more about ByteImages, including masking and casting. A mask is representing by a BitImage. We first read in the file lenna.ppm and store them in three ByteImages r, g and b. If you don't understand the following code, you should go back to lesson 4 and read it again.
cd C:/Dali/doc/tutorial package require DvmBasic package require DvmByteGeom package require DvmPnm set size [file size lenna.ppm] set bs [bitstream_new $size] set bp [bitparser_new] bitparser_wrap $bp $bs set file [open lenna.ppm r] fconfigure $file -translation binary -buffersize 65536 bitstream_channel_read $bs $file 0 close $file set hdr [pnm_hdr_new] set len [pnm_hdr_parse $bp $hdr] if {[pnm_hdr_get_type $hdr] != "ppm-bin"} { puts "input file is not a binary ppm." } set w [pnm_hdr_get_width $hdr] set h [pnm_hdr_get_height $hdr] set r [byte_new $w $h] set g [byte_new $w $h] set b [byte_new $w $h] ppm_parse $bp $r $g $b
This time we are going to process a gray scale version of lenna. So we are going to convert the images into gray scale.
package require DvmColor set lenna [byte_new $w $h] rgb_to_y $r $g $b $lenna
Next we are going to read in a second PGM file, logo.pgm, which is the logo of DalÄ—.
set size [file size logo.pgm] set logobs [bitstream_new $size] set logobp [bitparser_new] bitparser_wrap $logobp $logobs set file [open logo.pgm r] fconfigure $file -translation binary -buffersize 65536 bitstream_channel_read $logobs $file 0 close $file set hdr [pnm_hdr_new] set len [pnm_hdr_parse $logobp $hdr] if {[pnm_hdr_get_type $hdr] != "pgm-bin"} { puts "input file is not a binary pgm." } set w [pnm_hdr_get_width $hdr] set h [pnm_hdr_get_height $hdr]
The above code read the logo image into the BitStream logobs. Now we should store the image into a ByteImage. DalÄ— provide the casting mecahnism to avoid memory copying.
set logo [bitstream_cast_to_byte $logobs $hdr $len]
What this do is that we treat the data in the BitStream, starting from location len as a PGM image according to the properties specified in hdr. logo and logobs shared the same memory and therefore we cannot free logobs just yet. logo should look like this :
Now what we want to do is to overlap the clock in logo over the face of lenna. We want pixels which are almost white in logo to be replaced by pixels from lenna. We can do so by using a mask.
set mask [bit_new $w $h] bit_make_from_key $logo 245 255 $mask
This will create a mask with the same size as logo, with bit set to 1 at location where the pixel in logo has value range from 245 to 255. mask should look like this :
Now we simply copy the pixels from lenna into logo using mask to determine which pixel to copy.
byte_copy_with_mask $lenna $mask $logo
The result looks like this (uglier than I thought) :
Now we can output the result to a PGM file, starting with the header.
set file [open masked.pgm w] fconfigure $file -translation binary -buffersize 65536 bitparser_seek $bp 0 pnm_hdr_set_type $hdr "pgm-bin" pnm_hdr_encode $hdr $bp bitstream_channel_write $bs $file 0
Writing the body is slightly tricky. Remember that logo share the same memory as logobs. So it is not neccessary that we copy or encode logo into another BitStream. We can output logobs to file directly. But it is WRONG to call :
bitstream_channel_write $logobs $file $len # WRONG
Recall what bitstream_channel_write do : it will write all bytes starting from len to the end of valid data in it to the output channel. But since we did not call write directly into logobs (we cast it to a ByteImage and modify the ByteImage), there are no valid data in logobs. So the correct way to write logobs is to explicitly specify how many bytes to write :
bitstream_channel_write_segment $logobs $file $len [expr [byte_get_width $logo]*[byte_get_height $logo]] close $file
That should do it. Oh, remember to clean up by deallocating everything :
bitstream_free $bs bitparser_free $bp byte_free $r byte_free $g byte_free $b byte_free $lenna bitstream_free $logobs bitparser_free $logobp pnm_hdr_free $hdr byte_free $logo bit_free $mask
Source code for this lesson : l5.tcl
Lesson 4 : PNM Files | Lesson 6 : MPEG Basic | Contents
Last Updated : 06/03/2025 10:50:29