Skip to main content
improved code
Source Link
kzidane
  • 17.7k
  • 3
  • 28
  • 100

Update 0: here's my code after modifications

complete program

/**

  • copy.c
  • Computer Science 50
  • Problem Set 5
  • Copies a BMP piece by piece, just because. */

#include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <string.h> #include <ctype.h>//for isdigit

 

#include "bmp.h"Update 1:

int main(int argc, char* argv[]) { // ensure proper usage if (argc != 4) { printf("Usage:I used fflush(), but it doesn't work either./resize n infile outfile\n"); return 1; } Here's my program

/**
* copy.c
*
* Computer Science 50
* Problem Set 5
*
* Copies a BMP piece by piece, just because.
*/checking 
 if n is
#include integer<stdio.h>
int#include i=0;<stdlib.h>
string#include in=argv[1];<cs50.h>
while#include <string.h>
#include <ctype.h>//for isdigit

#include "bmp.h"

int main(in[i]!='\0'int argc, char* argv[])
{
    // ensure proper usage
    if( isdigit(in[i]argc != 4)
    {
        printf("Usage: ./resize n infile outfile\n");
    i++;    return 1;
    }
    
    else//checking if n is integer
    int i=0;
    string in=argv[1];
    while(in[i]!='\0')
    {
        if( isdigit(in[i]) )
        i++;
        
        else
        {
            printf("n, the resize factor, must be an integer.\n");
            return 5;
        }
    }
}

int n=atoi(in);
if(n<1 || n>100)
{
    printf("n, the resize factor, must be a positive integer less than 100.\n");
    return 6;
}


// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)

{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

// outfile's BITMAPFILEHEADER
BITMAPFILEHEADER bf2=bf;

// outfile's BITMAPINFOHEADER
BITMAPINFOHEADER bi2=bi;    
    
//multiplying width by n factor
bi2.biWidth =int n*n=atoi(bi.biWidthin);
//multiplying height by n factor
bi2.biHeightif(n<1 =|| n*(bi.biHeightn>100);

// determine padding for scanlines in outfile{
int padding =  (4 - (bi2.biWidth * sizeofprintf(RGBTRIPLE))"n, %the 4)resize %factor, 4;

//must determinebe paddinga forpositive scanlinesinteger inless infilethan 100.\n");
int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE))return %6;
 4) % 4;
 }
    
//size of the image
bi2.biSizeImage = (bi2.biWidth + padding) 
 * (abs(bi2.biHeight)) * 3;// positiveremember bi2.biHeightfilenames
 for calculation of bi2.biSizeImagechar* infile 
 = argv[2];
//final size of bmp 
 char* bf2.bfSizeoutfile = bi2.biSizeImage + 54;argv[3];

    // writeopen outfile'sinput BITMAPFILEHEADERfile 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

fwrite    // open output file
    FILE* outptr = fopen(&bf2outfile, sizeof"w");
    if (BITMAPFILEHEADERoutptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, 1"Could not create %s.\n", outptroutfile);
        return 3;
    }

    // writeread outfile'sinfile's BITMAPINFOHEADERBITMAPFILEHEADER
    
 BITMAPFILEHEADER bf;
fwrite    fread(&bi2&bf, sizeof(BITMAPINFOHEADERBITMAPFILEHEADER), 1, outptrinptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// iterate over infile's scanlines
fpos_t pos;
for (int i =// 0,ensure biHeightinfile =is abs(bi.biHeightlikely); ia <24-bit biHeight;uncompressed i++)BMP 4.0
{   
  if (bf.bfType != //0x4d42 iterate|| overbf.bfOffBits pixels!= in54 scanline
|| bi.biSize != 40 fgetpos|| (outptr,&pos);
    for (int j = 0;bi.biBitCount j!= <24 || bi.biWidth;biCompression j++!= 0)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeoffclose(RGBTRIPLE), 1, inptroutptr);
        
        // write RGB triple to outfile n times horizontally
        for fclose(int k = 0 ; k < n; k++inptr)
        {       ;
            fwritefprintf(&triplestderr, sizeof(RGBTRIPLE),"Unsupported 1,file outptrformat.\n");             
        }return 4;
    }
    
    
    // outfile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf2=bf;
    
    // skipoutfile's overBITMAPINFOHEADER
 padding in infile, ifBITMAPINFOHEADER any
bi2=bi;    fseek(inptr, 
 padding_in, SEEK_CUR);//padding_in is padding in inptr
  
    // thenmultiplying addwidth paddingby ton outfilefactor
    for (int lbi2.biWidth = 0;n*(bi.biWidth);
 l < padding; l++)//padding is padding in outptr
multiplying height by n {factor
      bi2.biHeight = fputcn*(0x00, outptrbi.biHeight);
    }        
    
    //flushing thedetermine bufferpadding tofor outptrscanlines in outfile
    fflushint padding =  (outptr4 - (bi2.biWidth * sizeof(RGBTRIPLE);) % 4) % 4;
    
    // resizedetermine verticallypadding for scanlines in infile
    int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    
    //move pointer to start of 
 scanline   //size of outptrthe image
    fsetposbi2.biSizeImage = (bi2.biWidth outptr,+ &pospadding) * (abs(bi2.biHeight);) * 3;// positive bi2.biHeight for calculation of bi2.biSizeImage  
    
    //anfinal arraysize of RGBTRIPLE to store onebmp scanline
    RGBTRIPLE triplex[bi2bf2.biWidth]; 
                
    //reading the already written first line from outptr    
    for (int mbfSize = 0 ; m < bi2.biWidthbiSizeImage ;+ m++)54;
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1// ,write outptr);outfile's 
 BITMAPFILEHEADER    }
    
    fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);

    //skip paddingwrite outfile's BITMAPINFOHEADER    
    fseek 
    fwrite(outptr&bi2, paddingsizeof(BITMAPINFOHEADER), SEEK_CUR1, outptr);
    
 
    //writing theiterate valuesover ininfile's arrayscanlines
 to outptr n timesfpos_t pos;
    for (int mni = 0, biHeight = abs(bi.biHeight); mni < n ;biHeight; mn++i++)
    {   
        //writing valuesiterate fromover thepixels arrayin scanline
        fgetpos (outptr,&pos);
        for (int oj = 0 ;0; oj < bi2bi.biWidth ;biWidth; o++j++)
        {
            fwrite// temporary storage
            RGBTRIPLE triple;            
            
            // read RGB triple from infile
            fread(&triplex[o]&triple, sizeof(RGBTRIPLE), 1, inptr);
            
            // write RGB triple to outfile n times horizontally
            for (int k = 0 ; k < n; k++)
            {       
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);             
            }
        }
        
        
        
        //adding skip over padding toin outptr'sinfile, scanlineif any
        fseek(inptr, padding_in, SEEK_CUR);//padding_in is padding in inptr

        // then add padding to outfile
        for (int pl = 0; pl < padding; p++l++)//padding is padding in outptr
        {
            fputc(0x00, outptr);
        }        
        
        //flushing the buffer to outptr
        fflush(outptr);
        
        // resize vertically  
        
        //move pointer to start of scanline of outptr
        fsetpos( outptr, &pos );
        
        //an array of RGBTRIPLE to store one scanline
        RGBTRIPLE triplex[bi2.biWidth]; 
                    
        //reading the already written first line from outptr    
        for (int m = 0 ; m < bi2.biWidth ; m++)
        {             
            fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
        }
        
        //skip padding
        fseek(outptr, padding, SEEK_CUR);
        
        //writing the values in array to outptr n times
        for (int mn = 0 ; mn < n ; mn++)
        {
            //writing values from the array
            for (int o = 0 ; o < bi2.biWidth ; o++)
            {
                fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
            }
            //adding padding to outptr's scanline
            for (int p = 0; p < padding; p++)
            {
                fputc(0x00, outptr);
            }   
        }               
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

}

Update: here's my code after modifications

complete program

/**

  • copy.c
  • Computer Science 50
  • Problem Set 5
  • Copies a BMP piece by piece, just because. */

#include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <string.h> #include <ctype.h>//for isdigit

#include "bmp.h"

int main(int argc, char* argv[]) { // ensure proper usage if (argc != 4) { printf("Usage: ./resize n infile outfile\n"); return 1; }

//checking if n is integer
int i=0;
string in=argv[1];
while(in[i]!='\0')
{
    if( isdigit(in[i]) )
    i++;
    
    else
    {
        printf("n, the resize factor, must be an integer.\n");
        return 5;
    }
}

int n=atoi(in);
if(n<1 || n>100)
{
    printf("n, the resize factor, must be a positive integer less than 100.\n");
    return 6;
}


// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)

{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

// outfile's BITMAPFILEHEADER
BITMAPFILEHEADER bf2=bf;

// outfile's BITMAPINFOHEADER
BITMAPINFOHEADER bi2=bi;    
    
//multiplying width by n factor
bi2.biWidth = n*(bi.biWidth);
//multiplying height by n factor
bi2.biHeight = n*(bi.biHeight);

// determine padding for scanlines in outfile
int padding =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine padding for scanlines in infile
int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    
//size of the image
bi2.biSizeImage = (bi2.biWidth + padding) * (abs(bi2.biHeight)) * 3;// positive bi2.biHeight for calculation of bi2.biSizeImage  
 
//final size of bmp 
  bf2.bfSize = bi2.biSizeImage + 54;

// write outfile's BITMAPFILEHEADER    

fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER    
  
fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);


// iterate over infile's scanlines
fpos_t pos;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{   
     // iterate over pixels in scanline
    fgetpos (outptr,&pos);
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);             
        }
    }
    
    
    
    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);//padding_in is padding in inptr

    // then add padding to outfile
    for (int l = 0; l < padding; l++)//padding is padding in outptr
    {
        fputc(0x00, outptr);
    }        
    
    //flushing the buffer to outptr
    fflush(outptr);
    
    // resize vertically  
    
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
                
    //reading the already written first line from outptr    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
     }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    
    //writing the values in array to outptr n times
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing values from the array
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        //adding padding to outptr's scanline
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

Update 0: here's my code after modifications

 

Update 1:

I used fflush(), but it doesn't work either. Here's my program

/**
* copy.c
*
* Computer Science 50
* Problem Set 5
*
* Copies a BMP piece by piece, just because.
*/ 
   
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>//for isdigit

#include "bmp.h"

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./resize n infile outfile\n");
        return 1;
    }
    
    //checking if n is integer
    int i=0;
    string in=argv[1];
    while(in[i]!='\0')
    {
        if( isdigit(in[i]) )
        i++;
        
        else
        {
            printf("n, the resize factor, must be an integer.\n");
            return 5;
        }
    }
    
    int n=atoi(in);
    if(n<1 || n>100)
    {
        printf("n, the resize factor, must be a positive integer less than 100.\n");
        return 6;
    }
    
     
    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];

    // open input file 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE* outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }
    
    // outfile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf2=bf;
    
    // outfile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi2=bi;     
        
    //multiplying width by n factor
    bi2.biWidth = n*(bi.biWidth);
    //multiplying height by n factor
    bi2.biHeight = n*(bi.biHeight);
    
    // determine padding for scanlines in outfile
    int padding =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    
    // determine padding for scanlines in infile
    int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    
         
    //size of the image
    bi2.biSizeImage = (bi2.biWidth + padding) * (abs(bi2.biHeight)) * 3;// positive bi2.biHeight for calculation of bi2.biSizeImage  
    
    //final size of bmp 
     bf2.bfSize = bi2.biSizeImage + 54;

    // write outfile's BITMAPFILEHEADER    
    
    fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER    
     
    fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
    
 
    // iterate over infile's scanlines
    fpos_t pos;
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {   
        // iterate over pixels in scanline
        fgetpos (outptr,&pos);
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;            
            
            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
            
            // write RGB triple to outfile n times horizontally
            for (int k = 0 ; k < n; k++)
            {       
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);             
            }
        }
        
        
        
        // skip over padding in infile, if any
        fseek(inptr, padding_in, SEEK_CUR);//padding_in is padding in inptr

        // then add padding to outfile
        for (int l = 0; l < padding; l++)//padding is padding in outptr
        {
            fputc(0x00, outptr);
        }        
        
        //flushing the buffer to outptr
        fflush(outptr);
        
        // resize vertically  
        
        //move pointer to start of scanline of outptr
        fsetpos( outptr, &pos );
        
        //an array of RGBTRIPLE to store one scanline
        RGBTRIPLE triplex[bi2.biWidth]; 
                    
        //reading the already written first line from outptr    
        for (int m = 0 ; m < bi2.biWidth ; m++)
        {             
            fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
        }
        
        //skip padding
        fseek(outptr, padding, SEEK_CUR);
        
        //writing the values in array to outptr n times
        for (int mn = 0 ; mn < n ; mn++)
        {
            //writing values from the array
            for (int o = 0 ; o < bi2.biWidth ; o++)
            {
                fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
            }
            //adding padding to outptr's scanline
            for (int p = 0; p < padding; p++)
            {
                fputc(0x00, outptr);
            }   
        }               
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
added 5350 characters in body
Source Link
sid
  • 15
  • 5

complete program

/**

  • copy.c
  • Computer Science 50
  • Problem Set 5
  • Copies a BMP piece by piece, just because. */

#include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <string.h> #include <ctype.h>//for isdigit

#include "bmp.h"

int main(int argc, char* argv[]) { // ensure proper usage if (argc != 4) { printf("Usage: ./resize n infile outfile\n"); return 1; }

//checking if n is integer
int i=0;
string in=argv[1];
while(in[i]!='\0')
{
    if( isdigit(in[i]) )
    i++;
    
    else
    {
        printf("n, the resize factor, must be an integer.\n");
        return 5;
    }
}

int n=atoi(in);
if(n<1 || n>100)
{
    printf("n, the resize factor, must be a positive integer less than 100.\n");
    return 6;
}


// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)

{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

// outfile's BITMAPFILEHEADER
BITMAPFILEHEADER bf2=bf;

// outfile's BITMAPINFOHEADER
BITMAPINFOHEADER bi2=bi;    
    
//multiplying width by n factor
bi2.biWidth = n*(bi.biWidth);
//multiplying height by n factor
bi2.biHeight = n*(bi.biHeight);

// determine padding for scanlines in outfile
int padding =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine padding for scanlines in infile
int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    
//size of the image
bi2.biSizeImage = (bi2.biWidth + padding) * (abs(bi2.biHeight)) * 3;// positive bi2.biHeight for calculation of bi2.biSizeImage  

//final size of bmp 
 bf2.bfSize = bi2.biSizeImage + 54;

// write outfile's BITMAPFILEHEADER    

fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER    
 
fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);


// iterate over infile's scanlines
fpos_t pos;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{   
    // iterate over pixels in scanline
    fgetpos (outptr,&pos);
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);             
        }
    }
    
    
    
    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);//padding_in is padding in inptr

    // then add padding to outfile
    for (int l = 0; l < padding; l++)//padding is padding in outptr
    {
        fputc(0x00, outptr);
    }        
    
    //flushing the buffer to outptr
    fflush(outptr);
    
    // resize vertically  
    
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
                
    //reading the already written first line from outptr    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
    }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    
    //writing the values in array to outptr n times
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing values from the array
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        //adding padding to outptr's scanline
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

complete program

/**

  • copy.c
  • Computer Science 50
  • Problem Set 5
  • Copies a BMP piece by piece, just because. */

#include <stdio.h> #include <stdlib.h> #include <cs50.h> #include <string.h> #include <ctype.h>//for isdigit

#include "bmp.h"

int main(int argc, char* argv[]) { // ensure proper usage if (argc != 4) { printf("Usage: ./resize n infile outfile\n"); return 1; }

//checking if n is integer
int i=0;
string in=argv[1];
while(in[i]!='\0')
{
    if( isdigit(in[i]) )
    i++;
    
    else
    {
        printf("n, the resize factor, must be an integer.\n");
        return 5;
    }
}

int n=atoi(in);
if(n<1 || n>100)
{
    printf("n, the resize factor, must be a positive integer less than 100.\n");
    return 6;
}


// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)

{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

// outfile's BITMAPFILEHEADER
BITMAPFILEHEADER bf2=bf;

// outfile's BITMAPINFOHEADER
BITMAPINFOHEADER bi2=bi;    
    
//multiplying width by n factor
bi2.biWidth = n*(bi.biWidth);
//multiplying height by n factor
bi2.biHeight = n*(bi.biHeight);

// determine padding for scanlines in outfile
int padding =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine padding for scanlines in infile
int padding_in =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    
//size of the image
bi2.biSizeImage = (bi2.biWidth + padding) * (abs(bi2.biHeight)) * 3;// positive bi2.biHeight for calculation of bi2.biSizeImage  

//final size of bmp 
 bf2.bfSize = bi2.biSizeImage + 54;

// write outfile's BITMAPFILEHEADER    

fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER    
 
fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);


// iterate over infile's scanlines
fpos_t pos;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{   
    // iterate over pixels in scanline
    fgetpos (outptr,&pos);
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);             
        }
    }
    
    
    
    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);//padding_in is padding in inptr

    // then add padding to outfile
    for (int l = 0; l < padding; l++)//padding is padding in outptr
    {
        fputc(0x00, outptr);
    }        
    
    //flushing the buffer to outptr
    fflush(outptr);
    
    // resize vertically  
    
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
                
    //reading the already written first line from outptr    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
    }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    
    //writing the values in array to outptr n times
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing values from the array
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        //adding padding to outptr's scanline
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

added 40 characters in body; edited tags; edited title
Source Link
kzidane
  • 17.7k
  • 3
  • 28
  • 100

pset5 resize not stretching vertically How to Resize an Image Vertically?

I amI'm able to expandresize a given .bmp.bmp horizontally, but the code for vertical expansionresizing is not working. Here is my code for vertical expansion.

// resize vertically

//move pointer to start of scanline of outptr fseek(outptr, -3 * (bi2.biWidth + padding), SEEK_CUR);

// resize vertically

//move pointer to start fgetposof scanline of outptr
fseek(outptr,&pos  -3 * (bi2.biWidth + padding), SEEK_CUR);
    
fgetpos (outptr,&pos);
     
//an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triple[bi2.biWidth + padding]; 
    
    //reading the already written first line    
    for (int p = 0 ; p < bi2.biWidth + padding; p++)
    { 
        fread(&triple[p], sizeof(RGBTRIPLE), 1, outptr); 
    }
    fgetpos (outptr,&pos);           
    
    //writing the copied array to outptr
    for (int k = 0 ; k < n; k++)
    {             
        for (int p = 0 ; p < bi2.biWidth + padding; p++)
         
            fwrite(&triple[p], sizeof(RGBTRIPLE), 1, outptr);   
                    
    }     
  

This is writtenexecuted after reading the first scanline is copies correctly from input bmpof the original bmp. Used gdbI used gdb to findsee the values in triple[0]of triple's elements,triple[1].....but but I found that they're all those are garbage values. 

Also if iwhen I check the position of pointerthe file position indicator in outptroutptr using fgetpos (outptr,&pos)fgetpos(), itsI find it not changing.!

modied code

 

// iterate over infile's scanlines fpos_t pos; for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) {
// iterate over pixels in scanline fgetpos (outptr,&pos); for (int j = 0; j < bi.biWidth; j++) { // temporary storage RGBTRIPLE triple;Update: here's my code after modifications

// iterate over infile's scanlines
fpos_t pos;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{   
    // iterate over pixels in scanline
    fgetpos (outptr,&pos);
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  
                       
        }
    }

    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);

    // then add padding to outfile
    for (int l = 0; l < padding; l++)
    {
        fputc(0x00, outptr);
    }        
   
    // resize vertically  
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
    
        
    //reading the already written first line    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
    }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing the copied array to outptr
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}

pset5 resize not stretching vertically

I am able to expand a given .bmp horizontally but the code for vertical expansion is not working. Here is my code for vertical expansion.

// resize vertically

//move pointer to start of scanline of outptr fseek(outptr, -3 * (bi2.biWidth + padding), SEEK_CUR);

    fgetpos (outptr,&pos);
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triple[bi2.biWidth + padding]; 
    
    //reading the already written first line    
    for (int p = 0 ; p < bi2.biWidth + padding; p++)
    { 
        fread(&triple[p], sizeof(RGBTRIPLE), 1, outptr); 
    }
    fgetpos (outptr,&pos);           
    
    //writing the copied array to outptr
    for (int k = 0 ; k < n; k++)
    {             
        for (int p = 0 ; p < bi2.biWidth + padding; p++)
         
            fwrite(&triple[p], sizeof(RGBTRIPLE), 1, outptr);   
                    
    }      

This is written after the first scanline is copies correctly from input bmp. Used gdb to find the values in triple[0],triple[1].....but all those are garbage. Also if i check the position of pointer in outptr using fgetpos (outptr,&pos), its not changing.

modied code

// iterate over infile's scanlines fpos_t pos; for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) {
// iterate over pixels in scanline fgetpos (outptr,&pos); for (int j = 0; j < bi.biWidth; j++) { // temporary storage RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  
                       
        }
    }

    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);

    // then add padding to outfile
    for (int l = 0; l < padding; l++)
    {
        fputc(0x00, outptr);
    }        
   
    // resize vertically  
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
    
        
    //reading the already written first line    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
    }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing the copied array to outptr
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}

How to Resize an Image Vertically?

I'm able to resize a given .bmp horizontally, but the code for vertical resizing is not working. Here is my code for vertical expansion.

// resize vertically

//move pointer to start of scanline of outptr
fseek(outptr,  -3 * (bi2.biWidth + padding), SEEK_CUR);
    
fgetpos (outptr,&pos);
     
//an array of RGBTRIPLE to store one scanline
RGBTRIPLE triple[bi2.biWidth + padding]; 
    
//reading the already written first line    
for (int p = 0 ; p < bi2.biWidth + padding; p++)
{ 
    fread(&triple[p], sizeof(RGBTRIPLE), 1, outptr); 
}
fgetpos (outptr,&pos);           
    
//writing the copied array to outptr
for (int k = 0 ; k < n; k++)
{             
    for (int p = 0 ; p < bi2.biWidth + padding; p++)
         
        fwrite(&triple[p], sizeof(RGBTRIPLE), 1, outptr);   
                    
} 
  

This is executed after reading the first scanline of the original bmp. I used gdb to see the values of triple's elements, but I found that they're all garbage values. 

Also when I check the position of the file position indicator in outptr using fgetpos(), I find it not changing!

 

Update: here's my code after modifications

// iterate over infile's scanlines
fpos_t pos;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{   
    // iterate over pixels in scanline
    fgetpos (outptr,&pos);
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;            
        
        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        
        // write RGB triple to outfile n times horizontally
        for (int k = 0 ; k < n; k++)
        {       
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  
                       
        }
    }

    // skip over padding in infile, if any
    fseek(inptr, padding_in, SEEK_CUR);

    // then add padding to outfile
    for (int l = 0; l < padding; l++)
    {
        fputc(0x00, outptr);
    }        
   
    // resize vertically  
    //move pointer to start of scanline of outptr
    fsetpos( outptr, &pos );
    
    //an array of RGBTRIPLE to store one scanline
    RGBTRIPLE triplex[bi2.biWidth]; 
    
        
    //reading the already written first line    
    for (int m = 0 ; m < bi2.biWidth ; m++)
    {             
        fread(&triplex[m], sizeof(RGBTRIPLE), 1 , outptr); 
    }
    
    //skip padding
    fseek(outptr, padding, SEEK_CUR);
    for (int mn = 0 ; mn < n ; mn++)
    {
        //writing the copied array to outptr
        for (int o = 0 ; o < bi2.biWidth ; o++)
        {
            fwrite(&triplex[o], sizeof(RGBTRIPLE), 1 , outptr);   
        }
        for (int p = 0; p < padding; p++)
        {
            fputc(0x00, outptr);
        }   
    }               
}
added 1935 characters in body
Source Link
sid
  • 15
  • 5
Loading
Source Link
sid
  • 15
  • 5
Loading