#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2017
    Posts
    1
    Rep Power
    0

    improve a fanction


    hi im trying to make this function work faster.
    it takes an img in bmp and put it into a matrix.
    for big pictures it take some time...

    Code:
    pixels** ImgToMat(FILE* img, int w, int h, int offset)
    {
    	int i, j, padding;
    
    	pixels **pixel;
    
    	pixel = (pixels**)malloc(sizeof(pixels*)*h);
    	for (i = 0; i < h; i++)
    	{
    		pixel[i] = (pixels*)malloc(sizeof(pixels)*w);
    	}
    	for (i = 0; i < h; i++)
    	{
    		if (!pixel[i])
    			exit(1);
    	}
    	padding = 4 - (w * 3) % 4;
    		if (padding == 4)
    			padding = 0;
    	for (i = 0; i < h; i++)
    	{
    		for (j = 0; j < w; j++)
    		{
    			fseek(img, offset + ((i*w + j) * 3)+i*padding, SEEK_SET);
    			pixel[i][j].SLD = 0;
    			fread(&pixel[i][j].SLD, 1, 1, img);
    			pixel[i][j].point = 0;
    
    		}
    		for (j = w * 3; j % 4 != 0; j++)
    		{
    			fgetc(img);
    		}
    
    	}
    
    	return (pixel); 
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,478
    Rep Power
    1875
    Well a few things spring to mind.
    1. remove the fseek in the middle of the innermost loop. Especially since all it seems to do is seek to the point where it just read to anyway.
    2. merge all the malloc calls into larger blocks, then simply divide into sub-blocks with a loop.
    3. You might consider doing something with the .point member, which prevents you reading a row of pixels as a contiguous block.

    I got 6x improvement with points 1 and 2.

    Code:
    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<time.h>
    
    typedef struct {
      unsigned char SLD[3];
      int point;
    } pixels;
    
    pixels** ImgToMat(FILE* img, int w, int h, int offset)
    {
    	int i, j, padding;
    
    	pixels **pixel;
    
    	pixel = (pixels**)malloc(sizeof(pixels*)*h);
    	for (i = 0; i < h; i++)
    	{
    		pixel[i] = (pixels*)malloc(sizeof(pixels)*w);
    	}
    	for (i = 0; i < h; i++)
    	{
    		if (!pixel[i])
    			exit(1);
    	}
    	padding = 4 - (w * 3) % 4;
    		if (padding == 4)
    			padding = 0;
    	for (i = 0; i < h; i++)
    	{
    		for (j = 0; j < w; j++)
    		{
    			fseek(img, offset + ((i*w + j) * 3)+i*padding, SEEK_SET);
    			//pixel[i][j].SLD = 0;
    			fread(&pixel[i][j].SLD, 1, 1, img);
    			pixel[i][j].point = 0;
    
    		}
    		for (j = w * 3; j % 4 != 0; j++)
    		{
    			fgetc(img);
    		}
    
    	}
    
    	return (pixel);
    }
    
    pixels** ImgToMat2(FILE* img, int w, int h, int offset)
    {
    	int i, j, padding;
    
    	pixels **pixel;
    
    	pixel = malloc(sizeof(pixels*)*h);
            if ( !pixel ) exit(1);
            pixel[0] = malloc(h*w*sizeof(pixels));
            if ( !pixel[0] ) exit(1);
    	for (i = 1; i < h; i++)
    	{
    		pixel[i] = pixel[i-1] + w;
    	}
    	padding = 4 - (w * 3) % 4;
    		if (padding == 4)
    			padding = 0;
    	fseek(img, offset, SEEK_SET);
    	for (i = 0; i < h; i++)
    	{
    		for (j = 0; j < w; j++)
    		{
    			fread(&pixel[i][j].SLD, 1, 1, img);
    			pixel[i][j].point = 0;
    
    		}
    		for (j = w * 3; j % 4 != 0; j++)
    		{
    			fgetc(img);
    		}
    
    	}
    
    	return (pixel);
    }
    
    unsigned long delta( const struct timespec *old, const struct timespec *new ) {
      unsigned long usec = ( new->tv_nsec - old->tv_nsec ) / 1000;
      usec += ( new->tv_sec - old->tv_sec ) * 1000000;
      return usec;
    }
    
    int main()
    {
        struct timespec start,end;
        FILE *fp = fopen("Untitled.bmp","r");
        clock_gettime(CLOCK_MONOTONIC,&start);
        pixels **p1 = ImgToMat(fp,640,400,54);
        clock_gettime(CLOCK_MONOTONIC,&end);
        printf("Time 1 = %lu uSec, first byte=%x\n", delta(&start,&end), p1[0][0].SLD[0] );
        rewind(fp);
        clock_gettime(CLOCK_MONOTONIC,&start);
        pixels **p2 = ImgToMat2(fp,640,400,54);
        clock_gettime(CLOCK_MONOTONIC,&end);
        printf("Time 2 = %lu uSec, first byte=%x\n", delta(&start,&end), p2[0][0].SLD[0] );
        rewind(fp);
        clock_gettime(CLOCK_MONOTONIC,&start);
        pixels **p3 = ImgToMat2(fp,640,400,54);
        clock_gettime(CLOCK_MONOTONIC,&end);
        printf("Time 3 = %lu uSec, first byte=%x\n", delta(&start,&end), p3[0][0].SLD[0] );
        rewind(fp);
        clock_gettime(CLOCK_MONOTONIC,&start);
        pixels **p4 = ImgToMat(fp,640,400,54);
        clock_gettime(CLOCK_MONOTONIC,&end);
        printf("Time 4 = %lu uSec, first byte=%x\n", delta(&start,&end), p4[0][0].SLD[0] );
        rewind(fp);
        for ( int i = 0 ; i < 400 ; i++ ) {
          free(p1[i]);
          free(p4[i]);
        }
        free(p2[0]);
        free(p3[0]);
        free(p1);
        free(p2);
        free(p3);
        free(p4);
        fclose(fp);
        return 0;
    }
    
    
    $ ./a.out 
    Time 1 = 42921 uSec, first byte=42
    Time 2 = 7686 uSec, first byte=42
    Time 3 = 7485 uSec, first byte=42
    Time 4 = 34040 uSec, first byte=42
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo