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
