emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problem with library images on Windows (again)


From: Juanma Barranquero
Subject: Re: Problem with library images on Windows (again)
Date: Thu, 19 May 2005 21:31:23 +0200

> This sounds incredible.  MSVC generally produces good code, so I find
> it hard to believe that it violates the C ABI, whereby the caller
> should pop arguments off the stack.  Are you sure this is indeed what
> happens?

Yes. If, immediately before the POP EBX, I manually restore the stack
to the value it had after the PUSH EBX at the start of the routine,
Emacs does not crash, and indeed it displays the TIFF file.

But I don't think is an error in MSVC. I think it's some mixup between
"pascal" and "C" style calls (as you know, the former remove their
arguments, the latter don't). MSVC must be thinking that the external
TIFF functions do remove their arguments, so it is not doing it.
Sounds like an issue with the external declarations on the header
files.

>  Can you show some evidence, like disassembly of code around
> the call to tiff_load, which would show how arguments are pushed onto
> the stack and never popped off it?

There goes the full tiff_load code, as shown on the Visual Studio
disassembler view. You can see by yourself that, when calling Emacs
functions, MSVC uses "ADD SP, nn" to fix the stack, but it doesn't do
it after the indirect calls to fn_TIFF* functions.

-- 
                    /L/e/k/t/u

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

/* Load TIFF image IMG for use on frame F.  Value is non-zero if
   successful.  */

static int
tiff_load (f, img)
     struct frame *f;
     struct image *img;
{
01074117  push        ebp  
01074118  mov         ebp,esp 
0107411A  sub         esp,24h 
0107411D  push        ebx  
  Lisp_Object file, specified_file;
  Lisp_Object specified_data;
  TIFF *tiff;
  int width, height, x, y;
  uint32 *buf;
  int rc;
  XImagePtr ximg;
  struct gcpro gcpro1;
  tiff_memory_source memsrc;

  specified_file = image_spec_value (img->spec, QCfile, NULL);
0107411E  mov         ebx,dword ptr [ebp+0Ch] 
01074121  mov         ecx,dword ptr [ebx+28h] 
01074124  push        esi  
01074125  push        edi  
01074126  xor         edi,edi 
01074128  push        edi  
01074129  push        dword ptr [_QCfile (1109E80h)] 
0107412F  call        image_spec_value (106FF15h) 
  specified_data = image_spec_value (img->spec, QCdata, NULL);
01074134  mov         ecx,dword ptr [ebx+28h] 
01074137  push        edi  
01074138  push        dword ptr [_QCdata (1109064h)] 
0107413E  mov         dword ptr [specified_file],eax 
01074141  call        image_spec_value (106FF15h) 
01074146  add         esp,10h 
  file = Qnil;
  GCPRO1 (file);

  fn_TIFFSetErrorHandler (tiff_error_handler);
01074149  push        offset tiff_error_handler (10723B8h) 
0107414E  mov         esi,eax 
01074150  call        dword ptr [_fn_TIFFSetErrorHandler (1138B64h)] 
  fn_TIFFSetWarningHandler (tiff_warning_handler);
01074156  push        offset tiff_warning_handler (1072400h) 
0107415B  call        dword ptr [_fn_TIFFSetWarningHandler (1138B78h)] 

  if (NILP (specified_data))
01074161  cmp         esi,dword ptr [_Qnil (1108D6Ch)] 
01074167  jne         tiff_load+0AEh (10741C5h) 
    {
      /* Read from a file */
      file = x_find_image_file (specified_file);
01074169  push        dword ptr [specified_file] 
0107416C  call        x_find_image_file (10706E5h) 
01074171  pop         ecx  
      if (!STRINGP (file))
01074172  mov         ecx,eax 
01074174  and         ecx,0E0000000h 
0107417A  cmp         ecx,60000000h 
01074180  mov         dword ptr [buf],eax 
01074183  je          tiff_load+81h (1074198h) 
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
01074185  push        dword ptr [_Qnil (1108D6Ch)] 
0107418B  push        dword ptr [specified_file] 
0107418E  push        offset string "Cannot find image file `%s'" (1166718h) 
          UNGCPRO;
          return 0;
01074193  jmp         tiff_load+11Ah (1074231h) 
        }

      /* Try to open the image file.  */
      tiff = fn_TIFFOpen (SDATA (file), "r");
01074198  push        offset string "r" (115F1E0h) 
0107419D  and         eax,1FFFFFFFh 
010741A2  push        dword ptr [eax+0Ch] 
010741A5  call        dword ptr [_fn_TIFFOpen (1138AC0h)] 
010741AB  mov         esi,eax 
      if (tiff == NULL)
010741AD  cmp         esi,edi 
010741AF  jne         tiff_load+129h (1074240h) 
        {
          image_error ("Cannot open `%s'", file, Qnil);
010741B5  push        dword ptr [_Qnil (1108D6Ch)] 
010741BB  push        dword ptr [buf] 
010741BE  push        offset string "Cannot open `%s'" (1166DA4h) 
          UNGCPRO;
          return 0;
010741C3  jmp         tiff_load+11Ah (1074231h) 
        }
    }
  else
    {
      /* Memory source! */
      memsrc.bytes = SDATA (specified_data);
010741C5  mov         eax,esi 
010741C7  and         eax,1FFFFFFFh 
010741CC  mov         ecx,dword ptr [eax+0Ch] 
010741CF  mov         dword ptr [memsrc],ecx 
      memsrc.len = SBYTES (specified_data);
010741D2  mov         ecx,dword ptr [eax+4] 
010741D5  cmp         ecx,edi 
010741D7  jge         tiff_load+0C9h (10741E0h) 
010741D9  mov         eax,dword ptr [eax] 
010741DB  mov         dword ptr [ebp-20h],eax 
010741DE  jmp         tiff_load+0CCh (10741E3h) 
010741E0  mov         dword ptr [ebp-20h],ecx 
      memsrc.index = 0;

      tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc,
                                (TIFFReadWriteProc) tiff_read_from_memory,
                                (TIFFReadWriteProc) tiff_write_from_memory,
                                tiff_seek_in_memory,
                                tiff_close_memory,
                                tiff_size_of_memory,
                                tiff_mmap_memory,
                                tiff_unmap_memory);
010741E3  push        offset tiff_unmap_memory (10723ACh) 
010741E8  push        offset tiff_mmap_memory (10723A9h) 
010741ED  push        offset tiff_size_of_memory (10723ADh) 
010741F2  push        offset tiff_close_memory (10723A6h) 
010741F7  push        offset tiff_seek_in_memory (107236Fh) 
010741FC  push        offset tiff_write_from_memory (107236Bh) 
01074201  push        offset tiff_read_from_memory (1072335h) 
01074206  lea         eax,[memsrc] 
01074209  push        eax  
0107420A  push        offset string "r" (115F1E0h) 
0107420F  push        offset string "memory_source" (1166DFCh) 
01074214  mov         dword ptr [ebp-1Ch],edi 
01074217  call        dword ptr [_fn_TIFFClientOpen (1138B00h)] 
0107421D  mov         esi,eax 

      if (!tiff)
0107421F  cmp         esi,edi 
01074221  jne         tiff_load+129h (1074240h) 
        {
          image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
01074223  push        dword ptr [_Qnil (1108D6Ch)] 
01074229  push        dword ptr [ebx+28h] 
0107422C  push        offset string "Cannot open memory source for
`%"... (1166DD8h)
01074231  call        add_to_log (1035C57h) 
01074236  add         esp,0Ch 
          UNGCPRO;
          return 0;
01074239  xor         eax,eax 
0107423B  jmp         tiff_load+272h (1074389h) 
        }
    }

  /* Get width and height of the image, and allocate a raster buffer
     of width x height 32-bit values.  */
  fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
01074240  lea         eax,[width] 
01074243  push        eax  
01074244  push        100h 
01074249  push        esi  
0107424A  call        dword ptr [_fn_TIFFGetField (1138B2Ch)] 
  fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
01074250  lea         eax,[height] 
01074253  push        eax  
01074254  push        101h 
01074259  push        esi  
0107425A  call        dword ptr [_fn_TIFFGetField (1138B2Ch)] 
  buf = (uint32 *) xmalloc (width * height * sizeof *buf);
01074260  mov         eax,dword ptr [height] 
01074263  imul        eax,dword ptr [width] 
01074267  shl         eax,2 
0107426A  push        eax  
0107426B  call        xmalloc (10070AFh) 
01074270  pop         ecx  

  rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
01074271  push        edi  
01074272  push        eax  
01074273  push        dword ptr [height] 
01074276  mov         dword ptr [buf],eax 
01074279  push        dword ptr [width] 
0107427C  push        esi  
0107427D  call        dword ptr [_fn_TIFFReadRGBAImage (1138B90h)] 
  fn_TIFFClose (tiff);
01074283  push        esi  
01074284  mov         dword ptr [specified_file],eax 
01074287  call        dword ptr [_fn_TIFFClose (1138AECh)] 
  if (!rc)
0107428D  cmp         dword ptr [specified_file],edi 
01074290  jne         tiff_load+198h (10742AFh) 
    {
      image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
01074292  push        dword ptr [_Qnil (1108D6Ch)] 
01074298  push        dword ptr [ebx+28h] 
0107429B  push        offset string "Error reading TIFF image `%s'" (1166DB8h) 
010742A0  call        add_to_log (1035C57h) 
010742A5  add         esp,0Ch 
010742A8  xor         esi,esi 
010742AA  jmp         tiff_load+267h (107437Eh) 
      xfree (buf);
      UNGCPRO;
      return 0;
    }

  /* Create the X image and pixmap.  */
  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
010742AF  lea         eax,[ebx+4] 
010742B2  push        eax  
010742B3  push        dword ptr [height] 
010742B6  lea         esi,[specified_file] 
010742B9  push        dword ptr [width] 
010742BC  xor         eax,eax 
010742BE  push        dword ptr [f] 
010742C1  call        x_create_x_image_and_pixmap (1072AE6h) 
010742C6  add         esp,10h 
010742C9  test        eax,eax 
010742CB  je          tiff_load+191h (10742A8h) 
    {
      xfree (buf);
      UNGCPRO;
      return 0;
    }

  /* Initialize the color table.  */
  init_color_table ();

  /* Process the pixel raster.  Origin is in the lower-left corner.  */
  for (y = 0; y < height; ++y)
010742CD  mov         dword ptr [y],edi 
010742D0  mov         edi,dword ptr [height] 
010742D3  test        edi,edi 
010742D5  jle         tiff_load+224h (107433Bh) 
    {
      uint32 *row = buf + y * width;
010742D7  mov         eax,dword ptr [y] 
010742DA  imul        eax,dword ptr [width] 
010742DE  mov         ecx,dword ptr [buf] 

      for (x = 0; x < width; ++x)
010742E1  xor         esi,esi 
010742E3  cmp         dword ptr [width],esi 
010742E6  lea         eax,[ecx+eax*4] 
010742E9  mov         dword ptr [row],eax 
010742EC  jle         tiff_load+21Ch (1074333h) 
        {
          uint32 abgr = row[x];
010742EE  mov         eax,dword ptr [row] 
010742F1  mov         eax,dword ptr [eax+esi*4] 
          int r = TIFFGetR (abgr) << 8;
          int g = TIFFGetG (abgr) << 8;
          int b = TIFFGetB (abgr) << 8;
          XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
010742F4  mov         ecx,eax 
010742F6  shr         ecx,10h 
010742F9  xor         edx,edx 
010742FB  mov         dh,cl 
010742FD  mov         ecx,eax 
010742FF  shr         ecx,8 
01074302  xor         ebx,ebx 
01074304  mov         bh,cl 
01074306  xor         ecx,ecx 
01074308  mov         ch,al 
0107430A  mov         eax,edx 
0107430C  push        ecx  
0107430D  mov         ecx,ebx 
0107430F  call        lookup_rgb_color (10718CDh) 
01074314  sub         edi,dword ptr [y] 
01074317  mov         ebx,eax 
01074319  dec         edi  
0107431A  push        edi  
0107431B  mov         edi,dword ptr [specified_file] 
0107431E  push        esi  
0107431F  call        XPutPixel (10719CBh) 
01074324  mov         edi,dword ptr [height] 
01074327  add         esp,0Ch 
0107432A  inc         esi  
0107432B  cmp         esi,dword ptr [width] 
0107432E  jl          tiff_load+1D7h (10742EEh) 

      for (x = 0; x < width; ++x)
01074330  mov         ebx,dword ptr [img] 
    {
      xfree (buf);
      UNGCPRO;
      return 0;
    }

  /* Initialize the color table.  */
  init_color_table ();

  /* Process the pixel raster.  Origin is in the lower-left corner.  */
  for (y = 0; y < height; ++y)
01074333  inc         dword ptr [y] 
01074336  cmp         dword ptr [y],edi 
01074339  jl          tiff_load+1C0h (10742D7h) 
        }
    }

#ifdef COLOR_TABLE_SUPPORT
  /* Remember the colors allocated for the image.  Free the color table.  */
  img->colors = colors_in_color_table (&img->ncolors);
  free_color_table ();
#endif /* COLOR_TABLE_SUPPORT */

  img->width = width;
0107433B  mov         eax,dword ptr [width] 
  img->height = height;

  /* Maybe fill in the background field while we have ximg handy. */
  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
0107433E  mov         ecx,dword ptr [ebx+28h] 
01074341  mov         dword ptr [ebx+1Ch],eax 
01074344  mov         dword ptr [ebx+20h],edi 
01074347  push        0    
01074349  push        dword ptr [_QCbackground (1141828h)] 
0107434F  call        image_spec_value (106FF15h) 
01074354  cmp         eax,dword ptr [_Qnil (1108D6Ch)] 
0107435A  pop         ecx  
0107435B  pop         ecx  
0107435C  jne         tiff_load+25Ch (1074373h) 
    IMAGE_BACKGROUND (img, f, ximg);
0107435E  test        byte ptr [ebx+18h],2 
01074362  jne         tiff_load+25Ch (1074373h) 
01074364  push        dword ptr [specified_file] 
01074367  push        dword ptr [f] 
0107436A  push        ebx  
0107436B  call        image_background (107012Ah) 
01074370  add         esp,0Ch 

  /* Put the image into the pixmap, then free the X image and its buffer.  */
  x_put_x_image (f, ximg, img->pixmap, width, height);
  x_destroy_x_image (ximg);
01074373  mov         eax,dword ptr [specified_file] 
01074376  call        x_destroy_x_image (10706D5h) 
0107437B  xor         esi,esi 
0107437D  inc         esi  
  xfree (buf);
0107437E  push        dword ptr [buf] 
01074381  call        xfree (1007174h) 
01074386  pop         ecx  

  UNGCPRO;
  return 1;
01074387  mov         eax,esi 
01074389  pop         edi  
0107438A  pop         esi  
0107438B  pop         ebx  
}
0107438C  leave            
0107438D  ret




reply via email to

[Prev in Thread] Current Thread [Next in Thread]