Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрое чтение BMP файла, проблема с оптимизацией алгоритма 
:(
    Опции темы
Graf Zeppelin
Дата 28.3.2004, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 28.3.2004

Репутация: нет
Всего: 1



исходник:
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <graphics.h>

unsigned long readnb(int handle,int from,int n)
{
int j=0;
unsigned char c;
unsigned long s=0;
lseek(handle,from,SEEK_SET);
do
{
read(handle,&c,1);
s=s+c*pow(2,j*8);
j++;
}while(j<n);
return(s);
}

int main(void)
{
int handle,i,bppixel,ctype,x=0,y=0;
FILE *stream;
unsigned char ch,r,g,b;
unsigned long fsize,width,height,asize,aloc;
int graphdriver=DETECT;
int graphmode;
initgraph(&graphdriver,&graphmode,"C:\\TC\\BGI");

clrscr();
if ((handle=open("D:\\work\\programs\\docs\\bmp\\untitled.bmp",O_RDONLY | O_BINARY))==-1)
{
perror("Error");
}
stream=fdopen(handle,"r+");

fsize=readnb(handle,2,4);
printf("Size: %lu\n",fsize);

aloc=readnb(handle,10,4);
printf("Array location: %lu\n",aloc);

width=readnb(handle,18,4);
printf("Width: %lu\n",width);

height=readnb(handle,22,4);
printf("Height: %lu\n",height);

bppixel=readnb(handle,28,2);
printf("Bit per pixel: %u\n",bppixel);

ctype=readnb(handle,30,4);
printf("Compression type: %u\n",ctype);

asize=readnb(handle,34,4);
printf("Array size: %lu\n",asize);

getch();
lseek(handle,aloc,SEEK_SET);
cleardevice();
y=height;
do
{
read(handle,&r,1);
read(handle,&g,1);
read(handle,&b,1);

putpixel(x,y,((r+g+b)/51));
x++;
if (x==width)
{
x=0;
y--;
}
//getch();
}while(!eof(handle));
fclose(stream);
close(handle);
getch();
closegraph();
}
выводит исходный файл 800*600*24 со скоростью ~строка в секунду :(
как ускорить процесс?
PM MAIL   Вверх
Дрон
Дата 28.3.2004, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



По-моему, в любом случае у тебя всё упрётся в быстродействие putpixel.
Но кое-что можно улучшить:

Вне main:

Код
#define BUFFSIZE 16

struct Color{
unsigned char r,g,b;
};

Внутри main:

Код
Color Buffer[BUFFSIZE];

И дальше вместо твоего:
Код
read(handle,&r,1);
read(handle,&g,1);
read(handle,&b,1);

putpixel(x,y,((r+g+b)/51));
x++;

Пишешь:
Код
read(handle,buffer,3*BUFFSIZE);

unsigned char *r,*g,*b;
r = &buffer[0].r;
g = &buffer[0].g;
b = &buffer[0].b;
for(int i=0;i<BUFFSIZE;i++){
 putpixel(x,y,((*r + *g + *b)/51));
 r+=3;
 g+=3;
 b+=3;
 x++;
}

Будет работать, если ширина картинки в пикселях кратна BUFFSIZE.
А выигрыш по быстродействию получается за счёт уменьшения числа обращений к файлу. Однако у меня при BUFFSIZE > 16 рост скорости прекращается из-за тормознутого putpixel. Можно поискать способ выводить на экран сразу порцию пикселей, но я с BGI почти не программировал, поэтому не знаю как.


--------------------
Да. Именно так.
PM   Вверх
Graf Zeppelin
Дата 28.3.2004, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 28.3.2004

Репутация: нет
Всего: 1



Плиз, выложи код целиком а то у меня не получается скомпилить.
PM MAIL   Вверх
Graf Zeppelin
Дата 28.3.2004, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 28.3.2004

Репутация: нет
Всего: 1



Все спасибо я разобрался. Действительно существенно быстрее.
--------------------
Jah, help me!
PM MAIL   Вверх
Graf Zeppelin
Дата 28.3.2004, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 28.3.2004

Репутация: нет
Всего: 1



Цитата
Можно поискать способ выводить на экран сразу порцию пикселей, но я с BGI почти не программировал, поэтому не знаю как.

Можно сначала файл загнать в bitmap буфер а потом вставить putimage`ем но я тоже не знаю как это можно программно реализовать.
--------------------
Jah, help me!
PM MAIL   Вверх
cardinal
Дата 28.3.2004, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

Репутация: 2
Всего: 99



Код
do
{
   read(handle,buffer,3*BUFFSIZE);

   unsigned char *r,*g,*b;
   r = &buffer[0].r;
   g = &buffer[0].g;
   b = &buffer[0].b;
 
   for(int i=0;i<BUFFSIZE;i++)
   {
       putpixel(x,y,((*r + *g + *b)/51));
       r+=3;
       g+=3;
       b+=3;
       x++;

       if (x==width)
       {
            x=0;
            y--;
       }
   }
}while(!eof(handle));

Вопрос первый: тебе обязательно на 51 делить или тебя 64 тоже устроит? Если устроит то измени ту строку на
Код
putpixel(x,y,((*r + *g + *b) >> 6));

Вопрос второй: ты как в asm'e разбираешься? Если нормально то попробуй переписать тот кусок (см. выше) полностью на asm'e. При этом удерживай например теже r, g, и b в регистрах и не отпускай их smile.gif.
Ну а вообще если ты сам не сделаешь функцию putpixel (ну или не разберешься с putimage), то больше ты особо ничего добиться не сможешь.


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
cardinal
Дата 28.3.2004, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

Репутация: 2
Всего: 99



Вот тебе немного информации про putimage, а вообще я бы поискал где нибудь пример (работающий smile.gif) и посмотрел бы что там происходит.

putimage

--------------------------------------------------------------------------------

Syntax
#include <graphics.h>
void far putimage(int left, int top, void far *bitmap, int op);

Description
putimage puts the bit image previously saved with getimage back onto the screen, with the upper left corner of the image placed at (left,top). bitmap points to the area in memory where the source image is stored.
The op parameter to putimage specifies a combination operator that controls how the color for each destination pixel onscreen is computed, based on the pixel already onscreen and the corresponding source pixel in memory. The enumeration putimage_ops, as defined in graphics.h, gives names to these operators. Name Value Description
COPY_PUT 0 Copy
XOR_PUT 1 Exclusive or
OR_PUT 2 Inclusive or
AND_PUT 3 And
NOT_PUT 4 Copy the inverse of the source
In other words, COPY_PUT copies the source bitmap image onto the screen, XOR_PUT XORs the source image with the image already onscreen, OR_PUT ORs the source image with that onscreen, and so on.


Return Value
None.

Example
Код
/* putimage example */

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

#define ARROW_SIZE 10

void draw_arrow(int x, int y);

int main()
{
  /* request autodetection */
  int gdriver = DETECT, gmode, errorcode;
  void *arrow;
  int x, y, maxx;
  unsigned int size;

  /* initialize graphics and local variables */
  initgraph(&gdriver, &gmode, "");

  errorcode = graphresult();
  if (errorcode != grOk)    /* an error occurred */
  {

     printf("Graphics error: %s\n", grapherrormsg(errorcode));
     printf("Press any key to halt:");
     getch();
     exit(1);               /* terminate with an error code */
  }

  maxx = getmaxx();
  x = 0;
  y = getmaxy() / 2;
  draw_arrow(x, y);

  /* calculate the size of the image and allocate space for it */
  size = imagesize(x, y-ARROW_SIZE, x+(4*ARROW_SIZE), y+ARROW_SIZE);
  arrow = malloc(size);

  /* grab the image */
  getimage(x, y-ARROW_SIZE, x+(4*ARROW_SIZE), y+ARROW_SIZE, arrow);


  /* repeat until a key is pressed */
  while (!kbhit()) {
     /* erase old image */
     putimage(x, y-ARROW_SIZE, arrow, XOR_PUT);
     x += ARROW_SIZE;
     if (x >= maxx)
        x = 0;

     /* plot new image */
     putimage(x, y-ARROW_SIZE, arrow, XOR_PUT);
  }

  free(arrow);
  closegraph();
  return 0;
}
void draw_arrow(int x, int y) {
  moveto(x, y);
  linerel(4*ARROW_SIZE, 0);
  linerel(-2*ARROW_SIZE, -1*ARROW_SIZE);
  linerel(0, 2*ARROW_SIZE);

  linerel(2*ARROW_SIZE, -1*ARROW_SIZE);
}


http://www.cs.colorado.edu/~main/manuals/bgi/putimage.html


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0792 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.