Страниц: [1]
  Печать  
Автор Тема: Некорректно работает функция PiResizeImage  (Прочитано 5230 раз)
sarus
Участник
*
Offline Offline

Сообщений: 6


Просмотр профиля
« : Июня 02, 2010, 02:36:34 pm »

C прискорбием обнаружил, что в QNX v.6.4.1 функция PiResizeImage "криво" растягивает изображение. Растяжение по вертикали происходит нормально, а по горизонтали ширина рисунка не меняется  Undecided
Любопытно было бы узнать, это только у меня такой "баг" или он общий.
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #1 : Июня 02, 2010, 10:27:23 pm »

Я пару раз использовал, проблем не было. Приведи кусок кода, посмотрим.
Записан

sarus
Участник
*
Offline Offline

Сообщений: 6


Просмотр профиля
« Ответ #2 : Июня 03, 2010, 08:12:03 am »

Код простой:
Код:
PhImage_t *LoadImgFile( char *_FNAME, int size_w, int size_h)
{
PxMethods_t methods;
PhImage_t *img=NULL;

memset( &methods, 0, sizeof( PxMethods_t ) );
methods.flags = PX_LOAD|PX_TRANSPARENT;
methods.px_warning  = pict_load_warning;
methods.px_error    = pict_load_error;
methods.px_alloc    = pict_memory_allocate;
methods.px_free     = pict_memory_free;

           img = PxLoadImage( _FNAME, &methods);
if( img != NULL ) {
img->flags = Ph_USE_TRANSPARENCY | Ph_RELEASE_IMAGE_ALL;
}

           PhImage_t *Wimg=NULL;
if (img != NULL) {
Wimg = PiResizeImage(img, NULL, size_w, size_h, (UseShmem>0 ? Pi_SHMEM : 0) );
}
            PhReleaseImage(img);

return Wimg;
}
Самое интересное, что в 6.3.2 эта функция недокуметирована, но работает корректно.
« Последнее редактирование: Июня 03, 2010, 08:35:48 am от mike » Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #3 : Июня 03, 2010, 09:23:44 am »

Код самой функции очень прост (из 6.5.0 trunk). Более новую реализацию дать не могу, эта функция из той, что была в public доступе:

Код:
#define GR_FPMUL(a,b) ((((uint64_t)(a)) * ((uint64_t)(b))) >> 16)
#define GR_FPDIV(a,b) ((((uint64_t)(a)) << 16) / ((uint64_t)(b)))

PhImage_t *PiResizeImage(PhImage_t *image,PhRect_t const *bounds,short w,short h,int flags)
{
PhRect_t oldRect,newRect,srcRect;
PhPoint_t dst,src;
PhImage_t *newImage;
unsigned long value,xScale,yScale,xScaleInv = 0,yScaleInv = 0;
char *ptr,*new_mask_ptr;
char const *old_mask_ptr;
struct
{
unsigned long x,y;
} next;

if(bounds)
srcRect = *bounds;
else
{
srcRect.ul.x = srcRect.ul.y = 0;
srcRect.lr.x = image->size.w - 1;
srcRect.lr.y = image->size.h - 1;
}

oldRect.ul.x = oldRect.ul.y = 0;
oldRect.lr.x = w - 1;
oldRect.lr.y = h - 1;

if(!(newImage = PiInitImage(image,(PhRect_t const*)(&oldRect),&newRect,0,flags | Pi_USE_COLORS,image->colors)))
return(NULL);

if((xScale = GR_FPDIV(newImage->size.w << 16,(srcRect.lr.x - srcRect.ul.x + 1) << 16)) <= 0x10000)
xScaleInv = GR_FPDIV((srcRect.lr.x - srcRect.ul.x + 1) << 16,newImage->size.w << 16);
if((yScale = GR_FPDIV(newImage->size.h << 16,(srcRect.lr.y - srcRect.ul.y + 1) << 16)) <= 0x10000)
yScaleInv = GR_FPDIV((srcRect.lr.y - srcRect.ul.y + 1) << 16,newImage->size.h << 16);

for(dst.y = 0,next.y = srcRect.ul.y << 16,src.y = srcRect.ul.y,ptr = newImage->image,old_mask_ptr = image->mask_bm,new_mask_ptr = newImage->mask_bm;
  dst.y < newImage->size.h;
  dst.y++,ptr += newImage->bpl,new_mask_ptr += newImage->mask_bpl)
{
if(yScaleInv)
{
src.y = next.y >> 16;
next.y += yScaleInv;
}
else
{
if(dst.y < (next.y >> 16) || src.y > srcRect.lr.y)
{
memcpy(ptr,ptr - newImage->bpl,newImage->bpl);
if(newImage->mask_bm)
memcpy(new_mask_ptr,new_mask_ptr - newImage->mask_bpl,newImage->mask_bpl);

continue;
}
else
next.y += yScale;
}

if(newImage->mask_bm)
old_mask_ptr = image->mask_bm + (src.y * image->mask_bpl);

if(xScaleInv)
{
for(dst.x = 0,next.x = srcRect.ul.x << 16,src.x = srcRect.ul.x;
  dst.x < newImage->size.w;dst.x++,next.x += xScaleInv)
{
src.x = next.x >> 16;
PiGetPixel(image,src.x,src.y,&value);
PiSetPixel(newImage,dst.x,dst.y,value);

if(newImage->mask_bm && !PiGetPixelFromData((uint8_t const *)old_mask_ptr,Pg_BITMAP_TRANSPARENT,src.x,&value))
{
if(!value)
PiSetPixelInData((uint8_t*)new_mask_ptr,Pg_BITMAP_TRANSPARENT,dst.x,0);
}
}
}
else
{
unsigned long color = 0;

for(dst.x = 0,next.x = srcRect.ul.x << 16,src.x = srcRect.ul.x;
  dst.x < newImage->size.w;dst.x++)
{
if(!PiGetPixel(image,src.x,src.y,&color) && (!newImage->mask_bm || PiGetPixelFromData((uint8_t const *)old_mask_ptr,Pg_BITMAP_TRANSPARENT,src.x,&value)))
value = 1;

next.x += xScale;

src.x++;

PiSetPixel(newImage,dst.x,dst.y,color);

if(!value && newImage->mask_bm)
PiSetPixelInData((uint8_t*)new_mask_ptr,Pg_BITMAP_TRANSPARENT,dst.x,0);
}
}

if(!yScaleInv)
src.y++;
}

/* Calculate CRC tags for new image */

if(!(flags & Pi_SUPPRESS_CRC))
newImage->image_tag = PtCRC(newImage->image,newImage->bpl * newImage->size.h);

if(flags & Pi_FREE)
{
image->flags |= Ph_RELEASE_IMAGE | Ph_RELEASE_PALETTE | Ph_RELEASE_TRANSPARENCY_MASK | Ph_RELEASE_GHOST_BITMAP;
PhReleaseImage(image);
}

return(newImage);
}
Записан

sarus
Участник
*
Offline Offline

Сообщений: 6


Просмотр профиля
« Ответ #4 : Июня 03, 2010, 09:56:04 am »

Спасибо.
Вставил функцию в свой код, но результат оказался тот же. Рисунок не растягивается по горизонтали шире, чем оригинальный рисунок Sad
По вертикали все четко работает.
Надо подробнее посмотреть код функции, может и обнаружится ошибка.
Записан
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #5 : Июня 03, 2010, 03:57:28 pm »

Попробовал код из хелпа. Действительно, в 6.4.1 изображение растягивается по горизонтали неправильно (сжимается нормально). В 6.5.0 такого эффекта нет (работает нормально в обе стороны).
Записан
Страниц: [1]
  Печать  
 
Перейти в: