info-sather
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New Package Maintainer


From: Sather User
Subject: Re: New Package Maintainer
Date: Fri, 2 Sep 2011 23:25:45 +0930 (CST)

On Sat, 18 Dec 2010, address@hidden wrote:


> There is a bug in the browser. ("May crash later:") I think I'll
> start by looking at that (3-4 weeks?)...  I have a lot to learn, and
> I think finding and fixing a bug is the best way to "get one's hands
> dirty".

Hi, Sadi.  Wondering how you went with the browser.

Here is a PGM class.  Unsophisticated, like me, no doubt, but may be
useful to someone.  There are different creates for reading/validating
and writing a PGM file.  Maybe not ready for release.  Use at your own
risk.

class PGM is
   shared errno:INT;
   shared strerr:STR;

   attr tag:FMAP{STR,STR};
   attr comment:FLIST{FSTR};
   attr f:FILE;
   attr height, width, maxval, prod, imsize, start_loc, end_loc:INT;
   attr deep:BOOL;
   attr writer:BOOL;

   oferr(n:INT) is
      strerr:="could not open file";
      errno := n
   end;

   ferr(n:INT) is
      -- format error
      strerr:="bad file format";
      errno := n;
   end;

   create(filename:STR, old:SAME, deep:BOOL):SAME is
      -- Writer create.  See comments below.
      return create(filename, old, deep, void, void)
   end;

   create(filename:STR, old:SAME, deep:BOOL, newwidth, newheight:INT):SAME is
      -- Create a PGM to write from a PGM that was read.
      -- Assumes we are modifying some PGM or more than one, whose
      -- headers must be copied.  The writing uses self.f which is
      -- here advanced to the point following the header so
      -- the first pixel can be written.  Can't use old.deep because we
      -- need the option of converting 16-bit input to 8-bit output.
      res:SAME:=new;
      res.writer:=true;
      if void(filename) then
         res.f:=FILE::stdout
      else
         res.f:=FILE::open_for_write(filename);
         if res.f.error then oferr(2); return void end;
      end;
      res.f+"P5\n";

      -- If there were multiple input PGMs, e.g. for noise reduction,
      -- the header data, comments, specific to all but the last are lost.
      -- The comments, width and height of the last input PGM only are used.

      if ~void(old.comment) and old.comment.size > 0 then
         loop
            res.f+("#"+old.comment.elt!+"\n")
         end
      end;
      -- Not old.deep: the parameter deep.
      if deep then res.maxval := 65535 else res.maxval := 255 end;
      if void(newwidth) then res.width:=old.width else res.width:=newwidth end;
      if void(newheight) then
         res.height:=old.height
      else
         res.height:=newheight
      end;
      res.f+res.width.str+" "+res.height.str+"\n"+res.maxval.str+"\n";
      return res
   end;

   create(filename, directory:STR):SAME is
      -- A reader create which does open_for_read of an existing PGM file,
      -- and some other things.
      res::=new;
      if ~void(directory) then
         filename := directory + "/" + filename
      end;
      f::=FILE::open_for_read(filename);
      if f.error then oferr(2); return void end;
      res.f:=f;
      -----------------------------------------------------------
      c:CHAR;
      c:=res.material_next;
      if c /= 'P' then ferr(29); return void end;
      c:=res.f.get_char;
      if c /= '5' then ferr(3);  return void end;
      c:=res.material_next;
      if ~c.is_digit then ferr(5); return void end;
      Width ::= res.my_sense(c).t2;
      c:=res.material_next;
      if ~c.is_digit then ferr(6);  return void end;
      Height::=res.my_sense(c).t2;
      c:=res.material_next;
      if ~c.is_digit then ferr(7); return void end;
      Maxval_tup::=res.my_sense(c);
      Maxval::=Maxval_tup.t2;
      if Maxval_tup.t1.is_space.not then ferr(8);  return void end;
      res.start_loc:=res.f.current_loc;
      res.f.seek_from_end(0);
      res.end_loc:=res.f.current_loc;
      res.f.seek_from_front(res.start_loc);
      res.width:=#INT(Width);
      res.height:=#INT(Height);
      res.maxval:=#INT(Maxval);
      res.deep:=res.maxval>255;
      prod::=res.width*res.height;
      if res.deep then prod:=prod+prod end;
      res.prod := prod;
      imsize::=res.end_loc-res.start_loc;
      res.imsize := imsize;
      if MAIN::dbg_header then
         #ERR+"width="+Width+"\theight="+Height+"\tmaxval="+Maxval+"\n";
         #ERR+"start_loc="+res.start_loc+"\tend_loc="+res.end_loc+"\n";
         #ERR+"prod="+res.prod+"\timsize="+res.imsize;
         #ERR+"\tprod-imsize="+(res.prod-res.imsize)+"\n";
         ferr(0);
         return void
      end;
      -- Final header test: more than 1 char between Maxval and 1st pixel?
      if prod/=imsize then ferr(9);  return void end;
      -- These must set shared errno:INT and return void
      return res
   end;

   my_sense(n:CHAR):TUP{CHAR,STR} is
      -- Place the arg in a new string buffer.
      -- Make it FSTR.
      -- Read the next character.
      -- If it is whitespace return the string buffer.
      -- If it is '#'step over it (saving comment) and return the
      -- string buffer.
      -- Otherwise append it to the string buffer and start again.
      c:CHAR;
      sb:FSTR:=#;
      sb:=sb.push(n);
      loop
         c:=f.get_char;
         if c.is_space then return #(c,sb.str) end;
         if c='#' then comment_collect_skip; return #(c,sb.str) end;
         sb:=sb.push(c)
      end
   end;

   stepover:CHAR is
      -- If the next item is a whitespace character or comment
      -- step over it and return '\0' else step over it and return it
      c:CHAR;
      c:=f.get_char;
      if c.is_space then return '\0' end;
      if c='#' then comment_collect_skip; return '\0' end;
      return c
   end;

   material_next:CHAR is
      -- Look for the next character that is not whitespace (inc blank
      -- lines) and not a comment.  Return the character.
      c:CHAR;
      loop
         c:=stepover;
         while!(c='\0')
      end;
      return c
   end;

   comment_collect_skip
   -- A "#" was found.  Advance to end of line, putting everthing
   -- before \n into a new comment item.
   is
      s:FSTR;
      loop
         c::=f.get_char;
         until!(c='\n');
         s:=s.push(c)
      end;
      comment:=comment.push(s)
   end;

   plus(i:INT) is
      -- append a character to new file
      if ~writer then
         #ERR+"Not a writer.\n"
      else
         if deep then
            f+i.urshift(8).char;
            f+i.band(255).char
         else
            f+i.char
         end
      end
   end;

   plus(n:FLT) is
      plus(n.round.int)
   end;

   get_int:INT is
      if writer then
         #ERR+"Not a reader.\n";
         return 0
      end;
      if deep then
         return f.get_char.int.utimes(256).uplus(f.get_char.int)
      end;
      return f.get_char.int
   end;

   pixnum_read_hexstr:STR is
      s::=get_int.hex_str;
      w::=s.size-2;
      return s.tail(w)
   end;

   close is f.close end;

end;


-- 
Michael Talbot-Wilson



reply via email to

[Prev in Thread] Current Thread [Next in Thread]