function [im, nchannels] = pnm_read( name, from ) % % [im, nchannels] = PNM_READ(name, from) - read a pnm file % % name: pnm file name % from: designates image source "file" or "stream" % (optional - default is file) % % im: returned image % nchannels: number of channels in the image (1 = bw, 3 = color) % % Note: If the image being read pbm or pgm type, im contains a single % image of gray values, and nchannels = 1. If the image is color then % nchannels = 3 and the colors are interleave by columns, i.e., % % RGBRGBRGB ... RGB; % RGBRGBRGB ... RGB; % % To extract just the red portion of the image you can use, for % example, % % I = pnm_read( "file.ppm" ); % [nr,nc] = size(I); % Red = I(:,1:3:nc); % if ( nargin < 2 ) from = "file"; endif if ( strcmp(from, "file") ) [file, msg] = fopen( name, "r", "native" ); if ( file == -1 ) error( msg ); endif elseif ( strcmp(from, "stream") ) file = name; else error( "illegal value for second argument" ); endif ch1 = fgets( file, 1 ); if ( ch1 != 'P' ) error( "invalid magic number" ); endif ch2 = fgets( file, 1 ); if ( index("2356", ch2) == 0 ) error( "invalid magic number" ); endif nc = pnm_getint( file ); nr = pnm_getint( file ); if ( nr <= 0 || nc <= 0 ) error( "illegal image dimensions (must be positive)" ); endif max = pnm_getint( file ); if ( max < 0 ) error( "illegal max pixel value (must be non-negative)" ); endif switch ( ch2 ) case '2' # PGM ascii format im = zeros(nr, nc); for i = 1:nr for j = 1:nc im(i,j) = pnm_getint(file); endfor endfor nchannels = 1; case '3' # PNM ascii format nc = 3 * nc; im = zeros(nr, nc); for i = 1:nr for j = 1:nc im(i,j) = pnm_getint(file); endfor endfor nchannels = 3; case '5' # PGM raw format [im, n] = fread( file, [nc,nr], "uchar" ); im = im'; if n ~= (nr * nc) error( "no image data read" ); endif nchannels = 1; case '6' # PNM raw format nc = 3 * nc; [im, n] = fread( file, [nc,nr], "uchar" ); im = im'; if n ~= (nr * nc) error( "no image data read" ); endif nchannels = 3; otherwise error( "invalid magic number" ); endswitch if ( strcmp(from, "file") ) fclose(file); endif endfunction