Removed old unused libs.

Original commit message from CVS:
Removed old unused libs.
This commit is contained in:
Wim Taymans 2001-06-15 22:00:37 +00:00
parent bb55e797b8
commit f0051deb21
34 changed files with 2 additions and 9162 deletions

View file

@ -1,9 +1,4 @@
if HAVE_CPU_I386
GSTARCH_SUBDS = winloader
else
GSTARCH_SUBDS =
endif
SUBDIRS = riff colorspace getbits putbits idct videoscale audio $(GSTARCH_SUBDS)
SUBDIRS = riff getbits putbits idct audio
DIST_SUBDIRS = riff colorspace getbits putbits videoscale winloader audio idct
DIST_SUBDIRS = riff getbits putbits audio idct

View file

@ -1,7 +0,0 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

View file

@ -1,19 +0,0 @@
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libgstcolorspace.la
if HAVE_CPU_I386
ARCHSRCS = yuv2rgb_mmx16.s
else
ARCHSRCS =
endif
libgstcolorspace_la_SOURCES = gstcolorspace.c rgb2rgb.c yuv2rgb.c $(ARCHSRCS)
libgstcolorspaceincludedir = $(includedir)/gst/libs/gstcolorspace
libgstcolorspaceinclude_HEADERS = gstcolorspace.h
noinst_HEADERS = yuv2rgb.h
# FIXME is this needed?
CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math

View file

@ -1,78 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
//#define DEBUG_ENABLED
#include <gst/gst.h>
#include <gstcolorspace.h>
extern GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceConverter *space, GstColorSpaceType srcspace,
GstColorSpaceType destspace);
extern GstColorSpaceConvertFunction gst_colorspace_yuv2rgb_get_converter(GstColorSpaceConverter *space, GstColorSpaceType srcspace,
GstColorSpaceType destspace);
extern GstColorSpaceConvertFunction gst_colorspace_rgb2yuv_get_converter(GstColorSpaceConverter *space, GstColorSpaceType srcspace,
GstColorSpaceType destspace);
extern GstColorSpaceConvertFunction gst_colorspace_yuv2yuv_get_converter(GstColorSpaceConverter *space, GstColorSpaceType srcspace,
GstColorSpaceType destspace);
GstColorSpaceConverter *gst_colorspace_converter_new(gint width, gint height, GstColorSpaceType srcspace,
GstColorSpaceType destspace, GdkVisual *destvisual)
{
GstColorSpaceConverter *new = g_malloc(sizeof(GstColorSpaceConverter));
new->width = width;
new->height = height;
new->srcspace = srcspace;
new->destspace = destspace;
new->visual = destvisual;
new->color_tables = NULL;
new->convert = NULL;
GST_DEBUG (0,"gst_colorspace: new\n");
if (GST_COLORSPACE_IS_RGB_TYPE(srcspace)) {
if (GST_COLORSPACE_IS_RGB_TYPE(destspace)) {
new->convert = gst_colorspace_rgb2rgb_get_converter(new, srcspace, destspace);
}
else {
//return gst_colorspace_rgb2yuv_get_converter(srcspace, destspace);
}
}
else if (GST_COLORSPACE_IS_YUV_TYPE(srcspace)) {
if (GST_COLORSPACE_IS_RGB_TYPE(destspace)) {
new->convert = gst_colorspace_yuv2rgb_get_converter(new, srcspace, destspace);
}
else {
//return gst_colorspace_yuv2yuv_get_converter(srcspace, destspace);
}
}
if (new->convert == NULL) {
g_print("gst_colorspace: conversion not implemented\n");
g_free(new);
new = NULL;
}
return new;
}
void gst_colorspace_destroy(GstColorSpaceConverter *space)
{
if (space->color_tables) g_free(space->color_tables);
g_free(space);
}

View file

@ -1,81 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_COLORSPACE_H__
#define __GST_COLORSPACE_H__
#include <gdk/gdk.h>
#include <gst/gst.h>
#include "yuv2rgb.h"
typedef enum {
GST_COLORSPACE_RGB555,
GST_COLORSPACE_BGR555,
GST_COLORSPACE_RGB565,
GST_COLORSPACE_BGR565,
GST_COLORSPACE_RGB24,
GST_COLORSPACE_BGR24,
GST_COLORSPACE_RGB32,
GST_COLORSPACE_BGR32,
GST_COLORSPACE_YUV420,
GST_COLORSPACE_YUV420P,
GST_COLORSPACE_YUV422,
GST_COLORSPACE_YUV422P
} GstColorSpaceType;
#define GST_COLORSPACE_RGB_FIRST GST_COLORSPACE_RGB555
#define GST_COLORSPACE_RGB_LAST GST_COLORSPACE_BGR32
#define GST_COLORSPACE_YUV_FIRST GST_COLORSPACE_YUV420
#define GST_COLORSPACE_YUV_LAST GST_COLORSPACE_YUV422P
typedef struct _GstColorSpaceConverter GstColorSpaceConverter;
typedef void (*GstColorSpaceConvertFunction) (GstColorSpaceConverter *space, guchar *src, guchar *dest);
struct _GstColorSpaceConverter {
guint width;
guint height;
GstColorSpaceType srcspace;
GstColorSpaceType destspace;
GdkVisual *visual;
guint insize;
guint outsize;
/* private */
GstColorSpaceYUVTables *color_tables;
GstColorSpaceConvertFunction convert;
};
#define GST_COLORSPACE_IS_RGB_TYPE(type) ((type)>=GST_COLORSPACE_RGB_FIRST && \
(type)<=GST_COLORSPACE_RGB_LAST)
#define GST_COLORSPACE_IS_YUV_TYPE(type) ((type)>=GST_COLORSPACE_YUV_FIRST && \
(type)<=GST_COLORSPACE_YUV_LAST)
GstColorSpaceConverter *gst_colorspace_converter_new(gint width, gint height, GstColorSpaceType srcspace,
GstColorSpaceType destspace, GdkVisual *destvisual);
#define gst_colorspace_convert(converter, src, dest) \
(converter)->convert((converter), (src), (dest))
void gst_colorspace_destroy(GstColorSpaceConverter *space);
#endif /* __GST_COLORSPACE_H__ */

View file

@ -1,284 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <string.h>
//#define DEBUG_ENABLED
#include "gstcolorspace.h"
static void gst_colorspace_rgb_to_rgb_identity(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_rgb24_to_bgr24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_rgb24_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_rgb32_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_rgb555_to_rgb565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_bgr565_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_bgr24_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_bgr32_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceConverter *space, GstColorSpaceType src, GstColorSpaceType dest) {
switch(src) {
case GST_COLORSPACE_RGB24:
space->insize = space->width*space->height*3;
switch(dest) {
case GST_COLORSPACE_RGB24:
space->outsize = space->width*space->height*3;
return gst_colorspace_rgb_to_rgb_identity;
case GST_COLORSPACE_BGR24:
space->outsize = space->width*space->height*3;
return gst_colorspace_rgb24_to_bgr24;
case GST_COLORSPACE_RGB32:
space->outsize = space->width*space->height*4;
return gst_colorspace_rgb24_to_rgb32;
default:
break;
}
break;
case GST_COLORSPACE_BGR24:
space->insize = space->width*space->height*3;
switch(dest) {
case GST_COLORSPACE_RGB24:
space->outsize = space->width*space->height*3;
return gst_colorspace_rgb24_to_bgr24;
case GST_COLORSPACE_BGR24:
space->outsize = space->width*space->height*3;
return gst_colorspace_rgb_to_rgb_identity;
case GST_COLORSPACE_BGR565:
space->outsize = space->width*space->height*2;
return gst_colorspace_bgr24_to_bgr565;
default:
break;
}
break;
case GST_COLORSPACE_RGB32:
space->insize = space->width*space->height*4;
switch(dest) {
case GST_COLORSPACE_BGR32:
space->outsize = space->width*space->height*4;
return gst_colorspace_rgb32_to_bgr32;
case GST_COLORSPACE_RGB32:
space->outsize = space->width*space->height*4;
return gst_colorspace_rgb_to_rgb_identity;
default:
break;
}
break;
case GST_COLORSPACE_BGR32:
space->insize = space->width*space->height*4;
switch(dest) {
case GST_COLORSPACE_RGB32:
space->outsize = space->width*space->height*4;
return gst_colorspace_rgb32_to_bgr32;
case GST_COLORSPACE_BGR32:
space->outsize = space->width*space->height*4;
return gst_colorspace_rgb_to_rgb_identity;
case GST_COLORSPACE_BGR565:
space->outsize = space->width*space->height*2;
return gst_colorspace_bgr32_to_bgr565;
case GST_COLORSPACE_RGB565:
space->outsize = space->width*space->height*2;
return gst_colorspace_bgr32_to_bgr565;
default:
break;
}
break;
case GST_COLORSPACE_BGR555:
space->insize = space->width*space->height*2;
switch(dest) {
case GST_COLORSPACE_RGB555:
space->outsize = space->width*space->height*2;
return gst_colorspace_rgb32_to_bgr32;
case GST_COLORSPACE_BGR565:
space->outsize = space->width*space->height*2;
return gst_colorspace_rgb555_to_rgb565;
default:
break;
}
break;
case GST_COLORSPACE_BGR565:
space->insize = space->width*space->height*2;
switch(dest) {
case GST_COLORSPACE_RGB32 :
space->outsize = space->width*space->height*4;
return gst_colorspace_bgr565_to_rgb32;
default:
break;
};
break;
default:
break;
}
g_print("gst_colorspace: conversion not supported %d %d\n", src, dest);
return NULL;
}
static void gst_colorspace_rgb_to_rgb_identity(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
memcpy(dest, src, space->outsize);
}
static void gst_colorspace_rgb24_to_bgr24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
gchar temp;
GST_DEBUG (0,"gst_colorspace_rgb24_to_bgr24 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height);
size = space->outsize/3;
if (src == dest) {
while (size--) {
temp = src[0];
src[0] = src[2];
src[2] = temp;
src+=3;
}
}
else {
while (size--) {
*dest++ = src[2];
*dest++ = src[1];
*dest++ = src[0];
src+=3;
}
}
GST_DEBUG (0,"gst_colorspace_rgb24_to_bgr24 end\n");
}
static void gst_colorspace_bgr24_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
guint16 *destptr = (guint16 *)dest;
GST_DEBUG (0,"gst_colorspace_bgr24_to_bgr565 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height);
size = space->outsize/2;
while (size--) {
*destptr++ = ((src[2]&0xF8)<<8)|((src[1]&0xFC)<<3)|((src[0]&0xF8)>>3);
src+=3;
}
GST_DEBUG (0,"gst_colorspace_bgr24_to_bgr565 end\n");
}
static void gst_colorspace_bgr32_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
guint16 *destptr = (guint16 *)dest;
GST_DEBUG (0,"gst_colorspace_bgr32_to_bgr565 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height);
size = space->outsize/2;
while (size--) {
*destptr++ = ((src[2]&0xF8)<<8)|((src[1]&0xFC)<<3)|((src[0]&0xF8)>>3);
src+=4;
}
GST_DEBUG (0,"gst_colorspace_bgr32_to_bgr565 end\n");
}
static void gst_colorspace_rgb24_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
guint32 *destptr = (guint32 *)dest;
GST_DEBUG (0,"gst_colorspace_rgb24_to_rgb32 %p %p %d\n", src, dest, space->outsize);
size = space->outsize/4;
while (size--) {
*destptr++ = (src[0]<<16)|(src[1]<<8)|src[2];
src+=3;
}
GST_DEBUG (0,"gst_colorspace_rgb24_to_rgb32 end\n");
}
static void gst_colorspace_rgb32_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
gchar temp;
GST_DEBUG (0,"gst_colorspace_rgb32_to_bgr32 %p %p %d\n", src, dest, space->outsize);
size = space->outsize/4;
if (src == dest) {
while (size--) {
temp = src[0];
src[0] = src[2];
src[2] = temp;
src+=4;
}
}
else {
while (size--) {
*dest++ = src[2];
*dest++ = src[1];
*dest++ = src[0];
dest++;
src+=4;
}
}
GST_DEBUG (0,"gst_colorspace_rgb32_to_bgr32 end\n");
}
static void gst_colorspace_rgb555_to_rgb565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
guint32 *srcptr = (guint32 *) src;
guint32 *destptr = (guint32 *) dest;
GST_DEBUG (0,"gst_colorspace_rgb555_to_rgb565 %p %p %d\n", src, dest, space->outsize);
size = space->outsize/4;
if (src == dest) {
while (size--) {
*srcptr += (*srcptr++)&0xFFE0FFE0;
}
}
else {
while (size--) {
*destptr++ = *srcptr + ((*srcptr++)&0xFFE0FFE0);
}
}
}
static void gst_colorspace_bgr565_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
gint size;
guint16 *srcptr = (guint16 *)src;
guint32 *destptr = (guint32 *)dest;
size = space->outsize >> 2;
g_assert (src != dest); /* todo */
while (size--) {
/* in detail I do this
red=(unsigned char)(*srcptr)&0x1f;
green=(unsigned char)(((*srcptr)&0x07E0)>>5);
blue=(unsigned char)(((*srcptr)&0xf800)>>11);
*destptr++ = (((guint32)blue) << 3)
| (((guint32)green) << (8+2))
| (((guint32)red) << (16+3));
*/
*destptr++ = (((*srcptr)&0xf800)>>8)|(((*srcptr)&0x07E0)<<5)|(((*srcptr)&0x1f)<<19);
srcptr++;
}
}

View file

@ -1,811 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <math.h>
#include <stdlib.h>
//#define DEBUG_ENABLED
#include <gst/gst.h>
#include <gstcolorspace.h>
//#undef HAVE_LIBMMX
#ifdef HAVE_LIBMMX
#include "mmx.h"
#endif
#include "yuv2rgb.h"
static void gst_colorspace_yuv420P_to_bgr16_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_bgr32_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_rgb24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_bgr24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_rgb16(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv420P_to_bgr16_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
static void gst_colorspace_yuv_to_rgb16(GstColorSpaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
static void gst_colorspace_yuv_to_rgb24(GstColorSpaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
static void gst_colorspace_yuv_to_rgb32(GstColorSpaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
#ifdef HAVE_LIBMMX
static void gst_colorspace_yuv_to_bgr32_mmx(GstColorSpaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
extern void gst_colorspace_yuv_to_bgr16_mmx(GstColorSpaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
#endif
static GstColorSpaceYUVTables * gst_colorspace_init_yuv(long depth,
long red_mask, long green_mask, long blue_mask);
GstColorSpaceConvertFunction gst_colorspace_yuv2rgb_get_converter(GstColorSpaceConverter *space, GstColorSpaceType src, GstColorSpaceType dest) {
GST_DEBUG (0,"gst_colorspace_yuv2rgb_get_converter %d %d\n", src, dest);
switch(src) {
case GST_COLORSPACE_YUV420P:
space->insize = space->width*space->height+space->width*space->height/2;
switch(dest) {
case GST_COLORSPACE_BGR32:
space->color_tables = gst_colorspace_init_yuv(32, 0xFF0000, 0x00FF00, 0x0000FF);
space->outsize = space->width*space->height*4;
#ifdef HAVE_LIBMMX
return gst_colorspace_yuv420P_to_bgr32_mmx;
#else
return gst_colorspace_yuv420P_to_bgr32;
#endif
case GST_COLORSPACE_RGB32:
space->color_tables = gst_colorspace_init_yuv(32, 0x0000FF, 0x00FF00, 0xFF0000);
space->outsize = space->width*space->height*4;
return gst_colorspace_yuv420P_to_rgb32;
case GST_COLORSPACE_RGB24:
space->color_tables = gst_colorspace_init_yuv(24, 0x0000FF, 0x00FF00, 0xFF0000);
space->outsize = space->width*space->height*3;
return gst_colorspace_yuv420P_to_rgb24;
case GST_COLORSPACE_BGR24:
space->color_tables = gst_colorspace_init_yuv(24, 0xFF0000, 0x00FF00, 0x0000FF);
space->outsize = space->width*space->height*3;
return gst_colorspace_yuv420P_to_bgr24;
case GST_COLORSPACE_RGB555:
case GST_COLORSPACE_RGB565:
case GST_COLORSPACE_BGR555:
g_return_val_if_fail(space->visual != NULL, NULL);
space->color_tables = gst_colorspace_init_yuv(16, space->visual->red_mask, space->visual->green_mask, space->visual->blue_mask);
space->outsize = space->width*space->height*2;
return gst_colorspace_yuv420P_to_rgb16;
case GST_COLORSPACE_BGR565:
g_return_val_if_fail(space->visual != NULL, NULL);
space->color_tables = gst_colorspace_init_yuv(16, space->visual->red_mask, space->visual->green_mask, space->visual->blue_mask);
space->outsize = space->width*space->height*2;
#ifdef HAVE_LIBMMX
return gst_colorspace_yuv420P_to_bgr16_mmx;
#else
return gst_colorspace_yuv420P_to_rgb16;
#endif
default:
break;
}
break;
default:
break;
}
g_print("gst_colorspace_yuv2rgb not implemented\n");
return NULL;
}
static void gst_colorspace_yuv420P_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_bgr32\n");
size = space->width * space->height;
gst_colorspace_yuv_to_rgb32(space->color_tables,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
static void gst_colorspace_yuv420P_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
{
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_rgb32\n");
size = space->width * space->height;
gst_colorspace_yuv_to_rgb32(space->color_tables,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
static void gst_colorspace_yuv420P_to_bgr24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_bgr24\n");
size = space->width * space->height;
gst_colorspace_yuv_to_rgb24(space->color_tables,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
static void gst_colorspace_yuv420P_to_rgb24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_rgb24\n");
size = space->width * space->height;
gst_colorspace_yuv_to_rgb24(space->color_tables,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
static void gst_colorspace_yuv420P_to_rgb16(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_rgb16\n");
size = space->width * space->height;
gst_colorspace_yuv_to_rgb16(space->color_tables,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
#ifdef HAVE_LIBMMX
static void gst_colorspace_yuv420P_to_bgr32_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_rgb32_mmx\n");
size = space->width * space->height;
gst_colorspace_yuv_to_bgr32_mmx(NULL,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
}
static void gst_colorspace_yuv420P_to_bgr16_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG (0,"gst_colorspace_yuv420P_to_bgr16_mmx \n");
size = space->width * space->height;
gst_colorspace_yuv_to_bgr16_mmx(NULL,
src, // Y component
src+size, // cr component
src+size+(size>>2), // cb component
dest,
space->height,
space->width);
GST_DEBUG (0,"gst_colorspace_yuv420P_to_bgr16_mmx done\n");
}
#endif
/*
* How many 1 bits are there in the longword.
* Low performance, do not call often.
*/
static int
number_of_bits_set(a)
unsigned long a;
{
if(!a) return 0;
if(a & 1) return 1 + number_of_bits_set(a >> 1);
return(number_of_bits_set(a >> 1));
}
/*
* Shift the 0s in the least significant end out of the longword.
* Low performance, do not call often.
*/
static unsigned long
shifted_down(a)
unsigned long a;
{
if(!a) return 0;
if(a & 1) return a;
return a >> 1;
}
/*
* How many 0 bits are there at most significant end of longword.
* Low performance, do not call often.
*/
static int
free_bits_at_top(a)
unsigned long a;
{
/* assume char is 8 bits */
if(!a) return sizeof(unsigned long) * 8;
/* assume twos complement */
if(((long)a) < 0l) return 0;
return 1 + free_bits_at_top ( a << 1);
}
/*
* How many 0 bits are there at least significant end of longword.
* Low performance, do not call often.
*/
static int
free_bits_at_bottom(a)
unsigned long a;
{
/* assume char is 8 bits */
if(!a) return sizeof(unsigned long) * 8;
if(((long)a) & 1l) return 0;
return 1 + free_bits_at_bottom ( a >> 1);
}
/*
*--------------------------------------------------------------
*
* InitColor16Dither --
*
* To get rid of the multiply and other conversions in color
* dither, we use a lookup table.
*
* Results:
* None.
*
* Side effects:
* The lookup tables are initialized.
*
*--------------------------------------------------------------
*/
static GstColorSpaceYUVTables *
gst_colorspace_init_yuv(long depth, long red_mask, long green_mask, long blue_mask)
{
int CR, CB, i;
int *L_tab, *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
long *r_2_pix_alloc;
long *g_2_pix_alloc;
long *b_2_pix_alloc;
GstColorSpaceYUVTables *tables = g_malloc(sizeof(GstColorSpaceYUVTables));
L_tab = tables->L_tab = (int *)malloc(256*sizeof(int));
Cr_r_tab = tables->Cr_r_tab = (int *)malloc(256*sizeof(int));
Cr_g_tab = tables->Cr_g_tab = (int *)malloc(256*sizeof(int));
Cb_g_tab = tables->Cb_g_tab = (int *)malloc(256*sizeof(int));
Cb_b_tab = tables->Cb_b_tab = (int *)malloc(256*sizeof(int));
r_2_pix_alloc = (long *)malloc(768*sizeof(long));
g_2_pix_alloc = (long *)malloc(768*sizeof(long));
b_2_pix_alloc = (long *)malloc(768*sizeof(long));
if (L_tab == NULL ||
Cr_r_tab == NULL ||
Cr_g_tab == NULL ||
Cb_g_tab == NULL ||
Cb_b_tab == NULL ||
r_2_pix_alloc == NULL ||
g_2_pix_alloc == NULL ||
b_2_pix_alloc == NULL) {
fprintf(stderr, "Could not get enough memory in InitColorDither\n");
exit(1);
}
for (i=0; i<256; i++) {
L_tab[i] = i;
/*
if (gammaCorrectFlag) {
L_tab[i] = GAMMA_CORRECTION(i);
}
*/
CB = CR = i;
/*
if (chromaCorrectFlag) {
CB -= 128;
CB = CHROMA_CORRECTION128(CB);
CR -= 128;
CR = CHROMA_CORRECTION128(CR);
}
else
*/
{
CB -= 128; CR -= 128;
}
Cr_r_tab[i] = (0.419/0.299) * CR;
Cr_g_tab[i] = -(0.299/0.419) * CR;
Cb_g_tab[i] = -(0.114/0.331) * CB;
Cb_b_tab[i] = (0.587/0.331) * CB;
}
/*
* Set up entries 0-255 in rgb-to-pixel value tables.
*/
for (i = 0; i < 256; i++) {
r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(red_mask));
r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(red_mask);
g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(green_mask));
g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(green_mask);
b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(blue_mask));
b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(blue_mask);
/*
* If we have 16-bit output depth, then we double the value
* in the top word. This means that we can write out both
* pixels in the pixel doubling mode with one op. It is
* harmless in the normal case as storing a 32-bit value
* through a short pointer will lose the top bits anyway.
* A similar optimisation for Alpha for 64 bit has been
* prepared for, but is not yet implemented.
*/
if(!(depth == 32) && !(depth == 24)) {
r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16;
g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16;
b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16;
}
#ifdef SIXTYFOUR_BIT
if(depth == 32) {
r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 32;
g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 32;
b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 32;
}
#endif
}
/*
* Spread out the values we have to the rest of the array so that
* we do not need to check for overflow.
*/
for (i = 0; i < 256; i++) {
r_2_pix_alloc[i] = r_2_pix_alloc[256];
r_2_pix_alloc[i+ 512] = r_2_pix_alloc[511];
g_2_pix_alloc[i] = g_2_pix_alloc[256];
g_2_pix_alloc[i+ 512] = g_2_pix_alloc[511];
b_2_pix_alloc[i] = b_2_pix_alloc[256];
b_2_pix_alloc[i+ 512] = b_2_pix_alloc[511];
}
tables->r_2_pix = r_2_pix_alloc + 256;
tables->g_2_pix = g_2_pix_alloc + 256;
tables->b_2_pix = b_2_pix_alloc + 256;
return tables;
}
/*
*--------------------------------------------------------------
*
* Color16DitherImage --
*
* Converts image into 16 bit color.
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
static void
gst_colorspace_yuv_to_rgb16(tables, lum, cb, cr, out, rows, cols)
GstColorSpaceYUVTables *tables;
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
unsigned char *out;
int cols, rows;
{
int L, CR, CB;
unsigned short *row1, *row2;
unsigned char *lum2;
int x, y;
int cr_r;
int crb_g;
int cb_b;
int cols_2 = cols>>1;
row1 = (unsigned short *)out;
row2 = row1 + cols;
lum2 = lum + cols;
for (y=rows>>1; y; y--) {
for (x=cols_2; x; x--) {
CR = *cr++;
CB = *cb++;
cr_r = tables->Cr_r_tab[CR];
crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
cb_b = tables->Cb_b_tab[CB];
L = tables->L_tab[(int) *lum++];
*row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
L = tables->L_tab[(int) *lum++];
*row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
/*
* Now, do second row.
*/
L = tables->L_tab[(int) *lum2++];
*row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
L = tables->L_tab[(int) *lum2++];
*row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
}
/*
* These values are at the start of the next line, (due
* to the ++'s above),but they need to be at the start
* of the line after that.
*/
lum = lum2;
row1 = row2;
lum2 += cols;
row2 += cols;
}
}
static void
gst_colorspace_yuv_to_rgb24(tables, lum, cb, cr, out, rows, cols)
GstColorSpaceYUVTables *tables;
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
unsigned char *out;
int cols, rows;
{
int L, CR, CB;
unsigned char *row1, *row2;
unsigned char *lum2;
int x, y;
int cr_r;
int crb_g;
int cb_b;
int cols_2 = cols>>1;
int cols_3 = cols*3;
unsigned char pixels[4];
row1 = out;
row2 = row1 + cols_3;
lum2 = lum + cols;
for (y=rows>>1; y; y--) {
for (x=cols_2; x; x--) {
CR = *cr++;
CB = *cb++;
cr_r = tables->Cr_r_tab[CR];
crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
cb_b = tables->Cb_b_tab[CB];
L = tables->L_tab[(int) *lum++];
((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
*row1++ = pixels[0]; *row1++ = pixels[1]; *row1++ = pixels[2];
L = tables->L_tab[(int) *lum++];
((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
*row1++ = pixels[0]; *row1++ = pixels[1]; *row1++ = pixels[2];
/*
* Now, do second row.
*/
L = tables->L_tab [(int) *lum2++];
((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
*row2++ = pixels[0]; *row2++ = pixels[1]; *row2++ = pixels[2];
L = tables->L_tab [(int) *lum2++];
((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
*row2++ = pixels[0]; *row2++ = pixels[1]; *row2++ = pixels[2];
}
lum = lum2;
row1 = row2;
lum2 += cols;
row2 += cols_3;
}
}
/*
*--------------------------------------------------------------
*
* Color32DitherImage --
*
* Converts image into 32 bit color (or 24-bit non-packed).
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
/*
* This is a copysoft version of the function above with ints instead
* of shorts to cause a 4-byte pixel size
*/
static void
gst_colorspace_yuv_to_rgb32(tables, lum, cb, cr, out, rows, cols)
GstColorSpaceYUVTables *tables;
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
unsigned char *out;
int cols, rows;
{
int L, CR, CB;
unsigned int *row1, *row2;
unsigned char *lum2;
int x, y;
int cr_r;
int crb_g;
int cb_b;
int cols_2 = cols>>1;
row1 = (guint32 *)out;
row2 = row1 + cols;
lum2 = lum + cols;
for (y=rows>>1; y; y--) {
for (x=cols_2; x; x--) {
CR = *cr++;
CB = *cb++;
cr_r = tables->Cr_r_tab[CR];
crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
cb_b = tables->Cb_b_tab[CB];
L = tables->L_tab[(int) *lum++];
*row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
L = tables->L_tab[(int) *lum++];
*row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
/*
* Now, do second row.
*/
L = tables->L_tab [(int) *lum2++];
*row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
L = tables->L_tab [(int) *lum2++];
*row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
}
lum = lum2;
row1 = row2;
lum2 += cols;
row2 += cols;
}
}
#ifdef HAVE_LIBMMX
static mmx_t MMX_80w = (mmx_t)(long long)0x0080008000800080LL; //dd 00080 0080h, 000800080h
static mmx_t MMX_00FFw = (mmx_t)(long long)0x00ff00ff00ff00ffLL; //dd 000FF 00FFh, 000FF00FFh
static mmx_t MMX_FF00w = (mmx_t)(long long)0xff00ff00ff00ff00LL; //dd 000FF 00FFh, 000FF00FFh
static mmx_t MMX32_Vredcoeff = (mmx_t)(long long)0x0059005900590059LL;
static mmx_t MMX32_Ubluecoeff = (mmx_t)(long long)0x0072007200720072LL;
static mmx_t MMX32_Ugrncoeff = (mmx_t)(long long)0xffeaffeaffeaffeaLL;
static mmx_t MMX32_Vgrncoeff = (mmx_t)(long long)0xffd2ffd2ffd2ffd2LL;
static void
gst_colorspace_yuv_to_bgr32_mmx(tables, lum, cr, cb, out, rows, cols)
GstColorSpaceYUVTables *tables;
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
unsigned char *out;
int cols, rows;
{
guint32 *row1 = (guint32 *)out; // 32 bit target
int cols4 = cols>>2;
int y, x;
for (y=rows>>1; y; y--) {
for (x=cols4; x; x--) {
// create Cr (result in mm1)
movd_m2r(*(mmx_t *)cb, mm1); // 0 0 0 0 v3 v2 v1 v0
pxor_r2r(mm7, mm7); // 00 00 00 00 00 00 00 00
movd_m2r(*(mmx_t *)lum, mm2); // 0 0 0 0 l3 l2 l1 l0
punpcklbw_r2r(mm7, mm1); // 0 v3 0 v2 00 v1 00 v0
punpckldq_r2r(mm1, mm1); // 00 v1 00 v0 00 v1 00 v0
psubw_m2r(MMX_80w, mm1); // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0
// create Cr_g (result in mm0)
movq_r2r(mm1, mm0); // r1 r1 r0 r0 r1 r1 r0 r0
pmullw_m2r(MMX32_Vgrncoeff, mm0); // red*-46dec=0.7136*64
pmullw_m2r(MMX32_Vredcoeff, mm1); // red*89dec=1.4013*64
psraw_i2r(6, mm0); // red=red/64
psraw_i2r(6, mm1); // red=red/64
// create L1 L2 (result in mm2,mm4)
// L2=lum+cols
movq_m2r(*(mmx_t *)(lum+cols),mm3); // 0 0 0 0 L3 L2 L1 L0
punpckldq_r2r(mm3, mm2); // L3 L2 L1 L0 l3 l2 l1 l0
movq_r2r(mm2, mm4); // L3 L2 L1 L0 l3 l2 l1 l0
pand_m2r(MMX_FF00w, mm2); // L3 0 L1 0 l3 0 l1 0
pand_m2r(MMX_00FFw, mm4); // 0 L2 0 L0 0 l2 0 l0
psrlw_i2r(8, mm2); // 0 L3 0 L1 0 l3 0 l1
// create R (result in mm6)
movq_r2r(mm2, mm5); // 0 L3 0 L1 0 l3 0 l1
movq_r2r(mm4, mm6); // 0 L2 0 L0 0 l2 0 l0
paddsw_r2r(mm1, mm5); // lum1+red:x R3 x R1 x r3 x r1
paddsw_r2r(mm1, mm6); // lum1+red:x R2 x R0 x r2 x r0
packuswb_r2r(mm5, mm5); // R3 R1 r3 r1 R3 R1 r3 r1
packuswb_r2r(mm6, mm6); // R2 R0 r2 r0 R2 R0 r2 r0
pxor_r2r(mm7, mm7); // 00 00 00 00 00 00 00 00
punpcklbw_r2r(mm5, mm6); // R3 R2 R1 R0 r3 r2 r1 r0
// create Cb (result in mm1)
movd_m2r(*(mmx_t *)cr, mm1); // 0 0 0 0 u3 u2 u1 u0
punpcklbw_r2r(mm7, mm1); // 0 u3 0 u2 00 u1 00 u0
punpckldq_r2r(mm1, mm1); // 00 u1 00 u0 00 u1 00 u0
psubw_m2r(MMX_80w, mm1); // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0
// create Cb_g (result in mm5)
movq_r2r(mm1, mm5); // u1 u1 u0 u0 u1 u1 u0 u0
pmullw_m2r(MMX32_Ugrncoeff, mm5); // blue*-109dec=1.7129*64
pmullw_m2r(MMX32_Ubluecoeff, mm1); // blue*114dec=1.78125*64
psraw_i2r(6, mm5); // blue=red/64
psraw_i2r(6, mm1); // blue=blue/64
// create G (result in mm7)
movq_r2r(mm2, mm3); // 0 L3 0 L1 0 l3 0 l1
movq_r2r(mm4, mm7); // 0 L2 0 L0 0 l2 0 l1
paddsw_r2r(mm5, mm3); // lum1+Cb_g:x G3t x G1t x g3t x g1t
paddsw_r2r(mm5, mm7); // lum1+Cb_g:x G2t x G0t x g2t x g0t
paddsw_r2r(mm0, mm3); // lum1+Cr_g:x G3 x G1 x g3 x g1
paddsw_r2r(mm0, mm7); // lum1+blue:x G2 x G0 x g2 x g0
packuswb_r2r(mm3, mm3); // G3 G1 g3 g1 G3 G1 g3 g1
packuswb_r2r(mm7, mm7); // G2 G0 g2 g0 G2 G0 g2 g0
punpcklbw_r2r(mm3, mm7); // G3 G2 G1 G0 g3 g2 g1 g0
// create B (result in mm5)
movq_r2r(mm2, mm3); // 0 L3 0 L1 0 l3 0 l1
movq_r2r(mm4, mm5); // 0 L2 0 L0 0 l2 0 l1
paddsw_r2r(mm1, mm3); // lum1+blue:x B3 x B1 x b3 x b1
paddsw_r2r(mm1, mm5); // lum1+blue:x B2 x B0 x b2 x b0
packuswb_r2r(mm3, mm3); // B3 B1 b3 b1 B3 B1 b3 b1
packuswb_r2r(mm5, mm5); // B2 B0 b2 b0 B2 B0 b2 b0
punpcklbw_r2r(mm3, mm5); // B3 B2 B1 B0 b3 b2 b1 b0
// fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
pxor_r2r(mm2, mm2); // 0 0 0 0 0 0 0 0
pxor_r2r(mm4, mm4); // 0 0 0 0 0 0 0 0
movq_r2r(mm6, mm1); // R3 R2 R1 R0 r3 r2 r1 r0
movq_r2r(mm5, mm3); // B3 B2 B1 B0 b3 b2 b1 b0
// process lower lum
punpcklbw_r2r(mm4, mm1); // 0 r3 0 r2 0 r1 0 r0
punpcklbw_r2r(mm4, mm3); // 0 b3 0 b2 0 b1 0 b0
movq_r2r(mm1, mm2); // 0 r3 0 r2 0 r1 0 r0
movq_r2r(mm3, mm0); // 0 b3 0 b2 0 b1 0 b0
punpcklwd_r2r(mm1, mm3); // 0 r1 0 b1 0 r0 0 b0
punpckhwd_r2r(mm2, mm0); // 0 r3 0 b3 0 r2 0 b2
pxor_r2r(mm2, mm2); // 0 0 0 0 0 0 0 0
movq_r2r(mm7, mm1); // G3 G2 G1 G0 g3 g2 g1 g0
punpcklbw_r2r(mm1, mm2); // g3 0 g2 0 g1 0 g0 0
punpcklwd_r2r(mm4, mm2); // 0 0 g1 0 0 0 g0 0
por_r2r(mm3, mm2); // 0 r1 g1 b1 0 r0 g0 b0
movq_r2m(mm2, *(mmx_t *)row1); // wrote out ! row1
pxor_r2r(mm2, mm2); // 0 0 0 0 0 0 0 0
punpcklbw_r2r(mm1, mm4); // g3 0 g2 0 g1 0 g0 0
punpckhwd_r2r(mm2, mm4); // 0 0 g3 0 0 0 g2 0
por_r2r(mm0, mm4); // 0 r3 g3 b3 0 r2 g2 b2
movq_r2m(mm4, *(mmx_t *)(row1+2)); // wrote out ! row1
// fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
// this can be done "destructive"
pxor_r2r(mm2, mm2); // 0 0 0 0 0 0 0 0
punpckhbw_r2r(mm2, mm6); // 0 R3 0 R2 0 R1 0 R0
punpckhbw_r2r(mm1, mm5); // G3 B3 G2 B2 G1 B1 G0 B0
movq_r2r(mm5, mm1); // G3 B3 G2 B2 G1 B1 G0 B0
punpcklwd_r2r(mm6, mm1); // 0 R1 G1 B1 0 R0 G0 B0
movq_r2m(mm1, *(mmx_t *)(row1+cols)); // wrote out ! row2
punpckhwd_r2r(mm6, mm5); // 0 R3 G3 B3 0 R2 G2 B2
movq_r2m(mm5, *(mmx_t *)(row1+cols+2)); // wrote out ! row2
lum+=4;
cr+=2;
cb+=2;
row1 +=4;
}
lum += cols;
row1 += cols;
}
emms();
}
#endif

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef __YUV2RGB_H__
#define __YUV2RGB_H__
typedef struct _GstColorSpaceYUVTables GstColorSpaceYUVTables;
struct _GstColorSpaceYUVTables {
int gammaCorrectFlag;
double gammaCorrect;
int chromaCorrectFlag;
double chromaCorrect;
int *L_tab, *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
/*
* We define tables that convert a color value between -256 and 512
* into the R, G and B parts of the pixel. The normal range is 0-255.
**/
long *r_2_pix;
long *g_2_pix;
long *b_2_pix;
};
#define CB_BASE 1
#define CR_BASE (CB_BASE*CB_RANGE)
#define LUM_BASE (CR_BASE*CR_RANGE)
#define Min(x,y) (((x) < (y)) ? (x) : (y))
#define Max(x,y) (((x) > (y)) ? (x) : (y))
#define GAMMA_CORRECTION(x) ((int)(pow((x) / 255.0, 1.0 / gammaCorrect) * 255.0))
#define CHROMA_CORRECTION256(x) ((x) >= 128 \
? 128 + Min(127, (int)(((x) - 128.0) * chromaCorrect)) \
: 128 - Min(128, (int)((128.0 - (x)) * chromaCorrect)))
#define CHROMA_CORRECTION128(x) ((x) >= 0 \
? Min(127, (int)(((x) * chromaCorrect))) \
: Max(-128, (int)(((x) * chromaCorrect))))
#define CHROMA_CORRECTION256D(x) ((x) >= 128 \
? 128.0 + Min(127.0, (((x) - 128.0) * chromaCorrect)) \
: 128.0 - Min(128.0, (((128.0 - (x)) * chromaCorrect))))
#define CHROMA_CORRECTION128D(x) ((x) >= 0 \
? Min(127.0, ((x) * chromaCorrect)) \
: Max(-128.0, ((x) * chromaCorrect)))
#endif

View file

@ -1,188 +0,0 @@
.globl mmx_80w
.data
.align 4
.type mmx_80w,@object
.size mmx_80w,8
mmx_80w:
.long 8388736
.long 8388736
.globl mmx_10w
.align 4
.type mmx_10w,@object
.size mmx_10w,8
mmx_10w:
.long 269488144
.long 269488144
.globl mmx_00ffw
.align 4
.type mmx_00ffw,@object
.size mmx_00ffw,8
mmx_00ffw:
.long 16711935
.long 16711935
.globl mmx_Y_coeff
.align 4
.type mmx_Y_coeff,@object
.size mmx_Y_coeff,8
mmx_Y_coeff:
.long 624895295
.long 624895295
.globl mmx_U_green
.align 4
.type mmx_U_green,@object
.size mmx_U_green,8
mmx_U_green:
.long -209849475
.long -209849475
.globl mmx_U_blue
.align 4
.type mmx_U_blue,@object
.size mmx_U_blue,8
mmx_U_blue:
.long 1083392147
.long 1083392147
.globl mmx_V_red
.align 4
.type mmx_V_red,@object
.size mmx_V_red,8
mmx_V_red:
.long 856830738
.long 856830738
.globl mmx_V_green
.align 4
.type mmx_V_green,@object
.size mmx_V_green,8
mmx_V_green:
.long -436410884
.long -436410884
.globl mmx_redmask
.align 4
.type mmx_redmask,@object
.size mmx_redmask,8
mmx_redmask:
.long -117901064
.long -117901064
.globl mmx_grnmask
.align 4
.type mmx_grnmask,@object
.size mmx_grnmask,8
mmx_grnmask:
.long -50529028
.long -50529028
.text
.align 4
.globl gst_colorspace_yuv_to_bgr16_mmx
.type gst_colorspace_yuv_to_bgr16_mmx,@function
gst_colorspace_yuv_to_bgr16_mmx:
subl $8,%esp
pushl %ebp
pushl %edi
pushl %esi
movl 28(%esp),%edi
movl 32(%esp),%ecx
movl 36(%esp),%edx
movl $1,%ebp
movl 48(%esp),%esi
sarl $1,%esi
movl %esi,16(%esp)
pxor %mm4, %mm4 # zero mm4
movl %esi,12(%esp)
sarl $2,12(%esp)
movl 40(%esp),%esi
.p2align 4,,7
.L68:
movd (%ecx), %mm0 # Load 4 Cb 00 00 00 00 00 u3 u2 u1 u0
movd (%edx), %mm1 # Load 4 Cr 00 00 00 00 00 v2 v1 v0
movq (%edi), %mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
movl 12(%esp),%eax
.p2align 4,,7
.L74:
punpcklbw %mm4, %mm0 # scatter 4 Cb 00 u3 00 u2 00 u1 00 u0
punpcklbw %mm4, %mm1 # scatter 4 Cr 00 v3 00 v2 00 v1 00 v0
psubsw mmx_80w, %mm0 # Cb -= 128
psubsw mmx_80w, %mm1 # Cr -= 128
psllw $3, %mm0 # Promote precision
psllw $3, %mm1 # Promote precision
movq %mm0, %mm2 # Copy 4 Cb 00 u3 00 u2 00 u1 00 u0
movq %mm1, %mm3 # Copy 4 Cr 00 v3 00 v2 00 v1 00 v0
pmulhw mmx_U_green, %mm2 # Mul Cb with green coeff -> Cb green
pmulhw mmx_V_green, %mm3 # Mul Cr with green coeff -> Cr green
pmulhw mmx_U_blue, %mm0 # Mul Cb -> Cblue 00 b3 00 b2 00 b1 00 b0
pmulhw mmx_V_red, %mm1 # Mul Cr -> Cred 00 r3 00 r2 00 r1 00 r0
paddsw %mm3, %mm2 # Cb green + Cr green -> Cgreen
psubusb mmx_10w, %mm6 # Y -= 16
movq %mm6, %mm7 # Copy 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
pand mmx_00ffw, %mm6 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0
psrlw $8, %mm7 # get Y odd 00 Y7 00 Y5 00 Y3 00 Y1
psllw $3, %mm6 # Promote precision
psllw $3, %mm7 # Promote precision
pmulhw mmx_Y_coeff, %mm6 # Mul 4 Y even 00 y6 00 y4 00 y2 00 y0
pmulhw mmx_Y_coeff, %mm7 # Mul 4 Y odd 00 y7 00 y5 00 y3 00 y1
movq %mm0, %mm3 # Copy Cblue
movq %mm1, %mm4 # Copy Cred
movq %mm2, %mm5 # Copy Cgreen
paddsw %mm6, %mm0 # Y even + Cblue 00 B6 00 B4 00 B2 00 B0
paddsw %mm7, %mm3 # Y odd + Cblue 00 B7 00 B5 00 B3 00 B1
paddsw %mm6, %mm1 # Y even + Cred 00 R6 00 R4 00 R2 00 R0
paddsw %mm7, %mm4 # Y odd + Cred 00 R7 00 R5 00 R3 00 R1
paddsw %mm6, %mm2 # Y even + Cgreen 00 G6 00 G4 00 G2 00 G0
paddsw %mm7, %mm5 # Y odd + Cgreen 00 G7 00 G5 00 G3 00 G1
packuswb %mm0, %mm0 # B6 B4 B2 B0 | B6 B4 B2 B0
packuswb %mm1, %mm1 # R6 R4 R2 R0 | R6 R4 R2 R0
packuswb %mm2, %mm2 # G6 G4 G2 G0 | G6 G4 G2 G0
packuswb %mm3, %mm3 # B7 B5 B3 B1 | B7 B5 B3 B1
packuswb %mm4, %mm4 # R7 R5 R3 R1 | R7 R5 R3 R1
packuswb %mm5, %mm5 # G7 G5 G3 G1 | G7 G5 G3 G1
punpcklbw %mm3, %mm0 # B7 B6 B5 B4 B3 B2 B1 B0
punpcklbw %mm4, %mm1 # R7 R6 R5 R4 R3 R2 R1 R0
punpcklbw %mm5, %mm2 # G7 G6 G5 G4 G3 G2 G1 G0
pand mmx_redmask, %mm0 # b7b6b5b4 b3_0_0_0 b7b6b5b4 b3_0_0_0
pand mmx_grnmask, %mm2 # g7g6g5g4 g3g2_0_0 g7g6g5g4 g3g2_0_0
pand mmx_redmask, %mm1 # r7r6r5r4 r3_0_0_0 r7r6r5r4 r3_0_0_0
psrlw $3,%mm0 #0_0_0_b7 b6b5b4b3 0_0_0_b7 b6b5b4b3
pxor %mm4, %mm4 # zero mm4
movq %mm0, %mm5 # Copy B7-B0
movq %mm2, %mm7 # Copy G7-G0
punpcklbw %mm4, %mm2 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0
punpcklbw %mm1, %mm0 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3
psllw $3,%mm2 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0
por %mm2, %mm0 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3
movq 8(%edi), %mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
movq %mm0, (%esi) # store pixel 0-3
punpckhbw %mm4, %mm7 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0
punpckhbw %mm1, %mm5 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3
psllw $3,%mm7 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0
movd 4(%ecx), %mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0
por %mm7, %mm5 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3
movd 4(%edx), %mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0
movq %mm5, 8(%esi) # store pixel 4-7
addl $8,%edi
addl $4,%ecx
addl $4,%edx
addl $16,%esi
decl %eax
jnz .L74
.L72:
xorl $1,%ebp
jne .L76
subl 16(%esp),%ecx
subl 16(%esp),%edx
.L76:
subl $1,44(%esp)
jnz .L68
emms
popl %esi
popl %edi
popl %ebp
addl $8,%esp
ret

View file

@ -1,7 +0,0 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

View file

@ -1,19 +0,0 @@
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libgstvideoscale.la
if HAVE_CPU_I386
SCALER = gstscale_x86.c gstscale_x86_asm.s
else
SCALER =
endif
libgstvideoscale_la_SOURCES = gstvideoscale.c $(SCALER)
libgstvideoscaleincludedir = $(includedir)/gst/libs/gstvideoscale
libgstvideoscaleinclude_HEADERS = gstvideoscale.h
noinst_HEADERS = gstscale_x86.h
#CFLAGS += -S -O1 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
CFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(GST_CFLAGS) $(XML_CFLAGS) -O5 -fomit-frame-pointer -ffast-math

View file

@ -1,80 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
//#define DEBUG_ENABLED
#include "gstvideoscale.h"
/* scalers */
void gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp);
void gst_videoscale_scale_nearest_x86 (GstVideoScale *scale,
unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh);
#define PREFIX16 0x66
#define STORE_BYTE 0xAA
#define STORE_WORD 0xAB
#define LOAD_BYTE 0xAC
#define LOAD_WORD 0xAD
#define RETURN 0xC3
void
gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp)
{
int i;
int pos, inc;
unsigned char *eip;
unsigned char load, store;
GST_DEBUG (0,"videoscale: setup scaling %p\n", copy_row);
switch (bpp) {
case 1:
load = LOAD_BYTE;
store = STORE_BYTE;
break;
case 2:
case 4:
load = LOAD_WORD;
store = STORE_WORD;
break;
default:
return;
}
pos = 0x10000;
inc = (src_w << 16) / dst_w;
eip = copy_row;
for ( i=0; i<dst_w; ++i ) {
while ( pos >= 0x10000L ) {
if ( bpp == 2 ) {
*eip++ = PREFIX16;
}
*eip++ = load;
pos -= 0x10000L;
}
if ( bpp == 2 ) {
*eip++ = PREFIX16;
}
*eip++ = store;
pos += inc;
}
*eip++ = RETURN;
GST_DEBUG (0,"scaler start/end %p %p %p\n", copy_row, eip, (void*)(eip-copy_row));
}

View file

@ -1,30 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_VIDEOSCALE__X86_H__
#define __GST_VIDEOSCALE__X86_H__
/* scalers */
void gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp);
void gst_videoscale_scale_nearest_x86 (GstVideoScale *scale,
unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh);
#endif /* __GST_VIDEOSCALE__X86_H__ */

View file

@ -1,53 +0,0 @@
.text
.align 4
.globl gst_videoscale_scale_nearest_x86
.type gst_videoscale_scale_nearest_x86,@function
gst_videoscale_scale_nearest_x86:
subl $8,%esp
pushl %ebp
pushl %edi
pushl %esi
movl 28(%esp),%ebp
movl 24(%esp),%edx
addl $28,%edx
movl 24(%esp),%eax
movl %edx,8220(%eax)
movl $65536,12(%esp)
movl 40(%esp),%ecx
sall $16,%ecx
movl %ecx,%eax
cltd
idivl 48(%esp)
movl %eax,%ecx
movl 48(%esp),%eax
movl %eax,16(%esp)
testl %eax,%eax
jle .L92
jmp .L100
.p2align 4,,7
.L97:
addl 36(%esp),%ebp
addl $-65536,12(%esp)
.L100:
cmpl $65536,12(%esp)
jg .L97
movl 32(%esp),%edi
movl %ebp,%esi
movl 24(%esp),%edx
movl 8220(%edx), %eax
call *%eax
movl 44(%esp),%eax
addl %eax,32(%esp)
addl %ecx,12(%esp)
decl 16(%esp)
cmpl $0,16(%esp)
jg .L100
.L92:
popl %esi
popl %edi
popl %ebp
addl $8,%esp
ret

View file

@ -1,393 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
//#define DEBUG_ENABLED
#include <stdlib.h>
#include <math.h>
#include "config.h"
#include "gstvideoscale.h"
#ifdef HAVE_CPU_I386
#include "gstscale_x86.h"
#endif
static void gst_videoscale_scale_yuv (GstVideoScale *scale, unsigned char *src, unsigned char *dest);
static void gst_videoscale_scale_rgb (GstVideoScale *scale, unsigned char *src, unsigned char *dest);
/* scalers */
static void gst_videoscale_scale_nearest (GstVideoScale *scale, unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh);
static void gst_videoscale_scale_plane_slow (GstVideoScale *scale, unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh);
static void gst_videoscale_scale_point_sample (GstVideoScale *scale, unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh);
/* filters */
static unsigned char gst_videoscale_bilinear (unsigned char *src, double x, double y, int sw, int sh);
static unsigned char gst_videoscale_bicubic (unsigned char *src, double x, double y, int sw, int sh);
GstVideoScale*
gst_videoscale_new (gint sw, gint sh, gint dw, gint dh,
GstColorSpaceType format, GstVideoScaleMethod method)
{
GstVideoScale *new = g_malloc(sizeof(GstVideoScale));
new->source_width = sw;
new->source_height = sh;
new->dest_width = dw;
new->dest_height = dh;
new->format = format;
new->method = method;
switch (format) {
case GST_COLORSPACE_YUV420P:
new->scale = gst_videoscale_scale_yuv;
new->scale_bytes = 1;
break;
case GST_COLORSPACE_RGB555:
case GST_COLORSPACE_RGB565:
case GST_COLORSPACE_BGR555:
case GST_COLORSPACE_BGR565:
new->scale = gst_videoscale_scale_rgb;
new->scale_bytes = 2;
break;
case GST_COLORSPACE_RGB32:
case GST_COLORSPACE_BGR32:
new->scale = gst_videoscale_scale_rgb;
new->scale_bytes = 4;
break;
default:
g_print("videoscale: unsupported video format %d\n", format);
g_free(new);
return NULL;
}
switch (method) {
case GST_VIDEOSCALE_POINT_SAMPLE:
new->scaler = gst_videoscale_scale_point_sample;
GST_DEBUG (0,"videoscale: scaling method POINT_SAMPLE\n");
break;
case GST_VIDEOSCALE_NEAREST:
#ifdef HAVE_CPU_I386
gst_videoscale_generate_rowbytes_x86 (new->copy_row, sw, dw, new->scale_bytes);
new->scaler = gst_videoscale_scale_nearest_x86;
#else
new->scaler = gst_videoscale_scale_nearest;
#endif
GST_DEBUG (0,"videoscale: scaling method NEAREST\n");
break;
case GST_VIDEOSCALE_BILINEAR:
new->scaler = gst_videoscale_scale_plane_slow;
new->filter = gst_videoscale_bilinear;
GST_DEBUG (0,"videoscale: scaling method BILINEAR\n");
break;
case GST_VIDEOSCALE_BICUBIC:
new->scaler = gst_videoscale_scale_plane_slow;
new->filter = gst_videoscale_bicubic;
GST_DEBUG (0,"videoscale: scaling method BICUBIC\n");
break;
default:
g_print("videoscale: unsupported scaling method %d\n", method);
g_free(new);
return NULL;
}
return new;
}
void
gst_videoscale_destroy (GstVideoScale *scale)
{
g_free(scale);
}
static void
gst_videoscale_scale_rgb (GstVideoScale *scale, unsigned char *src, unsigned char *dest)
{
int sw = scale->source_width;
int sh = scale->source_height;
int dw = scale->dest_width;
int dh = scale->dest_height;
GST_DEBUG (0,"videoscale: scaling RGB %dx%d to %dx%d\n", sw, sh, dw, dh);
switch (scale->scale_bytes) {
case 2:
dw = ((dw + 1) & ~1) << 1;
sw = sw<<1;
break;
case 4:
dw = ((dw + 2) & ~3) << 2;
sw = sw<<2;
break;
default:
break;
}
GST_DEBUG (0,"videoscale: %p %p\n", src, dest);
scale->scaler(scale, src, dest, sw, sh, dw, dh);
}
static void
gst_videoscale_scale_yuv (GstVideoScale *scale, unsigned char *src, unsigned char *dest)
{
int sw = scale->source_width;
int sh = scale->source_height;
int dw = scale->dest_width;
int dh = scale->dest_height;
GST_DEBUG (0,"videoscale: scaling YUV420P %dx%d to %dx%d\n", sw, sh, dw, dh);
scale->scaler(scale, src, dest, sw, sh, dw, dh);
src += sw*sh;
dest += dw*dh;
dh = dh>>1;
dw = dw>>1;
sh = sh>>1;
sw = sw>>1;
scale->scaler(scale, src, dest, sw, sh, dw, dh);
src += sw*sh;
dest += dw*dh;
scale->scaler(scale, src, dest, sw, sh, dw, dh);
}
#define RC(x,y) *(src+(int)(x)+(int)((y)*sw))
static unsigned char
gst_videoscale_bilinear (unsigned char *src, double x, double y, int sw, int sh)
{
int j=floor(x);
int k=floor(y);
double a=x-j;
double b=y-k;
double dest;
int color;
GST_DEBUG(0,"videoscale: scaling bilinear %f %f %dx%d\n", x, y, sw, sh);
dest=(1-a)*(1-b)*RC(j,k)+
a*(1-b)*RC(j+1,k);
k = MIN(sh-1, k);
dest+= b*(1-a)*RC(j,k+1)+
a*b*RC(j+1,k+1);
color=rint(dest);
if (color<0) color=abs(color); // cannot have negative values !
//if (color<0) color=0; // cannot have negative values !
if (color>255) color=255;
return (unsigned char) color;
}
static unsigned char
gst_videoscale_bicubic (unsigned char *src, double x, double y, int sw, int sh)
{
int j=floor(x);
int k=floor(y), k2;
double a=x-j;
double b=y-k;
double dest;
int color;
double t1, t2, t3, t4;
double a1, a2, a3, a4;
GST_DEBUG (0,"videoscale: scaling bicubic %dx%d\n", sw, sh);
a1 = -a*(1-a)*(1-a);
a2 = (1-2*a*a+a*a*a);
a3 = a*(1+a-a*a);
a4 = a*a*(1-a);
k2 = MAX(0, k-1);
t1=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2);
t2=a1*RC(j-1,k)+ a2*RC(j,k)+ a3*RC(j+1,k)- a4*RC(j+2,k);
k2 = MIN(sh, k+1);
t3=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2);
k2 = MIN(sh, k+2);
t4=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2);
dest= -b*(1-b)*(1-b)*t1+ (1-2*b*b+b*b*b)*t2+ b*(1+b-b*b)*t3+ b*b*(b-1)*t4;
color=rint(dest);
if (color<0) color=abs(color); // cannot have negative values !
if (color>255) color=255;
return (unsigned char) color;
}
static void
gst_videoscale_scale_plane_slow (GstVideoScale *scale, unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh)
{
double zoomx = ((double)dw)/(double)sw;
double zoomy = ((double)dh)/(double)sh;
double xr, yr;
int x, y;
GST_DEBUG (0,"videoscale: scale plane slow %dx%d %dx%d %g %g %p %p\n", sw, sh, dw, dh, zoomx, zoomy, src, dest);
for (y=0; y<dh; y++) {
yr = ((double)y)/zoomy;
for (x=0; x<dw; x++) {
xr = ((double)x)/zoomx;
GST_DEBUG (0,"videoscale: scale plane slow %g %g %p\n", xr, yr, (src+(int)(x)+(int)((y)*sw)));
if (floor(xr) == xr && floor(yr) == yr){
GST_DEBUG (0,"videoscale: scale plane %g %g %p %p\n", xr, yr, (src+(int)(x)+(int)((y)*sw)), dest);
*dest++ = RC(xr, yr);
}
else {
*dest++ = scale->filter(src, xr, yr, sw, sh);
//*dest++ = gst_videoscale_bicubic(src, xr, yr, sw, sh);
}
}
}
}
static void
gst_videoscale_scale_point_sample (GstVideoScale *scale, unsigned char *src, unsigned char *dest,
int sw, int sh, int dw, int dh)
{
int ypos, yinc, y;
int xpos, xinc, x;
int sum, xcount, ycount, loop;
unsigned char *srcp, *srcp2;
GST_DEBUG (0,"videoscale: scaling nearest point sample %p %p %d\n", src, dest, dw);
ypos = 0x10000;
yinc = (sh<<16)/dh;
xinc = (sw<<16)/dw;
for (y = dh; y; y--) {
ycount = 1;
srcp = src;
while (ypos >0x10000) {
ycount++;
ypos-=0x10000;
src += sw;
}
xpos = 0x10000;
for ( x=dw; x; x-- ) {
xcount = 0;
sum=0;
while ( xpos >= 0x10000L ) {
loop = ycount;
srcp2 = srcp;
while (loop--) {
sum += *srcp2;
srcp2 += sw;
}
srcp++;
xcount++;
xpos -= 0x10000L;
}
*dest++ = sum/(xcount*ycount);
xpos += xinc;
}
ypos += yinc;
}
}
static void
gst_videoscale_scale_nearest (GstVideoScale *scale,
unsigned char *src,
unsigned char *dest,
int sw, int sh, int dw, int dh)
{
int ypos, yinc, y;
int xpos, xinc, x;
GST_DEBUG (0, "videoscale: scaling nearest %p %p %d %d\n", src, dest, dw, scale->scale_bytes);
ypos = 0x10000;
yinc = (sh<<16)/dh;
xinc = (sw<<16)/dw;
for (y = dh; y; y--) {
while (ypos >0x10000) {
ypos-=0x10000;
src += sw;
}
xpos = 0x10000;
switch (scale->scale_bytes) {
case 4:
{
guint32 *destp = (guint32 *)dest;
guint32 *srcp = (guint32 *)src;
for ( x=dw>>2; x; x-- ) {
while ( xpos >= 0x10000L ) {
srcp++;
xpos -= 0x10000L;
}
*destp++ = *srcp;
xpos += xinc;
}
break;
}
case 2:
{
guint16 *destp = (guint16 *)dest;
guint16 *srcp = (guint16 *)src;
for ( x=dw>>1; x; x-- ) {
while ( xpos >= 0x10000L ) {
srcp++;
xpos -= 0x10000L;
}
*destp++ = *srcp;
xpos += xinc;
}
break;
}
case 1:
{
guchar *destp = dest;
guchar *srcp = src;
for ( x=dw; x; x-- ) {
while ( xpos >= 0x10000L ) {
srcp++;
xpos -= 0x10000L;
}
*destp++ = *srcp;
xpos += xinc;
}
}
}
dest += dw;
ypos += yinc;
}
}

View file

@ -1,57 +0,0 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_VIDEOSCALE_H__
#define __GST_VIDEOSCALE_H__
#include <gst/gst.h>
#include <libs/colorspace/gstcolorspace.h>
typedef enum {
GST_VIDEOSCALE_POINT_SAMPLE,
GST_VIDEOSCALE_NEAREST,
GST_VIDEOSCALE_BILINEAR,
GST_VIDEOSCALE_BICUBIC
} GstVideoScaleMethod;
typedef struct _GstVideoScale GstVideoScale;
typedef void (*GstVideoScaleScaler) (GstVideoScale *scale, guchar *src, guchar *dest);
struct _GstVideoScale {
guint source_width;
guint source_height;
guint dest_width;
guint dest_height;
GstColorSpaceType format;
GstVideoScaleMethod method;
guint scale_bytes;
/* private */
guchar copy_row[8192];
guchar *temp;
GstVideoScaleScaler scale;
void (*scaler) (GstVideoScale *scale, guchar *src, guchar *dest, gint sw, gint sh, gint dw, gint dh);
guchar (*filter) (guchar *src, gdouble x, gdouble y, gint sw, gint sh);
};
GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSpaceType format, GstVideoScaleMethod method);
#define gst_videoscale_scale(scaler, src, dest) (scaler)->scale((scaler), (src), (dest))
void gst_videoscale_destroy(GstVideoScale *scale);
#endif /* __GST_VIDEOSCALE_H__ */

View file

@ -1,7 +0,0 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

View file

@ -1,14 +0,0 @@
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libwinloader.la
# compiler manages to screw something up here... must reduce optimizations
CFLAGS += -O0 -funroll-loops
libwinloader_la_SOURCES = win32.c driver.c elfdll.c ext.c module.c \
pe_image.c pe_resource.c registry.c resource.c stubs.s vfl.c afl.c
noinst_HEADERS = wineacm.h win32.h registry.h avifmt.h
DEFINES=-rdynamic -fPIC -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf
CFLAGS += $(DEFINES)

View file

@ -1,759 +0,0 @@
/**************************************************************************
This file will contain an interface to ACM drivers.
Its content will be based mainly on wine/dlls/msacm32
actually, for audio decompression only the following functions
are needed:
acmStreamOpen ( takes formats of src and dest, returns stream handle )
acmStreamPrepareHeader ( takes stream handler and info on data )
acmStreamConvert ( the same as PrepareHeader )
acmStreamUnprepareHeader
acmStreamClose
acmStreamSize
maybe acmStreamReset
In future I'll also add functions for format enumeration,
but not right now.
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <wine/winbase.h>
#include <wine/windef.h>
#include <wine/winuser.h>
#include <wine/vfw.h>
#include <wine/winestring.h>
#include <wine/driver.h>
#include <wine/winerror.h>
#include <wine/msacm.h>
#include <wine/msacmdrv.h>
#include "wineacm.h"
#pragma pack(1)
#define OpenDriverA DrvOpen
extern HDRVR VFWAPI DrvOpen(long);
#define CloseDriver DrvClose
extern HDRVR VFWAPI DrvClose(long);
static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
{
return (PWINE_ACMSTREAM)has;
}
/***********************************************************************
* acmDriverAddA (MSACM32.2)
*/
MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
{
if (!phadid)
return MMSYSERR_INVALPARAM;
/* Check if any unknown flags */
if (fdwAdd &
~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
ACM_DRIVERADDF_GLOBAL))
return MMSYSERR_INVALFLAG;
/* Check if any incompatible flags */
if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
(fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
return MMSYSERR_INVALFLAG;
/* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
* LoadDriver on it, to be sure we can call SendDriverMessage on the
* hDrvr handle.
*/
*phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
/* FIXME: lParam, dwPriority and fdwAdd ignored */
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverClose (MSACM32.4)
*/
MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
{
PWINE_ACMDRIVER p;
PWINE_ACMDRIVER* tp;
if (fdwClose)
return MMSYSERR_INVALFLAG;
p = MSACM_GetDriver(had);
if (!p)
return MMSYSERR_INVALHANDLE;
for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
if (*tp == p) {
*tp = (*tp)->pNextACMDriver;
break;
}
}
if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
CloseDriver(p->hDrvr);
HeapFree(MSACM_hHeap, 0, p);
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverEnum (MSACM32.7)
*/
MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
{
PWINE_ACMDRIVERID p;
DWORD fdwSupport;
if (!fnCallback) {
return MMSYSERR_INVALPARAM;
}
if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
return MMSYSERR_INVALFLAG;
}
for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
if (!p->bEnabled) {
if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
else
continue;
}
(*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
}
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverID (MSACM32.8)
*/
MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
{
PWINE_ACMOBJ pao;
pao = MSACM_GetObj(hao);
if (!pao)
return MMSYSERR_INVALHANDLE;
if (!phadid)
return MMSYSERR_INVALPARAM;
if (fdwDriverID)
return MMSYSERR_INVALFLAG;
*phadid = (HACMDRIVERID) pao->pACMDriverID;
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverMessage (MSACM32.9)
* FIXME
* Not implemented
*/
LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
if (!pad)
return MMSYSERR_INVALPARAM;
/* FIXME: Check if uMsg legal */
if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
return MMSYSERR_NOTSUPPORTED;
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverOpen (MSACM32.10)
*/
MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
{
PWINE_ACMDRIVERID padid;
PWINE_ACMDRIVER pad;
ICOPEN icopen;
HDRVR hdrv;
TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
if (!phad)
return MMSYSERR_INVALPARAM;
padid = MSACM_GetDriverID(hadid);
if (!padid)
return MMSYSERR_INVALHANDLE;
if (fdwOpen)
return MMSYSERR_INVALFLAG;
pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
if (!pad) return MMSYSERR_NOMEM;
pad->obj.pACMDriverID = padid;
icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
icopen.fccHandler = (long)padid->pszFileName;
icopen.dwSize = sizeof(ICOPEN);
icopen.dwFlags = 0;
if (!padid->hInstModule)
pad->hDrvr = OpenDriverA((long)&icopen);
else
pad->hDrvr = padid->hInstModule;
if (!pad->hDrvr) {
HeapFree(MSACM_hHeap, 0, pad);
return MMSYSERR_ERROR;
}
pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
/* insert new pad at beg of list */
pad->pNextACMDriver = padid->pACMDriverList;
padid->pACMDriverList = pad;
/* FIXME: Create a WINE_ACMDRIVER32 */
*phad = (HACMDRIVER)pad;
return MMSYSERR_NOERROR;
}
/***********************************************************************
* acmDriverRemove (MSACM32.12)
*/
MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
{
PWINE_ACMDRIVERID padid;
padid = MSACM_GetDriverID(hadid);
if (!padid)
return MMSYSERR_INVALHANDLE;
if (fdwRemove)
return MMSYSERR_INVALFLAG;
MSACM_UnregisterDriver(padid);
return MMSYSERR_NOERROR;
}
/**********************************************************************/
HANDLE MSACM_hHeap = (HANDLE) NULL;
PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
/***********************************************************************
* MSACM_RegisterDriver32()
*/
PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName,
HINSTANCE hinstModule)
//
// File names are stored in driver.c. I reuse this variable to store driver ID
// in it. If it's <0x10000, it is primary codec for corresponding format.
//
{
PWINE_ACMDRIVERID padid;
TRACE("('%s', '%x', 0x%08x)\n", pszDriverAlias, pszFileName, hinstModule);
padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
padid->pszDriverAlias = (char*)malloc(strlen(pszDriverAlias)+1);
strcpy(padid->pszDriverAlias, pszDriverAlias);
// 1~strdup(pszDriverAlias);
padid->pszFileName = pszFileName;
padid->hInstModule = hinstModule;
padid->bEnabled = TRUE;
padid->pACMDriverList = NULL;
padid->pNextACMDriverID = NULL;
padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
if (MSACM_pLastACMDriverID)
MSACM_pLastACMDriverID->pNextACMDriverID = padid;
MSACM_pLastACMDriverID = padid;
if (!MSACM_pFirstACMDriverID)
MSACM_pFirstACMDriverID = padid;
return padid;
}
/***********************************************************************
* MSACM_RegisterAllDrivers32()
*/
void MSACM_RegisterAllDrivers(void)
{
LPSTR pszBuffer;
DWORD dwBufferLength;
if (MSACM_pFirstACMDriverID)
return;
MSACM_RegisterDriver("divxa32", (LPSTR)0x161, 0);
MSACM_RegisterDriver("msadp32", (LPSTR)0x2, 0);
MSACM_RegisterDriver("l3codeca", (LPSTR)0x55, 0);
}
/***********************************************************************
* MSACM_UnregisterDriver32()
*/
PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
{
PWINE_ACMDRIVERID pNextACMDriverID;
while (p->pACMDriverList)
acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
if (p->pszDriverAlias)
HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
// if (p->pszFileName)
// HeapFree(MSACM_hHeap, 0, p->pszFileName);
if (p == MSACM_pFirstACMDriverID)
MSACM_pFirstACMDriverID = p->pNextACMDriverID;
if (p == MSACM_pLastACMDriverID)
MSACM_pLastACMDriverID = p->pPrevACMDriverID;
if (p->pPrevACMDriverID)
p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
if (p->pNextACMDriverID)
p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
pNextACMDriverID = p->pNextACMDriverID;
HeapFree(MSACM_hHeap, 0, p);
return pNextACMDriverID;
}
/***********************************************************************
* MSACM_UnregisterAllDrivers32()
* FIXME
* Where should this function be called?
*/
void MSACM_UnregisterAllDrivers(void)
{
PWINE_ACMDRIVERID p;
for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
}
/***********************************************************************
* MSACM_GetDriverID32()
*/
PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
{
return (PWINE_ACMDRIVERID)hDriverID;
}
/***********************************************************************
* MSACM_GetDriver32()
*/
PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
{
return (PWINE_ACMDRIVER)hDriver;
}
/***********************************************************************
* MSACM_GetObj32()
*/
PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
{
return (PWINE_ACMOBJ)hObj;
}
/***********************************************************************
* acmStreamOpen (MSACM32.40)
*/
MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
DWORD dwInstance, DWORD fdwOpen)
{
PWINE_ACMSTREAM was;
PWINE_ACMDRIVER wad;
MMRESULT ret;
int wfxSrcSize;
int wfxDstSize;
TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
#define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
wfxSrcSize = SIZEOF_WFX(pwfxSrc);
wfxDstSize = SIZEOF_WFX(pwfxDst);
#undef SIZEOF_WFX
was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
if (was == NULL)
return MMSYSERR_NOMEM;
was->drvInst.cbStruct = sizeof(was->drvInst);
was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
if (pwfltr) {
was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
} else {
was->drvInst.pwfltr = NULL;
}
was->drvInst.dwCallback = dwCallback;
was->drvInst.dwInstance = dwInstance;
was->drvInst.fdwOpen = fdwOpen;
was->drvInst.fdwDriver = 0L;
was->drvInst.dwDriver = 0L;
was->drvInst.has = (HACMSTREAM)was;
if (had) {
if (!(wad = MSACM_GetDriver(had))) {
ret = MMSYSERR_INVALPARAM;
goto errCleanUp;
}
was->obj.pACMDriverID = wad->obj.pACMDriverID;
was->pDrv = wad;
was->hAcmDriver = 0; /* not to close it in acmStreamClose */
ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
if (ret != MMSYSERR_NOERROR)
goto errCleanUp;
} else {
PWINE_ACMDRIVERID wadi;
short drv_tag;
ret = ACMERR_NOTPOSSIBLE;
/* if(pwfxSrc->wFormatTag==1)//compression
drv_tag=pwfxDst->wFormatTag;
else
if(pwfxDst->wFormatTag==1)//decompression
drv_tag=pwfxSrc->wFormatTag;
else
goto errCleanUp;
ret=acmDriverOpen2(drv_tag);
if (ret == MMSYSERR_NOERROR) {
if ((wad = MSACM_GetDriver(had)) != 0) {
was->obj.pACMDriverID = wad->obj.pACMDriverID;
was->pDrv = wad;
was->hAcmDriver = had;
ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
if (ret == MMSYSERR_NOERROR) {
if (fdwOpen & ACM_STREAMOPENF_QUERY) {
acmDriverClose(had, 0L);
}
break;
}
}
acmDriverClose(had, 0L);*/
if(MSACM_pFirstACMDriverID==NULL)
MSACM_RegisterAllDrivers();
for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) {
ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
if (ret == MMSYSERR_NOERROR) {
if ((wad = MSACM_GetDriver(had)) != 0) {
was->obj.pACMDriverID = wad->obj.pACMDriverID;
was->pDrv = wad;
was->hAcmDriver = had;
ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
if (ret == MMSYSERR_NOERROR) {
if (fdwOpen & ACM_STREAMOPENF_QUERY) {
acmDriverClose(had, 0L);
}
break;
}
}
// no match, close this acm driver and try next one
acmDriverClose(had, 0L);
}
}
if (ret != MMSYSERR_NOERROR) {
ret = ACMERR_NOTPOSSIBLE;
goto errCleanUp;
}
}
ret = MMSYSERR_NOERROR;
if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
if (phas)
*phas = (HACMSTREAM)was;
TRACE("=> (%d)\n", ret);
return ret;
}
errCleanUp:
if (phas)
*phas = (HACMSTREAM)0;
HeapFree(MSACM_hHeap, 0, was);
TRACE("=> (%d)\n", ret);
return ret;
}
MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
{
PWINE_ACMSTREAM was;
MMRESULT ret;
TRACE("(0x%08x, %ld)\n", has, fdwClose);
if ((was = ACM_GetStream(has)) == NULL) {
return MMSYSERR_INVALHANDLE;
}
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
if (ret == MMSYSERR_NOERROR) {
if (was->hAcmDriver)
acmDriverClose(was->hAcmDriver, 0L);
HeapFree(MSACM_hHeap, 0, was);
}
TRACE("=> (%d)\n", ret);
return ret;
}
/***********************************************************************
* acmStreamConvert (MSACM32.38)
*/
MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
DWORD fdwConvert)
{
PWINE_ACMSTREAM was;
MMRESULT ret = MMSYSERR_NOERROR;
PACMDRVSTREAMHEADER padsh;
TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
if ((was = ACM_GetStream(has)) == NULL)
return MMSYSERR_INVALHANDLE;
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
return MMSYSERR_INVALPARAM;
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
return ACMERR_UNPREPARED;
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
* size. some fields are private to msacm internals, and are exposed
* in ACMSTREAMHEADER in the dwReservedDriver array
*/
padsh = (PACMDRVSTREAMHEADER)pash;
/* check that pointers have not been modified */
if (padsh->pbPreparedSrc != padsh->pbSrc ||
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
padsh->pbPreparedDst != padsh->pbDst ||
padsh->cbPreparedDstLength < padsh->cbDstLength) {
return MMSYSERR_INVALPARAM;
}
padsh->fdwConvert = fdwConvert;
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
if (ret == MMSYSERR_NOERROR) {
padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
}
TRACE("=> (%d)\n", ret);
return ret;
}
/***********************************************************************
* acmStreamPrepareHeader (MSACM32.41)
*/
MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
DWORD fdwPrepare)
{
PWINE_ACMSTREAM was;
MMRESULT ret = MMSYSERR_NOERROR;
PACMDRVSTREAMHEADER padsh;
TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
if ((was = ACM_GetStream(has)) == NULL)
return MMSYSERR_INVALHANDLE;
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
return MMSYSERR_INVALPARAM;
if (fdwPrepare)
ret = MMSYSERR_INVALFLAG;
if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
return MMSYSERR_NOERROR;
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
* size. some fields are private to msacm internals, and are exposed
* in ACMSTREAMHEADER in the dwReservedDriver array
*/
padsh = (PACMDRVSTREAMHEADER)pash;
padsh->fdwConvert = fdwPrepare;
padsh->padshNext = NULL;
padsh->fdwDriver = padsh->dwDriver = 0L;
padsh->fdwPrepared = 0;
padsh->dwPrepared = 0;
padsh->pbPreparedSrc = 0;
padsh->cbPreparedSrcLength = 0;
padsh->pbPreparedDst = 0;
padsh->cbPreparedDstLength = 0;
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
ret = MMSYSERR_NOERROR;
padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
padsh->fdwPrepared = padsh->fdwStatus;
padsh->dwPrepared = 0;
padsh->pbPreparedSrc = padsh->pbSrc;
padsh->cbPreparedSrcLength = padsh->cbSrcLength;
padsh->pbPreparedDst = padsh->pbDst;
padsh->cbPreparedDstLength = padsh->cbDstLength;
} else {
padsh->fdwPrepared = 0;
padsh->dwPrepared = 0;
padsh->pbPreparedSrc = 0;
padsh->cbPreparedSrcLength = 0;
padsh->pbPreparedDst = 0;
padsh->cbPreparedDstLength = 0;
}
TRACE("=> (%d)\n", ret);
return ret;
}
/***********************************************************************
* acmStreamReset (MSACM32.42)
*/
MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
{
PWINE_ACMSTREAM was;
MMRESULT ret = MMSYSERR_NOERROR;
TRACE("(0x%08x, %ld)\n", has, fdwReset);
if (fdwReset) {
ret = MMSYSERR_INVALFLAG;
} else if ((was = ACM_GetStream(has)) == NULL) {
return MMSYSERR_INVALHANDLE;
} else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
}
TRACE("=> (%d)\n", ret);
return ret;
}
/***********************************************************************
* acmStreamSize (MSACM32.43)
*/
MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
LPDWORD pdwOutputBytes, DWORD fdwSize)
{
PWINE_ACMSTREAM was;
ACMDRVSTREAMSIZE adss;
MMRESULT ret;
TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
if ((was = ACM_GetStream(has)) == NULL) {
return MMSYSERR_INVALHANDLE;
}
if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
return MMSYSERR_INVALFLAG;
}
*pdwOutputBytes = 0L;
switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
case ACM_STREAMSIZEF_DESTINATION:
adss.cbDstLength = cbInput;
adss.cbSrcLength = 0;
break;
case ACM_STREAMSIZEF_SOURCE:
adss.cbSrcLength = cbInput;
adss.cbDstLength = 0;
break;
default:
return MMSYSERR_INVALFLAG;
}
adss.cbStruct = sizeof(adss);
adss.fdwSize = fdwSize;
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
(DWORD)&was->drvInst, (DWORD)&adss);
if (ret == MMSYSERR_NOERROR) {
switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
case ACM_STREAMSIZEF_DESTINATION:
*pdwOutputBytes = adss.cbSrcLength;
break;
case ACM_STREAMSIZEF_SOURCE:
*pdwOutputBytes = adss.cbDstLength;
break;
}
}
TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
return ret;
}
/***********************************************************************
* acmStreamUnprepareHeader (MSACM32.44)
*/
MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
DWORD fdwUnprepare)
{
PWINE_ACMSTREAM was;
MMRESULT ret = MMSYSERR_NOERROR;
PACMDRVSTREAMHEADER padsh;
TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
if ((was = ACM_GetStream(has)) == NULL)
return MMSYSERR_INVALHANDLE;
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
return MMSYSERR_INVALPARAM;
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
return ACMERR_UNPREPARED;
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
* size. some fields are private to msacm internals, and are exposed
* in ACMSTREAMHEADER in the dwReservedDriver array
*/
padsh = (PACMDRVSTREAMHEADER)pash;
/* check that pointers have not been modified */
if (padsh->pbPreparedSrc != padsh->pbSrc ||
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
padsh->pbPreparedDst != padsh->pbDst ||
padsh->cbPreparedDstLength < padsh->cbDstLength) {
return MMSYSERR_INVALPARAM;
}
padsh->fdwConvert = fdwUnprepare;
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
ret = MMSYSERR_NOERROR;
padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
}
TRACE("=> (%d)\n", ret);
return ret;
}

View file

@ -1,242 +0,0 @@
/****************************************************************************
*
* AVIFMT - AVI file format definitions
*
****************************************************************************/
#ifndef AVIFMT
#define AVIFMT
#ifndef NOAVIFMT
#ifndef __WINE_WINDEF_H
#include <wine/windef.h>
#endif
#ifndef __WINE_MMSYSTEM_H
typedef DWORD FOURCC;
#endif
#ifdef _MSC_VER
#pragma warning(disable:4200)
#endif
/* The following is a short description of the AVI file format. Please
* see the accompanying documentation for a full explanation.
*
* An AVI file is the following RIFF form:
*
* RIFF('AVI'
* LIST('hdrl'
* avih(<MainAVIHeader>)
* LIST ('strl'
* strh(<Stream header>)
* strf(<Stream format>)
* ... additional header data
* LIST('movi'
* { LIST('rec'
* SubChunk...
* )
* | SubChunk } ....
* )
* [ <AVIIndex> ]
* )
*
* The main file header specifies how many streams are present. For
* each one, there must be a stream header chunk and a stream format
* chunk, enlosed in a 'strl' LIST chunk. The 'strf' chunk contains
* type-specific format information; for a video stream, this should
* be a BITMAPINFO structure, including palette. For an audio stream,
* this should be a WAVEFORMAT (or PCMWAVEFORMAT) structure.
*
* The actual data is contained in subchunks within the 'movi' LIST
* chunk. The first two characters of each data chunk are the
* stream number with which that data is associated.
*
* Some defined chunk types:
* Video Streams:
* ##db: RGB DIB bits
* ##dc: RLE8 compressed DIB bits
* ##pc: Palette Change
*
* Audio Streams:
* ##wb: waveform audio bytes
*
* The grouping into LIST 'rec' chunks implies only that the contents of
* the chunk should be read into memory at the same time. This
* grouping is used for files specifically intended to be played from
* CD-ROM.
*
* The index chunk at the end of the file should contain one entry for
* each data chunk in the file.
*
* Limitations for the current software:
* Only one video stream and one audio stream are allowed.
* The streams must start at the beginning of the file.
*
*
* To register codec types please obtain a copy of the Multimedia
* Developer Registration Kit from:
*
* Microsoft Corporation
* Multimedia Systems Group
* Product Marketing
* One Microsoft Way
* Redmond, WA 98052-6399
*
*/
#ifndef mmioFOURCC
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
#endif
/* Macro to make a TWOCC out of two characters */
#ifndef aviTWOCC
#define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
#endif
typedef WORD TWOCC;
/* form types, list types, and chunk types */
#define formtypeAVI mmioFOURCC('A', 'V', 'I', ' ')
#define listtypeAVIHEADER mmioFOURCC('h', 'd', 'r', 'l')
#define ckidAVIMAINHDR mmioFOURCC('a', 'v', 'i', 'h')
#define listtypeSTREAMHEADER mmioFOURCC('s', 't', 'r', 'l')
#define ckidSTREAMHEADER mmioFOURCC('s', 't', 'r', 'h')
#define ckidSTREAMFORMAT mmioFOURCC('s', 't', 'r', 'f')
#define ckidSTREAMHANDLERDATA mmioFOURCC('s', 't', 'r', 'd')
#define ckidSTREAMNAME mmioFOURCC('s', 't', 'r', 'n')
#define listtypeAVIMOVIE mmioFOURCC('m', 'o', 'v', 'i')
#define listtypeAVIRECORD mmioFOURCC('r', 'e', 'c', ' ')
#define ckidAVINEWINDEX mmioFOURCC('i', 'd', 'x', '1')
/*
** Stream types for the <fccType> field of the stream header.
*/
#define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's')
#define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's')
#define streamtypeMIDI mmioFOURCC('m', 'i', 'd', 's')
#define streamtypeTEXT mmioFOURCC('t', 'x', 't', 's')
/* Basic chunk types */
#define cktypeDIBbits aviTWOCC('d', 'b')
#define cktypeDIBcompressed aviTWOCC('d', 'c')
#define cktypePALchange aviTWOCC('p', 'c')
#define cktypeWAVEbytes aviTWOCC('w', 'b')
/* Chunk id to use for extra chunks for padding. */
#define ckidAVIPADDING mmioFOURCC('J', 'U', 'N', 'K')
/*
** Useful macros
**
** Warning: These are nasty macro, and MS C 6.0 compiles some of them
** incorrectly if optimizations are on. Ack.
*/
/* Macro to get stream number out of a FOURCC ckid */
#define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
#define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + \
(FromHex(HIBYTE(LOWORD(fcc))))))
/* Macro to get TWOCC chunk type out of a FOURCC ckid */
#define TWOCCFromFOURCC(fcc) HIWORD(fcc)
/* Macro to make a ckid for a chunk out of a TWOCC and a stream number
** from 0-255.
*/
#define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
#define MAKEAVICKID(tcc, stream) \
MAKELONG((ToHex((stream) & 0x0f) << 8) | \
(ToHex(((stream) & 0xf0) >> 4)), tcc)
/*
** Main AVI File Header
*/
/* flags for use in <dwFlags> in AVIFileHdr */
#define AVIF_HASINDEX 0x00000010 // Index at end of file?
#define AVIF_MUSTUSEINDEX 0x00000020
#define AVIF_ISINTERLEAVED 0x00000100
#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
#define AVIF_WASCAPTUREFILE 0x00010000
#define AVIF_COPYRIGHTED 0x00020000
/* The AVI File Header LIST chunk should be padded to this size */
#define AVI_HEADERSIZE 2048 // size of AVI header list
typedef struct
{
DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
DWORD dwMaxBytesPerSec; // max. transfer rate
DWORD dwPaddingGranularity; // pad to multiples of this
// size; normally 2K.
DWORD dwFlags; // the ever-present flags
DWORD dwTotalFrames; // # frames in file
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwReserved[4];
} MainAVIHeader;
/*
** Stream header
*/
#define AVISF_DISABLED 0x00000001
#define AVISF_VIDEO_PALCHANGES 0x00010000
typedef struct {
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags; /* Contains AVITF_* flags */
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate; /* dwRate / dwScale == samples/second */
DWORD dwStart;
DWORD dwLength; /* In units above... */
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT rcFrame;
} AVIStreamHeader;
/* Flags for index */
#define AVIIF_LIST 0x00000001L // chunk is a 'LIST'
#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
#define AVIIF_NOTIME 0x00000100L // this frame doesn't take any time
#define AVIIF_COMPUSE 0x0FFF0000L // these bits are for compressor use
#define FOURCC_RIFF mmioFOURCC('R', 'I', 'F', 'F')
#define FOURCC_LIST mmioFOURCC('L', 'I', 'S', 'T')
typedef struct
{
DWORD ckid;
DWORD dwFlags;
DWORD dwChunkOffset; // Position of chunk
DWORD dwChunkLength; // Length of chunk
} AVIINDEXENTRY;
#define AVISTREAMREAD_CONVENIENT (-1L)
/*
** Palette change chunk
**
** Used in video streams.
*/
#endif /* NOAVIFMT */
#endif

View file

@ -1,313 +0,0 @@
#include <stdio.h>
#include <malloc.h>
#include <wine/driver.h>
#include <wine/pe_image.h>
#include <wine/winreg.h>
#include <wine/vfw.h>
#include <registry.h>
#include "config.h"
#define STORE_ALL \
__asm__ ( \
"push %%ebx\n\t" \
"push %%ecx\n\t" \
"push %%edx\n\t" \
"push %%esi\n\t" \
"push %%edi\n\t"::)
#define REST_ALL \
__asm__ ( \
"pop %%edi\n\t" \
"pop %%esi\n\t" \
"pop %%edx\n\t" \
"pop %%ecx\n\t" \
"pop %%ebx\n\t"::)
#define WIN32_PATH GST_WIN32_LIBDIR
typedef struct {
UINT uDriverSignature;
HINSTANCE hDriverModule;
DRIVERPROC DriverProc;
DWORD dwDriverID;
} DRVR;
typedef DRVR *PDRVR;
typedef DRVR *NPDRVR;
typedef DRVR *LPDRVR;
static DWORD dwDrvID = 0;
LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message,
LPARAM lParam1, LPARAM lParam2 )
{
DRVR* module=(DRVR*)hDriver;
int result;
#ifdef DETAILED_OUT
printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2);
#endif
if(module==0)return -1;
if(module->hDriverModule==0)return -1;
if(module->DriverProc==0)return -1;
STORE_ALL;
result=module->DriverProc(module->dwDriverID,1,message,lParam1,lParam2);
REST_ALL;
#ifdef DETAILED_OUT
printf("\t\tResult: %X\n", result);
#endif
return result;
}
static NPDRVR DrvAlloc(HDRVR*lpDriver, LPUINT lpDrvResult)
{
NPDRVR npDriver;
/* allocate and lock handle */
if (lpDriver)
{
if (*lpDriver = (HDRVR) malloc(sizeof(DRVR)) )
{
if (npDriver = (NPDRVR) *lpDriver)
{
*lpDrvResult = MMSYSERR_NOERROR;
return (npDriver);
}
free((NPDRVR)*lpDriver);
}
return (*lpDrvResult = MMSYSERR_NOMEM, (NPDRVR) 0);
}
return (*lpDrvResult = MMSYSERR_INVALPARAM, (NPDRVR) 0);
}
typedef struct
{
HMODULE handle;
char name[64];
int usage;
}codec_t;
static codec_t avi_codecs[]={
{0, WIN32_PATH"/divxc32.dll", 0}, //0
{0, WIN32_PATH"/ir50_32.dll", 0},
{0, WIN32_PATH"/ir41_32.dll", 0},
{0, WIN32_PATH"/ir32_32.dll", 0},
{0, WIN32_PATH"/mpg4c32.dll", 0},
{0, WIN32_PATH"/iccvid.dll", 0}, //5
{0, WIN32_PATH"/libvideodll.so", 0},
{0, WIN32_PATH"/divxa32.acm", 0},
{0, WIN32_PATH"/msadp32.acm", 0},
{0, WIN32_PATH"/ativcr1.dll", 0},
{0, WIN32_PATH"/ativcr2.dll", 0}, //10
{0, WIN32_PATH"/i263_32.drv", 0},
{0, WIN32_PATH"/l3codeca.acm", 0},
// {0, WIN32_PATH"/atiyvu9.dll", 0},
};
static void DrvFree(HDRVR hDriver)
{
int i;
if(hDriver)
if(((DRVR*)hDriver)->hDriverModule)
if(((DRVR*)hDriver)->DriverProc)
(((DRVR*)hDriver)->DriverProc)(((DRVR*)hDriver)->dwDriverID, hDriver, DRV_CLOSE, 0, 0);
if(hDriver)
for(i=0; i<sizeof(avi_codecs)/sizeof(avi_codecs[0]); i++)
if(avi_codecs[i].handle==((DRVR*)hDriver)->hDriverModule)
{
avi_codecs[i].usage--;
if(avi_codecs[i].usage==0)
{
avi_codecs[i].handle=0;
if(((DRVR*)hDriver)->hDriverModule)
if(((DRVR*)hDriver)->DriverProc)
(((DRVR*)hDriver)->DriverProc)(0, hDriver, DRV_FREE, 0, 0);
FreeLibrary(((DRVR*)hDriver)->hDriverModule);
if (hDriver)
free((NPDRVR)hDriver);
return;
}
}
}
void DrvClose(HDRVR hdrvr)
{
DrvFree(hdrvr);
}
HDRVR
//DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2)
DrvOpen(LPARAM lParam2)
{
int drv_id;
char filename[MAX_PATH], *f;
UINT uDrvResult;
HDRVR hDriver;
NPDRVR npDriver;
char unknown[0x24];
int seg;
int qwe;
int regs[10];
int fccHandler=*((int*)lParam2+2);
int fccType=*((int*)lParam2+1);
if(fccType==0x63646976)//vidc
switch(fccHandler)
{
case mmioFOURCC('D', 'I', 'V', '3'):
case mmioFOURCC('D', 'I', 'V', '4'):
case mmioFOURCC('d', 'i', 'v', '3'):
case mmioFOURCC('d', 'i', 'v', '4'):
case mmioFOURCC('M', 'P', '4', '1'):
case mmioFOURCC('M', 'P', '4', '2'):
case mmioFOURCC('M', 'P', '4', '3'):
printf("Video in DivX ;-) format\n");
drv_id=0;
break;
case mmioFOURCC('I', 'V', '5', '0'):
case mmioFOURCC('i', 'v', '5', '0'):
printf("Video in Indeo Video 5 format\n");
drv_id=1;
break;
case mmioFOURCC('I', 'V', '4', '1'):
case mmioFOURCC('i', 'v', '4', '1'):
printf("Video in Indeo Video 4.1 format\n");
drv_id=2;
break;
case mmioFOURCC('I', 'V', '3', '2'):
case mmioFOURCC('i', 'v', '3', '2'):
printf("Video in Indeo Video 3.2 format\n");
drv_id=3;
break;
case mmioFOURCC('m', 'p', '4', '1'):
case mmioFOURCC('m', 'p', '4', '2'):
case mmioFOURCC('m', 'p', '4', '3'):
case mmioFOURCC('M', 'P', 'G', '4'):
printf("Video in Microsoft MPEG-4 format\n");
drv_id=4;
break;
case mmioFOURCC('c', 'v', 'i', 'd'):
printf("Video in Cinepak format\n");
drv_id=5;
break;
case mmioFOURCC('V', 'C', 'R', '1'):
drv_id=9;
break;
case mmioFOURCC('V', 'C', 'R', '2'):
drv_id=10;
break;
case mmioFOURCC('i', '2', '6', '3'):
case mmioFOURCC('I', '2', '6', '3'):
drv_id=11;
break;
// case mmioFOURCC('Y', 'V', 'U', '9'):
// drv_id=12;
// break;
default:
printf("Unknown codec %X='%c%c%c%c'\n", fccHandler,
fccHandler&0xFF, (fccHandler&0xFF00)>>8,
(fccHandler&0xFF0000)>>16, (fccHandler&0xFF000000)>>24);
return (HDRVR)0;
}
else
switch(fccHandler)
{
case 0x160://DivX audio
case 0x161://DivX audio
drv_id=7;
break;
case 0x2://MS ADPCM
drv_id=8;
break;
case 0x55://MPEG Layer 3
printf("MPEG Layer 3 ( 0x55 )\n");
drv_id=12;
break;
default:
printf("Unknown ACM codec 0x%X\n", fccHandler);
return (HDRVR)0;
}
if (!(npDriver = DrvAlloc(&hDriver, &uDrvResult)))
return ((HDRVR) 0);
if(avi_codecs[drv_id].handle==0)
{
if (!(avi_codecs[drv_id].handle=npDriver->hDriverModule = LoadLibraryA(avi_codecs[drv_id].name)))
{
printf("Can't open library %s\n", avi_codecs[drv_id].name);
DrvFree(hDriver);
return ((HDRVR) 0);
}
else avi_codecs[drv_id].usage=1;
}
else
{
npDriver->hDriverModule=avi_codecs[drv_id].handle;
avi_codecs[drv_id].usage++;
}
// 14c0
if(drv_id==0)
{
int newkey;
int bitrate;
int count=4;
if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\LinuxLoader\\Divx", 0, 0, &newkey)!=0)
goto no_reg;
if(RegQueryValueExA(newkey, "BitRate", 0, 0, &bitrate, &count)!=0)
{
RegCloseKey(newkey);
goto no_reg;
}
// printf("Setting default bitrate from %f to %d\n",
// *(double*)((char*)npDriver->hDriverModule+0x14c0), bitrate);
*(double*)((char*)npDriver->hDriverModule+0x14c0)=bitrate;
RegCloseKey(newkey);
no_reg:
;
}
if (!(npDriver->DriverProc = (DRIVERPROC)
GetProcAddress(npDriver->hDriverModule, "DriverProc")))
{
printf("Library %s is not a valid codec\n", avi_codecs[drv_id].name);
FreeLibrary(npDriver->hDriverModule);
DrvFree(hDriver);
return ((HDRVR) 0);
}
TRACE("DriverProc == %X\n", npDriver->DriverProc);
npDriver->dwDriverID = ++dwDrvID;
if (avi_codecs[drv_id].usage==1)
{
STORE_ALL;
(npDriver->DriverProc)(0, hDriver, DRV_LOAD, 0, 0);
REST_ALL;
TRACE("DRV_LOAD Ok!\n");
STORE_ALL;
(npDriver->DriverProc)(0, hDriver, DRV_ENABLE, 0, 0);
REST_ALL;
TRACE("DRV_ENABLE Ok!\n");
}
// open driver
STORE_ALL;
npDriver->dwDriverID=(npDriver->DriverProc)(npDriver->dwDriverID, hDriver, DRV_OPEN,
(LPARAM) (LPSTR) unknown, lParam2);
REST_ALL;
TRACE("DRV_OPEN Ok!(%X)\n", npDriver->dwDriverID);
if (uDrvResult)
{
DrvFree(hDriver);
hDriver = (HDRVR) 0;
}
return (hDriver);
}

View file

@ -1,304 +0,0 @@
/*
* Elf-dll loader functions
*
* Copyright 1999 Bertho A. Stultiens
*/
#include <config.h>
#ifdef HAVE_LIBDL
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <wine/config.h>
#include <wine/windef.h>
//#include <wine/global.h>
//#include <wine/process.h>
#include <wine/module.h>
#include <wine/heap.h>
#include <wine/elfdll.h>
#include <wine/debugtools.h>
#include <wine/winerror.h>
//DEFAULT_DEBUG_CHANNEL(elfdll)
#include <dlfcn.h>
struct modref_list_t;
typedef struct modref_list_t
{
WINE_MODREF* wm;
struct modref_list_t *next;
struct modref_list_t *prev;
}
modref_list;
//WINE_MODREF *local_wm=NULL;
extern modref_list* local_wm;
/*------------------ HACKS -----------------*/
extern DWORD fixup_imports(WINE_MODREF *wm);
extern void dump_exports(HMODULE hModule);
/*---------------- END HACKS ---------------*/
char *extra_ld_library_path = "/usr/lib/win32";
struct elfdll_image
{
HMODULE pe_module_start;
DWORD pe_module_size;
};
/****************************************************************************
* ELFDLL_dlopen
*
* Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf
* manually because libdl.so caches the environment and does not accept our
* changes.
*/
void *ELFDLL_dlopen(const char *libname, int flags)
{
char buffer[256];
int namelen;
void *handle;
char *ldpath;
/* First try the default path search of dlopen() */
handle = dlopen(libname, flags);
if(handle)
return handle;
/* Now try to construct searches through our extra search-path */
namelen = strlen(libname);
ldpath = extra_ld_library_path;
while(ldpath && *ldpath)
{
int len;
char *cptr;
char *from;
from = ldpath;
cptr = strchr(ldpath, ':');
if(!cptr)
{
len = strlen(ldpath);
ldpath = NULL;
}
else
{
len = cptr - ldpath;
ldpath = cptr + 1;
}
if(len + namelen + 1 >= sizeof(buffer))
{
ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n");
return NULL;
}
strncpy(buffer, from, len);
if(len)
{
buffer[len] = '/';
strcpy(buffer + len + 1, libname);
}
else
strcpy(buffer + len, libname);
TRACE("Trying dlopen('%s', %d)\n", buffer, flags);
handle = dlopen(buffer, flags);
if(handle)
return handle;
}
return NULL;
}
/****************************************************************************
* get_sobasename (internal)
*
*/
static LPSTR get_sobasename(LPCSTR path, LPSTR name)
{
char *cptr;
/* Strip the path from the library name */
if((cptr = strrchr(path, '/')))
{
char *cp = strrchr(cptr+1, '\\');
if(cp && cp > cptr)
cptr = cp;
}
else
cptr = strrchr(path, '\\');
if(!cptr)
cptr = (char *)path; /* No '/' nor '\\' in path */
else
cptr++;
strcpy(name, cptr);
cptr = strrchr(name, '.');
if(cptr)
*cptr = '\0'; /* Strip extension */
/* Convert to lower case.
* This must be done manually because it is not sure that
* other modules are accessible.
*/
for(cptr = name; *cptr; cptr++)
*cptr = tolower(*cptr);
return name;
}
/****************************************************************************
* ELFDLL_CreateModref (internal)
*
* INPUT
* hModule - the header from the elf-dll's data-segment
* path - requested path from original call
*
* OUTPUT
* A WINE_MODREF pointer to the new object
*
* BUGS
* - Does not handle errors due to dependencies correctly
* - path can be wrong
*/
#define RVA(base, va) (((DWORD)base) + ((DWORD)va))
static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path)
{
// IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
IMAGE_DATA_DIRECTORY *dir;
IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
WINE_MODREF *wm;
int len;
HANDLE procheap = GetProcessHeap();
wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm));
if(!wm)
return NULL;
wm->module = hModule;
wm->type = MODULE32_ELF; /* FIXME */
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
// if(dir->Size)
// wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress);
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
// if(dir->Size)
// pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress);
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
// if(dir->Size)
// wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress);
wm->filename = malloc(strlen(path)+1);
strcpy(wm->filename, path);
wm->modname = strrchr( wm->filename, '\\' );
if (!wm->modname) wm->modname = wm->filename;
else wm->modname++;
/*
len = GetShortPathNameA( wm->filename, NULL, 0 );
wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 );
GetShortPathNameA( wm->filename, wm->short_filename, len+1 );
wm->short_modname = strrchr( wm->short_filename, '\\' );
if (!wm->short_modname) wm->short_modname = wm->short_filename;
else wm->short_modname++;
*/
/* Link MODREF into process list */
// EnterCriticalSection( &PROCESS_Current()->crit_section );
if(local_wm)
{
local_wm->next=malloc(sizeof(modref_list));
local_wm->next->prev=local_wm;
local_wm->next->next=NULL;
local_wm->next->wm=wm;
local_wm=local_wm->next;
}
else
{
local_wm=malloc(sizeof(modref_list));
local_wm->next=local_wm->prev=NULL;
local_wm->wm=wm;
}
// LeaveCriticalSection( &PROCESS_Current()->crit_section );
return wm;
}
/****************************************************************************
* ELFDLL_LoadLibraryExA (internal)
*
* Implementation of elf-dll loading for PE modules
*/
WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags)
{
LPVOID dlhandle;
struct elfdll_image *image;
char name[129];
char soname[129];
WINE_MODREF *wm;
get_sobasename(path, name);
strcpy(soname, name);
strcat(soname, ".so");
/* Try to open the elf-dll */
dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY);
if(!dlhandle)
{
WARN("Could not load %s (%s)\n", soname, dlerror());
SetLastError( ERROR_FILE_NOT_FOUND );
return NULL;
}
/* Get the 'dllname_elfdll_image' variable */
/* strcpy(soname, name);
strcat(soname, "_elfdll_image");
image = (struct elfdll_image *)dlsym(dlhandle, soname);
if(!image)
{
ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror());
dlclose(dlhandle);
SetLastError( ERROR_BAD_FORMAT );
return NULL;
}
*/
wm = ELFDLL_CreateModref((int)dlhandle, path);
if(!wm)
{
ERR("Could not create WINE_MODREF for %s\n", path);
dlclose(dlhandle);
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
return wm;
}
/****************************************************************************
* ELFDLL_UnloadLibrary (internal)
*
* Unload an elf-dll completely from memory and deallocate the modref
*/
void ELFDLL_UnloadLibrary(WINE_MODREF *wm)
{
}
#endif /*HAVE_LIBDL*/

View file

@ -1,554 +0,0 @@
/********************************************************
*
*
* Stub functions for Wine module
*
*
********************************************************/
#include <malloc.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <wine/windef.h>
//#include <wine/winbase.h>
int dbg_header_err( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_warn( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_fixme( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_trace( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_vprintf( const char *format, ... )
{
return 0;
}
int __vprintf( const char *format, ... )
{
#ifdef DETAILED_OUT
va_list va;
va_start(va, format);
vprintf(format, va);
va_end(va);
#endif
return 0;
}
int GetProcessHeap()
{
return 1;
}
void* HeapAlloc(int heap, int flags, int size)
{
if(flags & 0x8)
return calloc(size, 1);
else
return malloc(size);
}
int HeapFree(int heap, int flags, void* mem)
{
free(mem);
return 1;
}
static int last_error;
int GetLastError()
{
return last_error;
}
int SetLastError(int error)
{
return last_error=error;
}
int ReadFile(int handle, void* mem, unsigned long size, long* result, long flags)
{
*result=read(handle, mem, size);
return *result;
}
int lstrcmpiA(const char* c1, const char* c2)
{
return strcasecmp(c1,c2);
}
int lstrcpynA(char* dest, const char* src, int num)
{
return strncmp(dest,src,num);
}
int lstrlenA(const char* s)
{
return strlen(s);
}
int lstrlenW(const short* s)
{
int l;
if(!s)
return 0;
l=0;
while(s[l])
l++;
return l;
}
int lstrcpynWtoA(char* dest, const char* src, int count)
{
int moved=0;
if((dest==0) || (src==0))
return 0;
while(moved<count)
{
*dest=*src;
moved++;
if(*src==0)
return moved;
src++;
dest++;
}
}
int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n)
{
if(s1==0)
return;
if(s2==0)
return;
while(n>0)
{
if(*s1<*s2)
return -1;
else
if(*s1>*s2)
return 1;
else
if(*s1==0)
return 0;
s1++;
s2++;
n--;
}
return 0;
}
int IsBadReadPtr(void* data, int size)
{
if(size==0)
return 0;
if(data==NULL)
return 1;
return 0;
}
char* HEAP_strdupA(const char* string)
{
// return strdup(string);
char* answ=malloc(strlen(string)+1);
strcpy(answ, string);
return answ;
}
short* HEAP_strdupAtoW(void* heap, void* hz, const char* string)
{
int size, i;
short* answer;
if(string==0)
return 0;
size=strlen(string);
answer=malloc(size+size+2);
for(i=0; i<=size; i++)
answer[i]=(short)string[i];
return answer;
}
char* HEAP_strdupWtoA(void* heap, void* hz, const short* string)
{
int size, i;
char* answer;
if(string==0)
return 0;
size=0;
while(string[size])
size++;
answer=malloc(size+2);
for(i=0; i<=size; i++)
answer[i]=(char)string[i];
return answer;
}
/***********************************************************************
* FILE_dommap
*/
//#define MAP_PRIVATE
//#define MAP_SHARED
#undef MAP_ANON
LPVOID FILE_dommap( int unix_handle, LPVOID start,
DWORD size_high, DWORD size_low,
DWORD offset_high, DWORD offset_low,
int prot, int flags )
{
int fd = -1;
int pos;
LPVOID ret;
if (size_high || offset_high)
printf("offsets larger than 4Gb not supported\n");
if (unix_handle == -1)
{
#ifdef MAP_ANON
// printf("Anonymous\n");
flags |= MAP_ANON;
#else
static int fdzero = -1;
if (fdzero == -1)
{
if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
{
perror( "/dev/zero: open" );
exit(1);
}
}
fd = fdzero;
#endif /* MAP_ANON */
/* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
#ifdef MAP_SHARED
flags &= ~MAP_SHARED;
#endif
#ifdef MAP_PRIVATE
flags |= MAP_PRIVATE;
#endif
}
else fd = unix_handle;
// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot);
// if ((ret = mmap( start, size_low, prot,
// flags, fd, offset_low )) != (LPVOID)-1)
if ((ret = mmap( start, size_low, prot,
MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
{
// printf("address %08x\n", *(int*)ret);
// printf("%x\n", ret);
return ret;
}
// printf("mmap %d\n", errno);
/* mmap() failed; if this is because the file offset is not */
/* page-aligned (EINVAL), or because the underlying filesystem */
/* does not support mmap() (ENOEXEC), we do it by hand. */
if (unix_handle == -1) return ret;
if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
if (prot & PROT_WRITE)
{
/* We cannot fake shared write mappings */
#ifdef MAP_SHARED
if (flags & MAP_SHARED) return ret;
#endif
#ifdef MAP_PRIVATE
if (!(flags & MAP_PRIVATE)) return ret;
#endif
}
/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
/* Reserve the memory with an anonymous mmap */
ret = FILE_dommap( -1, start, size_high, size_low, 0, 0,
PROT_READ | PROT_WRITE, flags );
if (ret == (LPVOID)-1)
// {
// perror(
return ret;
/* Now read in the file */
if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
{
FILE_munmap( ret, size_high, size_low );
// printf("lseek\n");
return (LPVOID)-1;
}
read( fd, ret, size_low );
lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */
mprotect( ret, size_low, prot ); /* Set the right protection */
// printf("address %08x\n", *(int*)ret);
return ret;
}
/***********************************************************************
* FILE_munmap
*/
int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
{
if (size_high)
printf("offsets larger than 4Gb not supported\n");
return munmap( start, size_low );
}
static int mapping_size=0;
struct file_mapping_s;
typedef struct file_mapping_s
{
int mapping_size;
char* name;
HANDLE handle;
struct file_mapping_s* next;
struct file_mapping_s* prev;
}file_mapping;
static file_mapping* fm=0;
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
HANDLE CreateFileMappingA(int hFile, void* lpAttr,
DWORD flProtect, DWORD dwMaxHigh, DWORD dwMaxLow, const char* name)
{
unsigned int len;
HANDLE answer;
int anon=0;
int mmap_access=0;
if(hFile<0)
{
anon=1;
hFile=open("/dev/zero", O_RDWR);
if(hFile<0)
return 0;
}
if(!anon)
{
len=lseek(hFile, 0, SEEK_END);
lseek(hFile, 0, SEEK_SET);
}
else len=dwMaxLow;
if(flProtect & PAGE_READONLY)
mmap_access |=PROT_READ;
else
mmap_access |=PROT_READ|PROT_WRITE;
answer=(HANDLE)mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
if(anon)
close(hFile);
if(answer!=(HANDLE)-1)
{
if(fm==0)
{
fm=malloc(sizeof(file_mapping));
fm->prev=NULL;
}
else
{
fm->next=malloc(sizeof(file_mapping));
fm->next->prev=fm;
fm=fm->next;
}
fm->next=NULL;
fm->handle=answer;
if(name)
{
fm->name=malloc(strlen(name)+1);
strcpy(fm->name, name);
}
else
fm->name=NULL;
fm->mapping_size=len;
if(anon)
close(hFile);
return answer;
}
return (HANDLE)0;
}
int UnmapViewOfFile(HANDLE handle)
{
file_mapping* p;
int result;
if(fm==0)
return (HANDLE)0;
for(p=fm; p; p=p->next)
{
if(p->handle==handle)
{
result=munmap((void*)handle, p->mapping_size);
if(p->next)p->next->prev=p->prev;
if(p->prev)p->prev->next=p->next;
if(p->name)
free(p->name);
if(p==fm)
fm=p->prev;
free(p);
return result;
}
}
return 0;
}
//static int va_size=0;
struct virt_alloc_s;
typedef struct virt_alloc_s
{
int mapping_size;
char* address;
struct virt_alloc_s* next;
struct virt_alloc_s* prev;
int state;
}virt_alloc;
static virt_alloc* vm=0;
#define MEM_COMMIT 0x00001000
#define MEM_RESERVE 0x00002000
void* VirtualAlloc(void* address, DWORD size, DWORD type, DWORD protection)
{
void* answer;
int fd=open("/dev/zero", O_RDWR);
size=(size+0xffff)&(~0xffff);
// printf("VirtualAlloc(0x%08X, %d)\n", address
if(address!=0)
{
//check whether we can allow to allocate this
virt_alloc* str=vm;
while(str)
{
if((unsigned)address>=(unsigned)str->address+str->mapping_size)
{
str=str->prev;
continue;
}
if((unsigned)address+size<(unsigned)str->address)
{
str=str->prev;
continue;
}
if(str->state==0)
{
#warning FIXME
if(((unsigned)address+size<(unsigned)str->address+str->mapping_size) && (type & MEM_COMMIT))
{
close(fd);
return address; //returning previously reserved memory
}
return NULL;
}
close(fd);
return NULL;
}
answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, fd, 0);
}
else
answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE, fd, 0);
// answer=FILE_dommap(-1, address, 0, size, 0, 0,
// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
close(fd);
if(answer==(void*)-1)
{
printf("Error no %d\n", errno);
printf("VirtualAlloc(0x%08X, %d) failed\n", address, size);
return NULL;
}
else
{
virt_alloc *new_vm=malloc(sizeof(virt_alloc));
new_vm->mapping_size=size;
new_vm->address=answer;
new_vm->prev=vm;
if(type & MEM_RESERVE)
new_vm->state=0;
else
new_vm->state=1;
if(vm)
vm->next=new_vm;
vm=new_vm;
vm->next=0;
// if(va_size!=0)
// printf("Multiple VirtualAlloc!\n");
// printf("answer=0x%08x\n", answer);
return answer;
}
}
int VirtualFree(void* address, int t1, int t2)//not sure
{
virt_alloc* str=vm;
int answer;
while(str)
{
if(address!=str->address)
{
str=str->prev;
continue;
}
answer=munmap(str->address, str->mapping_size);
if(str->next)str->next->prev=str->prev;
if(str->prev)str->prev->next=str->next;
if(vm==str)vm=0;
free(str);
return 0;
}
return -1;
}
int WideCharToMultiByte(unsigned int codepage, long flags, const short* src,
int srclen,char* dest, int destlen, const char* defch, int* used_defch)
{
int i;
if(src==0)
return 0;
if(dest==0)
{
for(i=0; i<srclen; i++)
{
src++;
if(*src==0)
return i+1;
}
}
if(used_defch)
*used_defch=0;
for(i=0; i<min(srclen, destlen); i++)
{
*dest=(char)*src;
dest++;
src++;
if(*dest==0)
return i+1;
}
return 0;
}
int MultiByteToWideChar(unsigned int codepage,long flags, const char* src, int srclen,
short* dest, int destlen)
{
return 0;
}
HANDLE OpenFileMappingA(long access, long prot, char* name)
{
file_mapping* p;
if(fm==0)
return (HANDLE)0;
if(name==0)
return (HANDLE)0;
for(p=fm; p; p=p->prev)
{
if(p->name==0)
continue;
if(strcmp(p->name, name)==0)
return p->handle;
}
return 0;
}

View file

@ -1,617 +0,0 @@
/*
* Modules
*
* Copyright 1995 Alexandre Julliard
*/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
/*
#ifdef __linux__
#include <asm/unistd.h>
#include <asm/ldt.h>
#else
#define LDT_ENTRIES 8192
#define LDT_ENTRY_SIZE 8
struct modify_ldt_ldt_s {
unsigned int entry_number;
unsigned long base_addr;
unsigned int limit;
unsigned int seg_32bit:1;
unsigned int contents:2;
unsigned int read_exec_only:1;
unsigned int limit_in_pages:1;
unsigned int seg_not_present:1;
unsigned int useable:1;
};
#define MODIFY_LDT_CONTENTS_DATA 0
#define MODIFY_LDT_CONTENTS_STACK 1
#define MODIFY_LDT_CONTENTS_CODE 2
#define __NR_modify_ldt 123
#endif
*/
#include <wine/windef.h>
#include <wine/winerror.h>
#include <wine/heap.h>
#include <wine/module.h>
#include <wine/pe_image.h>
#include <wine/debugtools.h>
struct modref_list_t;
typedef struct modref_list_t
{
WINE_MODREF* wm;
struct modref_list_t *next;
struct modref_list_t *prev;
}
modref_list;
/***********************************************************************
* LDT_EntryToBytes
*
* Convert an ldt_entry structure to the raw bytes of the descriptor.
*/
/*static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content )
{
*buffer++ = ((content->base_addr & 0x0000ffff) << 16) |
(content->limit & 0x0ffff);
*buffer = (content->base_addr & 0xff000000) |
((content->base_addr & 0x00ff0000)>>16) |
(content->limit & 0xf0000) |
(content->contents << 10) |
((content->read_exec_only == 0) << 9) |
((content->seg_32bit != 0) << 22) |
((content->limit_in_pages != 0) << 23) |
0xf000;
}
*/
//
// funcs:
//
// 0 read LDT
// 1 write old mode
// 0x11 write
//
/*
static int modify_ldt( int func, struct modify_ldt_ldt_s *ptr,
unsigned long count )
{
int res;
#ifdef __PIC__
__asm__ __volatile__( "pushl %%ebx\n\t"
"movl %2,%%ebx\n\t"
"int $0x80\n\t"
"popl %%ebx"
: "=a" (res)
: "0" (__NR_modify_ldt),
"r" (func),
"c" (ptr),
"d" (sizeof(struct modify_ldt_ldt_s)*count) );
#else
__asm__ __volatile__("int $0x80"
: "=a" (res)
: "0" (__NR_modify_ldt),
"b" (func),
"c" (ptr),
"d" (sizeof(struct modify_ldt_ldt_s)*count) );
#endif
if (res >= 0) return res;
errno = -res;
return -1;
}
static int fs_installed=0;
static char* fs_seg=0;
static int install_fs()
{
struct modify_ldt_ldt_s array;
int fd;
int ret;
void* prev_struct;
if(fs_installed)
return 0;
fd=open("/dev/zero", O_RDWR);
fs_seg=mmap((void*)0xbf000000, 0x30000, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, 0);
if(fs_seg==0)
{
printf("ERROR: Couldn't allocate memory for fs segment\n");
return -1;
}
array.base_addr=((int)fs_seg+0xffff) & 0xffff0000;
array.entry_number=0x1;
array.limit=array.base_addr+getpagesize()-1;
array.seg_32bit=1;
array.read_exec_only=0;
array.seg_not_present=0;
array.contents=MODIFY_LDT_CONTENTS_DATA;
array.limit_in_pages=0;
#ifdef linux
ret=modify_ldt(0x1, &array, 1);
if(ret<0)
{
perror("install_fs");
MESSAGE("Couldn't install fs segment, expect segfault\n");
}
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
{
long d[2];
LDT_EntryToBytes( d, &array );
ret = i386_set_ldt(0x1, (union descriptor *)d, 1);
if (ret < 0)
{
perror("install_fs");
MESSAGE("Did you reconfigure the kernel with \"options USER_LDT\"?\n");
}
}
#endif
__asm__
(
"movl $0xf,%eax\n\t"
// "pushw %ax\n\t"
"movw %ax, %fs\n\t"
);
prev_struct=malloc(8);
*(void**)array.base_addr=prev_struct;
printf("prev_struct: 0x%X\n", prev_struct);
close(fd);
fs_installed=1;
return 0;
};
static int uninstall_fs()
{
printf("Uninstalling FS segment\n");
if(fs_seg==0)
return -1;
munmap(fs_seg, 0x30000);
fs_installed=0;
return 0;
}
*/
//WINE_MODREF *local_wm=NULL;
modref_list* local_wm=NULL;
WINE_MODREF *MODULE_FindModule(LPCSTR m)
{
modref_list* list=local_wm;
TRACE("Module %s request\n", m);
if(list==NULL)
return NULL;
while(strcmp(m, list->wm->filename))
{
printf("%s: %x\n", list->wm->filename, list->wm->module);
list=list->prev;
if(list==NULL)
return NULL;
}
TRACE("Resolved to %s\n", list->wm->filename);
return list->wm;
}
void MODULE_RemoveFromList(WINE_MODREF *mod)
{
modref_list* list=local_wm;
if(list==0)
return;
if(mod==0)
return;
if((list->prev==NULL)&&(list->next==NULL))
{
free(list);
local_wm=NULL;
// uninstall_fs();
return;
}
for(;list;list=list->prev)
{
if(list->wm==mod)
{
if(list->prev)
list->prev->next=list->next;
if(list->next)
list->next->prev=list->prev;
if(list==local_wm)
local_wm=list->prev;
free(list);
return;
}
}
}
WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m)
{
modref_list* list=local_wm;
TRACE("Module %X request\n", m);
if(list==NULL)
return NULL;
while(m!=list->wm->module)
{
// printf("Checking list %X wm %X module %X\n",
// list, list->wm, list->wm->module);
list=list->prev;
if(list==NULL)
return NULL;
}
TRACE("LookupHMODULE hit %X\n", list->wm);
return list->wm;
}
/*************************************************************************
* MODULE_InitDll
*/
static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
"THREAD_ATTACH", "THREAD_DETACH" };
assert( wm );
/* Skip calls for modules loaded with special load flags */
if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
|| ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) )
return TRUE;
TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved );
/* Call the initialization routine */
switch ( wm->type )
{
case MODULE32_PE:
retv = PE_InitDLL( wm, type, lpReserved );
break;
case MODULE32_ELF:
/* no need to do that, dlopen() already does */
break;
default:
ERR("wine_modref type %d not handled.\n", wm->type );
retv = FALSE;
break;
}
/* The state of the module list may have changed due to the call
to PE_InitDLL. We cannot assume that this module has not been
deleted. */
TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv );
return retv;
}
/*************************************************************************
* MODULE_DllProcessAttach
*
* Send the process attach notification to all DLLs the given module
* depends on (recursively). This is somewhat complicated due to the fact that
*
* - we have to respect the module dependencies, i.e. modules implicitly
* referenced by another module have to be initialized before the module
* itself can be initialized
*
* - the initialization routine of a DLL can itself call LoadLibrary,
* thereby introducing a whole new set of dependencies (even involving
* the 'old' modules) at any time during the whole process
*
* (Note that this routine can be recursively entered not only directly
* from itself, but also via LoadLibrary from one of the called initialization
* routines.)
*
* Furthermore, we need to rearrange the main WINE_MODREF list to allow
* the process *detach* notifications to be sent in the correct order.
* This must not only take into account module dependencies, but also
* 'hidden' dependencies created by modules calling LoadLibrary in their
* attach notification routine.
*
* The strategy is rather simple: we move a WINE_MODREF to the head of the
* list after the attach notification has returned. This implies that the
* detach notifications are called in the reverse of the sequence the attach
* notifications *returned*.
*
* NOTE: Assumes that the process critical section is held!
*
*/
WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
int i;
assert( wm );
/* prevent infinite recursion in case of cyclical dependencies */
if ( ( wm->flags & WINE_MODREF_MARKER )
|| ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) )
return retv;
TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
/* Tag current MODREF to prevent recursive loop */
wm->flags |= WINE_MODREF_MARKER;
/* Recursively attach all DLLs this one depends on */
/* for ( i = 0; retv && i < wm->nDeps; i++ )
if ( wm->deps[i] )
retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved );
*/
/* Call DLL entry point */
//local_wm=wm;
if(local_wm)
{
local_wm->next=malloc(sizeof(modref_list));
local_wm->next->prev=local_wm;
local_wm->next->next=NULL;
local_wm->next->wm=wm;
local_wm=local_wm->next;
}
else
{
local_wm=malloc(sizeof(modref_list));
local_wm->next=local_wm->prev=NULL;
local_wm->wm=wm;
}
/* Remove recursion flag */
wm->flags &= ~WINE_MODREF_MARKER;
if ( retv )
{
retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved );
if ( retv )
wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
}
TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
return retv;
}
/*************************************************************************
* MODULE_DllProcessDetach
*
* Send DLL process detach notifications. See the comment about calling
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved )
{
// WINE_MODREF *wm=local_wm;
wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED;
MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved );
}
/***********************************************************************
* LoadLibraryExA (KERNEL32)
*/
HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
{
WINE_MODREF *wm;
if(!libname)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
// if(fs_installed==0)
// install_fs();
wm = MODULE_LoadLibraryExA( libname, hfile, flags );
if ( wm )
{
if ( !MODULE_DllProcessAttach( wm, NULL ) )
{
WARN_(module)("Attach failed for module '%s', \n", libname);
MODULE_FreeLibrary(wm);
SetLastError(ERROR_DLL_INIT_FAILED);
MODULE_RemoveFromList(wm);
wm = NULL;
}
}
return wm ? wm->module : 0;
}
/***********************************************************************
* MODULE_LoadLibraryExA (internal)
*
* Load a PE style module according to the load order.
*
* The HFILE parameter is not used and marked reserved in the SDK. I can
* only guess that it should force a file to be mapped, but I rather
* ignore the parameter because it would be extremely difficult to
* integrate this with different types of module represenations.
*
*/
WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
{
DWORD err = GetLastError();
WINE_MODREF *pwm;
int i;
// module_loadorder_t *plo;
SetLastError( ERROR_FILE_NOT_FOUND );
TRACE("Trying native dll '%s'\n", libname);
pwm = PE_LoadLibraryExA(libname, flags);
#ifdef HAVE_LIBDL
if(!pwm)
{
TRACE("Trying ELF dll '%s'\n", libname);
pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags);
}
#endif
// printf("0x%08x\n", pwm);
// break;
if(pwm)
{
/* Initialize DLL just loaded */
TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module);
/* Set the refCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
pwm->refCount++;
SetLastError( err ); /* restore last error */
return pwm;
}
WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
return NULL;
}
/***********************************************************************
* LoadLibraryA (KERNEL32)
*/
HMODULE WINAPI LoadLibraryA(LPCSTR libname) {
return LoadLibraryExA(libname,0,0);
}
/***********************************************************************
* FreeLibrary
*/
WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
WIN_BOOL retv = FALSE;
WINE_MODREF *wm;
wm=MODULE32_LookupHMODULE(hLibModule);
// wm=local_wm;
if ( !wm || !hLibModule )
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
else
retv = MODULE_FreeLibrary( wm );
MODULE_RemoveFromList(wm);
return retv;
}
/***********************************************************************
* MODULE_DecRefCount
*
* NOTE: Assumes that the process critical section is held!
*/
static void MODULE_DecRefCount( WINE_MODREF *wm )
{
int i;
if ( wm->flags & WINE_MODREF_MARKER )
return;
if ( wm->refCount <= 0 )
return;
--wm->refCount;
TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount );
if ( wm->refCount == 0 )
{
wm->flags |= WINE_MODREF_MARKER;
for ( i = 0; i < wm->nDeps; i++ )
if ( wm->deps[i] )
MODULE_DecRefCount( wm->deps[i] );
wm->flags &= ~WINE_MODREF_MARKER;
}
}
/***********************************************************************
* MODULE_FreeLibrary
*
* NOTE: Assumes that the process critical section is held!
*/
WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
{
TRACE("(%s) - START\n", wm->modname );
/* Recursively decrement reference counts */
//MODULE_DecRefCount( wm );
/* Call process detach notifications */
MODULE_DllProcessDetach( wm, FALSE, NULL );
PE_UnloadLibrary(wm);
TRACE("END\n");
return TRUE;
}
/***********************************************************************
* GetProcAddress (KERNEL32.257)
*/
FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
{
return MODULE_GetProcAddress( hModule, function, TRUE );
}
/***********************************************************************
* MODULE_GetProcAddress (internal)
*/
FARPROC MODULE_GetProcAddress(
HMODULE hModule, /* [in] current module handle */
LPCSTR function, /* [in] function to be looked up */
WIN_BOOL snoop )
{
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
// WINE_MODREF *wm=local_wm;
FARPROC retproc;
if (HIWORD(function))
TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function);
else
TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function);
if (!wm) {
SetLastError(ERROR_INVALID_HANDLE);
return (FARPROC)0;
}
switch (wm->type)
{
case MODULE32_PE:
retproc = PE_FindExportedFunction( wm, function, snoop );
if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
return retproc;
#ifdef HAVE_LIBDL
case MODULE32_ELF:
retproc = (FARPROC) dlsym( wm->module, function);
if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
return retproc;
#endif
default:
ERR("wine_modref type %d not handled.\n",wm->type);
SetLastError(ERROR_INVALID_HANDLE);
return (FARPROC)0;
}
}

View file

@ -1,920 +0,0 @@
/*
* Copyright 1994 Eric Youndale & Erik Bos
* Copyright 1995 Martin von Löwis
* Copyright 1996-98 Marcus Meissner
*
* based on Eric Youndale's pe-test and:
*
* ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
* make that:
* ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP
*/
/* Notes:
* Before you start changing something in this file be aware of the following:
*
* - There are several functions called recursively. In a very subtle and
* obscure way. DLLs can reference each other recursively etc.
* - If you want to enhance, speed up or clean up something in here, think
* twice WHY it is implemented in that strange way. There is usually a reason.
* Though sometimes it might just be lazyness ;)
* - In PE_MapImage, right before fixup_imports() all external and internal
* state MUST be correct since this function can be called with the SAME image
* AGAIN. (Thats recursion for you.) That means MODREF.module and
* NE_MODULE.module32.
* - Sometimes, we can't use Linux mmap() to mmap() the images directly.
*
* The problem is, that there is not direct 1:1 mapping from a diskimage and
* a memoryimage. The headers at the start are mapped linear, but the sections
* are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte
* aligned in memory. Linux likes them 4096 byte aligned in memory (due to
* x86 pagesize, this cannot be fixed without a rather large kernel rewrite)
* and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM)
* and other byte blocksizes, we can't always do this. We *can* do this for
* newer pe binaries produced by MSVC 5 and later, since they are also aligned
* to 4096 byte boundaries on disk.
*/
#include <wine/config.h>
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <wine/windef.h>
#include <wine/winbase.h>
#include <wine/winerror.h>
#include <wine/heap.h>
#include <wine/pe_image.h>
#include <wine/module.h>
#include <wine/debugtools.h>
#include "win32.h"
#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta))
extern void* LookupExternal(const char* library, int ordinal);
extern void* LookupExternalByName(const char* library, const char* name);
void dump_exports( HMODULE hModule )
{
char *Module;
int i, j;
u_short *ordinal;
u_long *function,*functions;
u_char **name;
unsigned int load_addr = hModule;
DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start);
Module = (char*)RVA(pe_exports->Name);
TRACE("*******EXPORT DATA*******\n");
TRACE("Module name is %s, %ld functions, %ld names\n",
Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);
ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals);
functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);
name=(u_char**) RVA(pe_exports->AddressOfNames);
TRACE(" Ord RVA Addr Name\n" );
for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)
{
if (!*function) continue;
if (TRACE_ON(win32))
{
DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) );
for (j = 0; j < pe_exports->NumberOfNames; j++)
if (ordinal[j] == i)
{
DPRINTF( " %s", (char*)RVA(name[j]) );
break;
}
if ((*function >= rva_start) && (*function <= rva_end))
DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
DPRINTF("\n");
}
}
}
/* Look up the specified function or ordinal in the exportlist:
* If it is a string:
* - look up the name in the Name list.
* - look up the ordinal with that index.
* - use the ordinal as offset into the functionlist
* If it is a ordinal:
* - use ordinal-pe_export->Base as offset into the functionlist
*/
FARPROC PE_FindExportedFunction(
WINE_MODREF *wm,
LPCSTR funcName,
WIN_BOOL snoop )
{
u_short * ordinals;
u_long * function;
u_char ** name, *ename = NULL;
int i, ordinal;
PE_MODREF *pem = &(wm->binfmt.pe);
IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export;
unsigned int load_addr = wm->module;
u_long rva_start, rva_end, addr;
char * forward;
if (HIWORD(funcName))
TRACE("(%s)\n",funcName);
else
TRACE("(%d)\n",(int)funcName);
if (!exports) {
/* Not a fatal problem, some apps do
* GetProcAddress(0,"RegisterPenApp") which triggers this
* case.
*/
WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
return NULL;
}
ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals);
function= (u_long*) RVA(exports->AddressOfFunctions);
name = (u_char **) RVA(exports->AddressOfNames);
forward = NULL;
rva_start = PE_HEADER(wm->module)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
if (HIWORD(funcName))
{
int min = 0, max = exports->NumberOfNames - 1;
while (min <= max)
{
int res, pos = (min + max) / 2;
ename = RVA(name[pos]);
if (!(res = strcmp( ename, funcName )))
{
ordinal = ordinals[pos];
goto found;
}
if (res > 0) max = pos - 1;
else min = pos + 1;
}
for (i = 0; i < exports->NumberOfNames; i++)
{
ename = RVA(name[i]);
if (!strcmp( ename, funcName ))
{
ERR( "%s.%s required a linear search\n", wm->modname, funcName );
ordinal = ordinals[i];
goto found;
}
}
return NULL;
}
else
{
ordinal = LOWORD(funcName) - exports->Base;
if (snoop && name)
{
for (i = 0; i < exports->NumberOfNames; i++)
if (ordinals[i] == ordinal)
{
ename = RVA(name[i]);
break;
}
}
}
found:
if (ordinal >= exports->NumberOfFunctions)
{
TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base );
return NULL;
}
addr = function[ordinal];
if (!addr) return NULL;
if ((addr < rva_start) || (addr >= rva_end))
{
FARPROC proc = RVA(addr);
if (snoop)
{
if (!ename) ename = "@";
// proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
TRACE("SNOOP_GetProcAddress n/a\n");
}
return proc;
}
else
{
WINE_MODREF *wm;
char *forward = RVA(addr);
char module[256];
char *end = strchr(forward, '.');
if (!end) return NULL;
if (end - forward >= sizeof(module)) return NULL;
memcpy( module, forward, end - forward );
module[end-forward] = 0;
if (!(wm = MODULE_FindModule( module )))
{
ERR("module not found for forward '%s'\n", forward );
return NULL;
}
return MODULE_GetProcAddress( wm->module, end + 1, snoop );
}
}
DWORD fixup_imports( WINE_MODREF *wm )
{
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
PE_MODREF *pem;
unsigned int load_addr = wm->module;
int i,characteristics_detection=1;
char *modname;
assert(wm->type==MODULE32_PE);
pem = &(wm->binfmt.pe);
if (pem->pe_export)
modname = (char*) RVA(pem->pe_export->Name);
else
modname = "<unknown>";
TRACE("Dumping imports list\n");
pe_imp = pem->pe_import;
if (!pe_imp) return 0;
/* We assume that we have at least one import with !0 characteristics and
* detect broken imports with all characteristsics 0 (notably Borland) and
* switch the detection off for them.
*/
for (i = 0; pe_imp->Name ; pe_imp++) {
if (!i && !pe_imp->u.Characteristics)
characteristics_detection = 0;
if (characteristics_detection && !pe_imp->u.Characteristics)
break;
i++;
}
if (!i) return 0;
wm->nDeps = i;
wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
/* load the imported modules. They are automatically
* added to the modref list of the process.
*/
for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
WINE_MODREF *wmImp;
IMAGE_IMPORT_BY_NAME *pe_name;
PIMAGE_THUNK_DATA import_list,thunk_list;
char *name = (char *) RVA(pe_imp->Name);
if (characteristics_detection && !pe_imp->u.Characteristics)
break;
//#warning FIXME: here we should fill imports
TRACE("Loading imports for %s.dll\n", name);
if (pe_imp->u.OriginalFirstThunk != 0) {
TRACE("Microsoft style imports used\n");
import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);
thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
while (import_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
// TRACE("--- Ordinal %s,%d\n", name, ordinal);
thunk_list->u1.Function=LookupExternal(
name, ordinal);
} else {
pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
// TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
thunk_list->u1.Function=LookupExternalByName(
name, pe_name->Name);
}
import_list++;
thunk_list++;
}
} else {
TRACE("Borland style imports used\n");
thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
while (thunk_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {
int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);
TRACE("--- Ordinal %s.%d\n",name,ordinal);
thunk_list->u1.Function=LookupExternal(
name, ordinal);
} else {
pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData);
TRACE("--- %s %s.%d\n",
pe_name->Name,name,pe_name->Hint);
thunk_list->u1.Function=LookupExternalByName(
name, pe_name->Name);
}
thunk_list++;
}
}
}
return 0;
}
static int calc_vma_size( HMODULE hModule )
{
int i,vma_size = 0;
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule);
TRACE("Dump of segment table\n");
TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
{
TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
pe_seg->Name,
pe_seg->Misc.VirtualSize,
pe_seg->VirtualAddress,
pe_seg->SizeOfRawData,
pe_seg->PointerToRawData,
pe_seg->PointerToRelocations,
pe_seg->PointerToLinenumbers,
pe_seg->NumberOfRelocations,
pe_seg->NumberOfLinenumbers,
pe_seg->Characteristics);
vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData);
vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize);
pe_seg++;
}
return vma_size;
}
static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r )
{
int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase;
int hdelta = (delta >> 16) & 0xFFFF;
int ldelta = delta & 0xFFFF;
if(delta == 0)
return;
while(r->VirtualAddress)
{
char *page = (char*) RVA(r->VirtualAddress);
int count = (r->SizeOfBlock - 8)/2;
int i;
TRACE_(fixup)("%x relocations for page %lx\n",
count, r->VirtualAddress);
for(i=0;i<count;i++)
{
int offset = r->TypeOffset[i] & 0xFFF;
int type = r->TypeOffset[i] >> 12;
// TRACE_(fixup)("patching %x type %x\n", offset, type);
switch(type)
{
case IMAGE_REL_BASED_ABSOLUTE: break;
case IMAGE_REL_BASED_HIGH:
*(short*)(page+offset) += hdelta;
break;
case IMAGE_REL_BASED_LOW:
*(short*)(page+offset) += ldelta;
break;
case IMAGE_REL_BASED_HIGHLOW:
*(int*)(page+offset) += delta;
break;
case IMAGE_REL_BASED_HIGHADJ:
FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n");
break;
case IMAGE_REL_BASED_MIPS_JMPADDR:
FIXME("Is this a MIPS machine ???\n");
break;
default:
FIXME("Unknown fixup type\n");
break;
}
}
r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock);
}
}
/**********************************************************************
* PE_LoadImage
* Load one PE format DLL/EXE into memory
*
* Unluckily we can't just mmap the sections where we want them, for
* (at least) Linux does only support offsets which are page-aligned.
*
* BUT we have to map the whole image anyway, for Win32 programs sometimes
* want to access them. (HMODULE32 point to the start of it)
*/
HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version )
{
HMODULE hModule;
HANDLE mapping;
IMAGE_NT_HEADERS *nt;
IMAGE_SECTION_HEADER *pe_sec;
IMAGE_DATA_DIRECTORY *dir;
BY_HANDLE_FILE_INFORMATION bhfi;
int i, rawsize, lowest_va, vma_size, file_size = 0;
DWORD load_addr = 0, aoep, reloc = 0;
// struct get_read_fd_request *req = get_req_buffer();
int unix_handle = handle;
int page_size = getpagesize();
// if ( GetFileInformationByHandle( hFile, &bhfi ) )
// file_size = bhfi.nFileSizeLow;
file_size=lseek(handle, 0, SEEK_END);
lseek(handle, 0, SEEK_SET);
//#warning fix CreateFileMappingA
mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT,
0, 0, NULL );
if (!mapping)
{
WARN("CreateFileMapping error %ld\n", GetLastError() );
return 0;
}
// hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
hModule=(HMODULE)mapping;
// CloseHandle( mapping );
if (!hModule)
{
WARN("MapViewOfFile error %ld\n", GetLastError() );
return 0;
}
if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE)
{
WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule);
goto error;
}
nt = PE_HEADER( hModule );
if ( nt->Signature != IMAGE_NT_SIGNATURE )
{
WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature );
goto error;
}
if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 )
{
MESSAGE("Trying to load PE image for unsupported architecture (");
switch (nt->FileHeader.Machine)
{
case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break;
case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break;
case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break;
case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break;
case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break;
case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break;
case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break;
default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break;
}
MESSAGE(")\n");
goto error;
}
pe_sec = PE_SECTIONS( hModule );
rawsize = 0; lowest_va = 0x10000;
for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
{
if (lowest_va > pe_sec[i].VirtualAddress)
lowest_va = pe_sec[i].VirtualAddress;
if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
continue;
if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
}
if ( file_size && file_size < rawsize )
{
ERR("PE module is too small (header: %d, filesize: %d), "
"probably truncated download?\n",
rawsize, file_size );
goto error;
}
aoep = nt->OptionalHeader.AddressOfEntryPoint;
if (aoep && (aoep < lowest_va))
FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
"below the first virtual address (0x%08x) "
"(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
filename, aoep, lowest_va );
/* FIXME: Hack! While we don't really support shared sections yet,
* this checks for those special cases where the whole DLL
* consists only of shared sections and is mapped into the
* shared address space > 2GB. In this case, we assume that
* the module got mapped at its base address. Thus we simply
* check whether the module has actually been mapped there
* and use it, if so. This is needed to get Win95 USER32.DLL
* to work (until we support shared sections properly).
*/
if ( nt->OptionalHeader.ImageBase & 0x80000000 )
{
HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase;
IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) );
/* Well, this check is not really comprehensive,
but should be good enough for now ... */
if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) )
&& memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0
&& !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) )
&& memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 )
{
UnmapViewOfFile( (LPVOID)hModule );
return sharedMod;
}
}
load_addr = nt->OptionalHeader.ImageBase;
vma_size = calc_vma_size( hModule );
load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
if (load_addr == 0)
{
FIXME("We need to perform base relocations for %s\n", filename);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC;
if (dir->Size)
reloc = dir->VirtualAddress;
else
{
FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
filename,
(nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)?
"stripped during link" : "unknown reason" );
goto error;
}
/* FIXME: If we need to relocate a system DLL (base > 2GB) we should
* really make sure that the *new* base address is also > 2GB.
* Some DLLs really check the MSB of the module handle :-/
*/
if ( nt->OptionalHeader.ImageBase & 0x80000000 )
ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" );
load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
if (!load_addr) {
FIXME_(win32)(
"FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size);
goto error;
}
}
TRACE("Load addr is %lx (base %lx), range %x\n",
load_addr, nt->OptionalHeader.ImageBase, vma_size );
TRACE_(segment)("Loading %s at %lx, range %x\n",
filename, load_addr, vma_size );
#if 0
*(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule;
*PE_HEADER( load_addr ) = *nt;
memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule),
sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections );
memcpy( load_addr, hModule, lowest_fa );
#endif
if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders,
0, 0, PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr)
{
ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n");
goto error;
}
pe_sec = PE_SECTIONS( hModule );
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++)
{
if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue;
TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
{
ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
goto error;
}
if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
(pe_sec->SizeOfRawData & (page_size-1)))
{
DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
TRACE("clearing %p - %p\n",
RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
RVA(pe_sec->VirtualAddress) + end );
memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
end - pe_sec->SizeOfRawData );
}
}
if ( reloc )
do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) );
*version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 )
| (nt->OptionalHeader.MinorSubsystemVersion & 0xff);
UnmapViewOfFile( (LPVOID)hModule );
return (HMODULE)load_addr;
error:
if (unix_handle != -1) close( unix_handle );
if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE );
UnmapViewOfFile( (LPVOID)hModule );
return 0;
}
/**********************************************************************
* PE_CreateModule
*
* Create WINE_MODREF structure for loaded HMODULE32, link it into
* process modref_list, and fixup all imports.
*
* Note: hModule must point to a correctly allocated PE image,
* with base relocations applied; the 16-bit dummy module
* associated to hModule must already exist.
*
* Note: This routine must always be called in the context of the
* process that is to own the module to be created.
*/
WINE_MODREF *PE_CreateModule( HMODULE hModule,
LPCSTR filename, DWORD flags, WIN_BOOL builtin )
{
DWORD load_addr = (DWORD)hModule;
IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
IMAGE_DATA_DIRECTORY *dir;
IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
WINE_MODREF *wm;
int result;
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
if (dir->Size)
pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
if (dir->Size)
pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
if (dir->Size)
pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
if (dir->Size) FIXME("Exception directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
if (dir->Size) FIXME("Security directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
if (dir->Size) TRACE("Debug directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
if (dir->Size) FIXME("Copyright string ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
if (dir->Size) FIXME("Load Configuration directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
if (dir->Size) TRACE("Bound Import directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
if (dir->Size) TRACE("Import Address Table directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
if (dir->Size)
{
TRACE("Delayed import, stub calls LoadLibrary\n" );
/*
* Nothing to do here.
*/
#ifdef ImgDelayDescr
/*
* This code is useful to observe what the heck is going on.
*/
{
ImgDelayDescr *pe_delay = NULL;
pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
}
#endif
}
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
if (dir->Size) FIXME("Unknown directory 14 ignored\n" );
dir = nt->OptionalHeader.DataDirectory+15;
if (dir->Size) FIXME("Unknown directory 15 ignored\n" );
wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(*wm) );
wm->module = hModule;
if ( builtin )
wm->flags |= WINE_MODREF_INTERNAL;
if ( flags & DONT_RESOLVE_DLL_REFERENCES )
wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
if ( flags & LOAD_LIBRARY_AS_DATAFILE )
wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;
wm->type = MODULE32_PE;
wm->binfmt.pe.pe_export = pe_export;
wm->binfmt.pe.pe_import = pe_import;
wm->binfmt.pe.pe_resource = pe_resource;
wm->binfmt.pe.tlsindex = -1;
wm->filename = malloc(strlen(filename)+1);
strcpy(wm->filename, filename );
wm->modname = strrchr( wm->filename, '\\' );
if (!wm->modname) wm->modname = wm->filename;
else wm->modname++;
if ( pe_export )
dump_exports( hModule );
/* Fixup Imports */
if ( pe_import
&& !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
&& !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
&& fixup_imports( wm ) )
{
/* remove entry from modref chain */
return NULL;
}
return wm;
return wm;
}
/******************************************************************************
* The PE Library Loader frontend.
* FIXME: handle the flags.
*/
WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
{
HMODULE hModule32;
WINE_MODREF *wm;
char filename[256];
int hFile;
WORD version = 0;
strncpy(filename, name, sizeof(filename));
hFile=open(filename, O_RDONLY);
if(hFile==-1)
return NULL;
hModule32 = PE_LoadImage( hFile, filename, &version );
if (!hModule32)
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) )
{
ERR( "can't load %s\n", filename );
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
close(hFile);
return wm;
}
/*****************************************************************************
* PE_UnloadLibrary
*
* Unload the library unmapping the image and freeing the modref structure.
*/
void PE_UnloadLibrary(WINE_MODREF *wm)
{
TRACE(" unloading %s\n", wm->filename);
HeapFree( GetProcessHeap(), 0, wm->filename );
HeapFree( GetProcessHeap(), 0, wm->short_filename );
HeapFree( GetProcessHeap(), 0, wm );
}
/*****************************************************************************
* Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
* FIXME: this function should use PE_LoadLibraryExA, but currently can't
* due to the PROCESS_Create stuff.
*/
/* Called if the library is loaded or freed.
* NOTE: if a thread attaches a DLL, the current thread will only do
* DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
* (SDK)
*/
WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
assert( wm->type == MODULE32_PE );
if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
(PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
) {
DLLENTRYPROC entry ;
entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0);
if(entry==NULL)
entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint );
TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
entry, wm->module, type, lpReserved );
printf("Entering DllMain()\n");
retv = entry( wm->module, type, lpReserved );
}
return retv;
}
static LPVOID
_fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) {
if ( ((DWORD)addr>opt->ImageBase) &&
((DWORD)addr<opt->ImageBase+opt->SizeOfImage)
)
return (LPVOID)(((DWORD)addr)+delta);
else
return addr;
}

View file

@ -1,390 +0,0 @@
/*
* PE (Portable Execute) File Resources
*
* Copyright 1995 Thomas Sandford
* Copyright 1996 Martin von Loewis
*
* Based on the Win16 resource handling code in loader/resource.c
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
* Copyright 1997 Marcus Meissner
*/
#include <stdlib.h>
#include <sys/types.h>
#include <wine/winestring.h>
#include <wine/windef.h>
#include <wine/pe_image.h>
#include <wine/module.h>
#include <wine/heap.h>
//#include "task.h"
//#include "process.h"
//#include "stackframe.h"
#include <wine/debugtools.h>
/**********************************************************************
* HMODULE32toPE_MODREF
*
* small helper function to get a PE_MODREF from a passed HMODULE32
*/
static PE_MODREF*
HMODULE32toPE_MODREF(HMODULE hmod) {
WINE_MODREF *wm;
wm = MODULE32_LookupHMODULE( hmod );
if (!wm || wm->type!=MODULE32_PE)
return NULL;
return &(wm->binfmt.pe);
}
/**********************************************************************
* GetResDirEntryW
*
* Helper function - goes down one level of PE resource tree
*
*/
PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
LPCWSTR name,DWORD root,
WIN_BOOL allowdefault)
{
int entrynum;
PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
int namelen;
if (HIWORD(name)) {
if (name[0]=='#') {
char buf[10];
lstrcpynWtoA(buf,name+1,10);
return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
}
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
(BYTE *) resdirptr +
sizeof(IMAGE_RESOURCE_DIRECTORY));
namelen = lstrlenW(name);
for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
{
PIMAGE_RESOURCE_DIR_STRING_U str =
(PIMAGE_RESOURCE_DIR_STRING_U) (root +
entryTable[entrynum].u1.s.NameOffset);
if(namelen != str->Length)
continue;
if(wcsnicmp(name,str->NameString,str->Length)==0)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[entrynum].u2.s.OffsetToDirectory);
}
return NULL;
} else {
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
(BYTE *) resdirptr +
sizeof(IMAGE_RESOURCE_DIRECTORY) +
resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[entrynum].u2.s.OffsetToDirectory);
/* just use first entry if no default can be found */
if (allowdefault && !name && resdirptr->NumberOfIdEntries)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[0].u2.s.OffsetToDirectory);
return NULL;
}
}
/**********************************************************************
* GetResDirEntryA
*/
PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
LPCSTR name, DWORD root,
WIN_BOOL allowdefault )
{
PIMAGE_RESOURCE_DIRECTORY retv;
LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
: (LPWSTR)name;
retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
return retv;
}
/**********************************************************************
* PE_FindResourceEx32W
*/
HANDLE PE_FindResourceExW(
WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
) {
PIMAGE_RESOURCE_DIRECTORY resdirptr;
DWORD root;
HANDLE result;
PE_MODREF *pem = &(wm->binfmt.pe);
if (!pem || !pem->pe_resource)
return 0;
resdirptr = pem->pe_resource;
root = (DWORD) resdirptr;
if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
return 0;
if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
return 0;
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
/* Try LANG_NEUTRAL, too */
if(!result)
return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
return result;
}
/**********************************************************************
* PE_LoadResource32
*/
HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
{
if (!hRsrc || !wm || wm->type!=MODULE32_PE)
return 0;
return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
}
/**********************************************************************
* PE_SizeofResource32
*/
DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
{
/* we don't need hModule */
if (!hRsrc)
return 0;
return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
}
/**********************************************************************
* PE_EnumResourceTypes32A
*/
WIN_BOOL
PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPSTR name;
if (et[i].u1.s.NameIsString)
name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
else
name = (LPSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,name,lparam);
if (HIWORD(name))
HeapFree(heap,0,name);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceTypes32W
*/
WIN_BOOL
PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR type;
if (et[i].u1.s.NameIsString)
type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
else
type = (LPWSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32A
*/
WIN_BOOL
PE_EnumResourceNamesA(
HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
LPWSTR typeW;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(type))
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPSTR name;
if (et[i].u1.s.NameIsString)
name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
else
name = (LPSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,name,lparam);
if (HIWORD(name)) HeapFree(heap,0,name);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32W
*/
WIN_BOOL
PE_EnumResourceNamesW(
HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR name;
if (et[i].u1.s.NameIsString)
name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
else
name = (LPWSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,name,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32A
*/
WIN_BOOL
PE_EnumResourceLanguagesA(
HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
LPWSTR nameW,typeW;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(name))
nameW = HEAP_strdupAtoW(heap,0,name);
else
nameW = (LPWSTR)name;
resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(nameW))
HeapFree(heap,0,nameW);
if (!resdir)
return FALSE;
if (HIWORD(type))
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
/* languages are just ids... I hopem */
ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceLanguages32W
*/
WIN_BOOL
PE_EnumResourceLanguagesW(
HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
if (!ret)
break;
}
return ret;
}

View file

@ -1,410 +0,0 @@
#include <stdio.h>
#include <fcntl.h>
#include <pwd.h>
#include <sys/types.h>
#include <wine/winbase.h>
#include <wine/winreg.h>
#include <wine/winnt.h>
#include <wine/winerror.h>
#include <registry.h>
struct reg_value
{
int type;
char* name;
int len;
char* value;
};
static int reg_size=0;
static struct reg_value* regs=0;
struct reg_handle_s;
typedef struct reg_handle_s
{
int handle;
char* name;
struct reg_handle_s* next;
struct reg_handle_s* prev;
} reg_handle_t;
static reg_handle_t* head=0;
#define DIR -25
static void create_registry();
static void open_registry();
static void save_registry();
static void create_registry(){
if(regs)
{
printf("Logic error: create_registry() called with existing registry\n");
save_registry();
return;
}
regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
regs[0].type=regs[1].type=DIR;
regs[0].name=(char*)malloc(5);
strcpy(regs[0].name, "HKLM");
regs[1].name=(char*)malloc(5);
strcpy(regs[1].name, "HKCU");
regs[0].value=regs[1].value=NULL;
regs[0].len=regs[1].len=0;
reg_size=2;
save_registry();
}
static void open_registry()
{
int fd;
int i;
int len;
struct passwd* pwent;
char* pathname;
if(regs)
{
printf("Multiple open_registry(>\n");
return;
}
pwent=getpwuid(getuid());
pathname=(char*)malloc(strlen(pwent->pw_dir)+20);
strcpy(pathname, pwent->pw_dir);
strcat(pathname, "/.registry");
fd=open(pathname, O_RDONLY);
free(pathname);
if(fd==-1)
{
printf("Creating new registry\n");
create_registry();
return;
}
read(fd, &reg_size, 4);
regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
for(i=0; i<reg_size; i++)
{
read(fd,&regs[i].type,4);
read(fd,&len,4);
regs[i].name=(char*)malloc(len+1);
if(regs[i].name==0)
{
reg_size=i+1;
goto error;
}
read(fd, regs[i].name, len);
regs[i].name[len]=0;
read(fd,&regs[i].len,4);
regs[i].value=(char*)malloc(len);
if(regs[i].value==0)
{
free(regs[i].name);
reg_size=i+1;
goto error;
}
read(fd, regs[i].value, regs[i].len);
}
error:
close(fd);
return;
}
static void save_registry()
{
int fd, i, len;
struct passwd* pwent;
char* pathname;
pwent=getpwuid(getuid());
pathname=(char*)malloc(strlen(pwent->pw_dir)+20);
strcpy(pathname, pwent->pw_dir);
strcat(pathname, "/.registry");
fd=open(pathname, O_WRONLY | O_CREAT, 00777);
free(pathname);
if(fd==-1)
{
printf("Failed to open registry file for writing.\n");
return;
}
write(fd, &reg_size, 4);
for(i=0; i<reg_size; i++)
{
write(fd, &regs[i].type, 4);
len=strlen(regs[i].name);
write(fd, &len, 4);
write(fd, regs[i].name, len);
write(fd, &regs[i].len, 4);
write(fd, regs[i].value, regs[i].len);
}
close(fd);
}
static reg_handle_t* find_handle_by_name(const char* name)
{
reg_handle_t* t;
for(t=head; t; t=t->prev)
{
if(!strcmp(t->name, name))
{
return t;
}
}
return 0;
}
static struct reg_value* find_value_by_name(const char* name)
{
int i;
for(i=0; i<reg_size; i++)
if(!strcmp(regs[i].name, name))
return regs+i;
return 0;
}
static reg_handle_t* find_handle(int handle)
{
reg_handle_t* t;
for(t=head; t; t=t->prev)
{
if(t->handle==handle)
{
return t;
}
}
return 0;
}
static int generate_handle()
{
static int zz=249;
zz++;
while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
zz++;
return zz;
}
static reg_handle_t* insert_handle(long handle, const char* name)
{
reg_handle_t* t;
t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
if(head==0)
{
t->prev=0;
}
else
{
head->next=t;
t->prev=head;
}
t->next=0;
t->name=(char*)malloc(strlen(name)+1);
strcpy(t->name, name);
t->handle=handle;
head=t;
return t;
}
static char* build_keyname(long key, const char* subkey)
{
char* full_name;
reg_handle_t* t;
if((t=find_handle(key))==0)
{
TRACE("Invalid key\n");
return NULL;
}
if(subkey==NULL)
subkey="<default>";
full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
strcpy(full_name, t->name);
strcat(full_name, "\\");
strcat(full_name, subkey);
return full_name;
}
struct reg_value* insert_reg_value(int handle, const char* name, int type, void* value, int len)
{
reg_handle_t* t;
struct reg_value* v;
char* fullname;
if((fullname=build_keyname(handle, name))==NULL)
{
TRACE("Invalid handle\n");
return NULL;
}
if((v=find_value_by_name(fullname))==0)
//creating new value in registry
{
if(regs==0)
create_registry();
regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
v=regs+reg_size;
reg_size++;
}
else
//replacing old one
{
free(v->value);
free(v->name);
}
v->type=type;
v->len=len;
v->value=(char*)malloc(len);
memcpy(v->value, value, len);
v->name=(char*)malloc(strlen(fullname)+1);
strcpy(v->name, fullname);
save_registry();
return v;
}
static void init_registry()
{
printf("Initializing registry\n");
open_registry();
insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
insert_handle(HKEY_CURRENT_USER, "HKCU");
}
static reg_handle_t* find_handle_2(long key, const char* subkey)
{
char* full_name;
reg_handle_t* t;
if((t=find_handle(key))==0)
{
TRACE("Invalid key\n");
return (reg_handle_t*)-1;
}
if(subkey==NULL)
return t;
full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
strcpy(full_name, t->name);
strcat(full_name, "\\");
strcat(full_name, subkey);
t=find_handle_by_name(full_name);
free(full_name);
return t;
}
long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
{
char* full_name;
reg_handle_t* t;
struct reg_value* v;
TRACE("Opening key %s\n", subkey);
if(!regs)
init_registry()
;
/* t=find_handle_2(key, subkey);
if(t==0)
return -1;
if(t==(reg_handle_t*)-1)
return -1;
*/ full_name=build_keyname(key, subkey);
if(!full_name)
return -1;
v=find_value_by_name(full_name);
t=insert_handle(generate_handle(), full_name);
*newkey=t->handle;
free(full_name);
return 0;
}
long RegCloseKey(long key)
{
reg_handle_t *handle;
if(key==HKEY_LOCAL_MACHINE)
return 0;
if(key==HKEY_CURRENT_USER)
return 0;
handle=find_handle(key);
if(handle==0)
return 0;
if(handle->prev)
handle->prev->next=handle->next;
if(handle->next)
handle->next->prev=handle->prev;
if(handle->name)
free(handle->name);
if(handle==head)
head=head->prev;
free(handle);
return 1;
}
long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
{
struct reg_value* t;
char* c;
TRACE("Querying value %s\n", value);
if(!regs)
init_registry()
;
c=build_keyname(key, value);
if(c==NULL)
return 1;
if((t=find_value_by_name(c))==0)
{
free(c);
return 2;
}
free(c);
if(type)
*type=t->type;
if(data)
memcpy(data, t->value, (t->len<*count)?t->len:*count);
if(count)
{
if(*count<t->len)
{
*count=t->len;
return ERROR_MORE_DATA;
}else return 0;
}
return 0;
}
long RegCreateKeyExA(long key, const char* name, long reserved,
void* classs, long options, long security,
void* sec_attr, int* newkey, int* status)
{
reg_handle_t* t;
char* fullname;
struct reg_value* v;
TRACE("Creating/Opening key %s\n", name);
if(!regs)
init_registry()
;
fullname=build_keyname(key, name);
if(fullname==NULL)
return 1;
v=find_value_by_name(fullname);
if(v==0)
{
int qw=45708;
v=insert_reg_value(key, name, DIR, &qw, 4);
*status=REG_CREATED_NEW_KEY;
// return 0;
}
else
*status=REG_OPENED_EXISTING_KEY;
t=insert_handle(generate_handle(), fullname);
*newkey=t->handle;
free(fullname);
return 0;
}
long RegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
{
struct reg_value* t;
char* c;
TRACE("Request to set value %s\n", name);
if(!regs)
init_registry()
;
c=build_keyname(key, name);
if(c==NULL)
return 1;
insert_reg_value(key, name, v2, data, size);
free(c);
return 0;
}

View file

@ -1,25 +0,0 @@
/********************************************************
Declaration of registry access functions
Copyright 2000 Eugene Smith (divx@euro.ru)
Last modified: 18.06.2000
*********************************************************/
#ifndef REGISTRY_H
#define REGISTRY_H
#ifdef __cplusplus
extern "C" {
#endif
long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey);
long RegCloseKey(long key);
long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count);
long RegCreateKeyExA(long key, const char* name, long reserved,
void* classs, long options, long security,
void* sec_attr, int* newkey, int* status) ;
long RegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size);
#ifdef __cplusplus
};
#endif
#endif

View file

@ -1,475 +0,0 @@
/*
* Resources
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <wine/winbase.h>
#include <wine/windef.h>
#include <wine/winuser.h>
#include <wine/heap.h>
#include <wine/module.h>
#include <wine/debugtools.h>
#include <wine/winerror.h>
#define CP_ACP 0
WORD WINE_LanguageId=0x409;//english
#define HRSRC_MAP_BLOCKSIZE 16
typedef struct _HRSRC_ELEM
{
HANDLE hRsrc;
WORD type;
} HRSRC_ELEM;
typedef struct _HRSRC_MAP
{
int nAlloc;
int nUsed;
HRSRC_ELEM *elem;
} HRSRC_MAP;
static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
LPCSTR name, WORD lang, int unicode)
{
HRSRC hRsrc = 0;
LPWSTR typeStr, nameStr;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if(!wm)
return 0;
/* 32-bit PE module */
if ( HIWORD( type ) && (!unicode))
typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type );
else
typeStr = (LPWSTR)type;
if ( HIWORD( name ) && (!unicode))
nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
else
nameStr = (LPWSTR)name;
hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
if ( HIWORD( type ) && (!unicode))
HeapFree( GetProcessHeap(), 0, typeStr );
if ( HIWORD( name ) && (!unicode))
HeapFree( GetProcessHeap(), 0, nameStr );
return hRsrc;
}
/**********************************************************************
* RES_FindResource
*/
static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
LPCSTR name, WORD lang, int unicode )
{
HRSRC hRsrc;
// __TRY
// {
hRsrc = RES_FindResource2(hModule, type, name, lang, unicode);
// }
// __EXCEPT(page_fault)
// {
// WARN("page fault\n");
// SetLastError(ERROR_INVALID_PARAMETER);
// return 0;
// }
// __ENDTRY
return hRsrc;
}
/**********************************************************************
* RES_SizeofResource
*/
static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc)
{
DWORD size = 0;
HRSRC hRsrc32;
// HMODULE16 hMod16 = MapHModuleLS( hModule );
// NE_MODULE *pModule = NE_GetPtr( hMod16 );
// WINE_MODREF *wm = pModule && pModule->module32?
// MODULE32_LookupHMODULE( pModule->module32 ) : NULL;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return 0;
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
if(!HIWORD(hRsrc))
{
printf("16-bit hRsrcs not supported\n");
return 0;
}
size = PE_SizeofResource( hModule, hRsrc );
return size;
}
/**********************************************************************
* RES_AccessResource
*/
static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc )
{
HFILE hFile = HFILE_ERROR;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return HFILE_ERROR;
/* 32-bit PE module */
FIXME("32-bit modules not yet supported.\n" );
hFile = HFILE_ERROR;
return hFile;
}
/**********************************************************************
* RES_LoadResource
*/
static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc)
{
HGLOBAL hMem = 0;
HRSRC hRsrc32;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return 0;
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
if(!HIWORD(hRsrc))
{
printf("16-bit hRsrcs not supported\n");
return 0;
}
hMem = PE_LoadResource( wm, hRsrc );
return hMem;
}
/**********************************************************************
* RES_LockResource
*/
static LPVOID RES_LockResource( HGLOBAL handle )
{
LPVOID bits = NULL;
TRACE("(%08x, %s)\n", handle, "PE" );
bits = (LPVOID)handle;
return bits;
}
/**********************************************************************
* RES_FreeResource
*/
static WIN_BOOL RES_FreeResource( HGLOBAL handle )
{
HGLOBAL retv = handle;
return (WIN_BOOL)retv;
}
/**********************************************************************
* FindResourceA (KERNEL32.128)
*/
HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
{
return RES_FindResource( hModule, type, name,
WINE_LanguageId, 0);
}
HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type )
{
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
WINE_LanguageId, 1);
}
/**********************************************************************
* FindResourceExA (KERNEL32.129)
*/
HANDLE WINAPI FindResourceExA( HMODULE hModule,
LPCSTR type, LPCSTR name, WORD lang )
{
return RES_FindResource( hModule, type, name,
lang, 0 );
}
HANDLE WINAPI FindResourceExW( HMODULE hModule,
LPCWSTR type, LPCWSTR name, WORD lang )
{
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
lang, 1 );
}
/**********************************************************************
* LockResource (KERNEL32.384)
*/
LPVOID WINAPI LockResource( HGLOBAL handle )
{
return RES_LockResource( handle );
}
/**********************************************************************
* FreeResource (KERNEL32.145)
*/
WIN_BOOL WINAPI FreeResource( HGLOBAL handle )
{
return RES_FreeResource( handle );
}
/**********************************************************************
* AccessResource (KERNEL32.64)
*/
INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc )
{
return RES_AccessResource( hModule, hRsrc );
}
/**********************************************************************
* SizeofResource (KERNEL32.522)
*/
DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
{
return RES_SizeofResource( hModule, hRsrc );
}
/**********************************************************************
* LoadStringA (USER32.375)
*/
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
LPSTR buffer, INT buflen )
{
INT retval;
INT wbuflen;
INT abuflen;
LPWSTR wbuf = NULL;
LPSTR abuf = NULL;
if ( buffer != NULL && buflen > 0 )
*buffer = 0;
wbuflen = LoadStringW(instance,resource_id,NULL,0);
if ( !wbuflen )
return 0;
wbuflen ++;
retval = 0;
wbuf = HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) );
wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen);
if ( wbuflen > 0 )
{
abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL);
if ( abuflen > 0 )
{
if ( buffer == NULL || buflen == 0 )
retval = abuflen;
else
{
abuf = HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) );
abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL);
if ( abuflen > 0 )
{
abuflen = min(abuflen,buflen - 1);
memcpy( buffer, abuf, abuflen );
buffer[abuflen] = 0;
retval = abuflen;
}
HeapFree( GetProcessHeap(), 0, abuf );
}
}
}
HeapFree( GetProcessHeap(), 0, wbuf );
return retval;
}
/**********************************************************************
* LoadStringW (USER32.376)
*/
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
LPWSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
WCHAR *p;
int string_num;
int i;
if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
resource_id = (UINT)(-((INT)resource_id));
TRACE("instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
/* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
* 20 - 31. */
hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
RT_STRINGW );
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
p = LockResource(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
TRACE("strlen = %d\n", (int)*p );
if (buffer == NULL) return *p;
i = min(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i * sizeof (WCHAR));
buffer[i] = (WCHAR) 0;
} else {
if (buflen > 1) {
buffer[0] = (WCHAR) 0;
return 0;
}
#if 0
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
#endif
}
TRACE("String loaded !\n");
return i;
}
/* Messages...used by FormatMessage32* (KERNEL32.something)
*
* They can be specified either directly or using a message ID and
* loading them from the resource.
*
* The resourcedata has following format:
* start:
* 0: DWORD nrofentries
* nrofentries * subentry:
* 0: DWORD firstentry
* 4: DWORD lastentry
* 8: DWORD offset from start to the stringentries
*
* (lastentry-firstentry) * stringentry:
* 0: WORD len (0 marks end)
* 2: WORD flags
* 4: CHAR[len-4]
* (stringentry i of a subentry refers to the ID 'firstentry+i')
*
* Yes, ANSI strings in win32 resources. Go figure.
*/
/**********************************************************************
* LoadMessageA (internal)
*/
INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang,
LPSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
PMESSAGE_RESOURCE_DATA mrd;
PMESSAGE_RESOURCE_BLOCK mrb;
PMESSAGE_RESOURCE_ENTRY mre;
int i,slen;
TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
/*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang);
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem);
mre = NULL;
mrb = &(mrd->Blocks[0]);
for (i=mrd->NumberOfBlocks;i--;) {
if ((id>=mrb->LowId) && (id<=mrb->HighId)) {
mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries);
id -= mrb->LowId;
break;
}
mrb++;
}
if (!mre)
return 0;
for (i=id;i--;) {
if (!mre->Length)
return 0;
mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length));
}
slen=mre->Length;
TRACE(" - strlen=%d\n",slen);
i = min(buflen - 1, slen);
if (buffer == NULL)
return slen;
if (i>0) {
lstrcpynA(buffer,(char*)mre->Text,i);
buffer[i]=0;
} else {
if (buflen>1) {
buffer[0]=0;
return 0;
}
}
if (buffer)
TRACE("'%s' copied !\n", buffer);
return i;
}
/**********************************************************************
* EnumResourceTypesA (KERNEL32.90)
*/
WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun,
LONG lParam)
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceTypesA(hmodule,lpfun,lParam);
}
/**********************************************************************
* EnumResourceNamesA (KERNEL32.88)
*/
WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type,
ENUMRESNAMEPROCA lpfun, LONG lParam )
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam);
}
/**********************************************************************
* EnumResourceLanguagesA (KERNEL32.86)
*/
WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type,
LPCSTR name, ENUMRESLANGPROCA lpfun,
LONG lParam)
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam);
}
/**********************************************************************
* LoadResource (KERNEL32.370)
*/
HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
{
return RES_LoadResource( hModule, hRsrc);
}

View file

@ -1,36 +0,0 @@
.file "stubs.c"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC0:
.string "Called unk_%s\n"
.text
.align 4
.globl unk_exp1
.type unk_exp1,@function
unk_exp1:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl $1,-4(%ebp)
movl -4(%ebp),%eax
movl %eax,%ecx
movl %ecx,%edx
sall $4,%edx
subl %eax,%edx
leal 0(,%edx,2),%eax
movl %eax,%edx
addl $export_names,%edx
pushl %edx
pushl $.LC0
call printf
addl $8,%esp
xorl %eax,%eax
jmp .L1
.align 4
.L1:
leave
ret
.Lfe1:
.size unk_exp1,.Lfe1-unk_exp1
.ident "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)"

View file

@ -1,375 +0,0 @@
/*
* Copyright 1998 Marcus Meissner
*/
#include <stdio.h>
#include <string.h>
#include <wine/winbase.h>
#include <wine/windef.h>
#include <wine/winuser.h>
#include <wine/vfw.h>
#include <wine/winestring.h>
#include <wine/driver.h>
#include <avifmt.h>
#define FIXME_(X) printf
#define FIXME printf
long VFWAPI VideoForWindowsVersion(void);
long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
LRESULT VFWAPI ICClose(HIC hic);
LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
#define OpenDriverA DrvOpen
extern HDRVR VFWAPI DrvOpen(long);
#define STORE_ALL \
__asm__ ( \
"push %%ebx\n\t" \
"push %%ecx\n\t" \
"push %%edx\n\t" \
"push %%esi\n\t" \
"push %%edi\n\t"::)
#define REST_ALL \
__asm__ ( \
"pop %%edi\n\t" \
"pop %%esi\n\t" \
"pop %%edx\n\t" \
"pop %%ecx\n\t" \
"pop %%ebx\n\t"::)
typedef struct {
unsigned int uDriverSignature;
void* hDriverModule;
void* DriverProc;
long dwDriverID;
} DRVR;
/***********************************************************************
* VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
* Returns the version in major.minor form.
* In Windows95 this returns 0x040003b6 (4.950)
*/
long VideoForWindowsVersion(void) {
return 0x040003B6; /* 4.950 */
}
/* system.ini: [drivers] */
/***********************************************************************
* ICInfo [MSVFW.33]
* Get information about an installable compressor. Return TRUE if there
* is one.
*/
int VFWAPI
ICInfo(
long fccType, /* [in] type of compressor ('vidc') */
long fccHandler, /* [in] <n>th compressor */
ICINFO *lpicinfo /* [out] information about compressor */
) {
char type[5],buf[2000];
memcpy(type,&fccType,4);type[4]=0;
TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
/* does OpenDriver/CloseDriver */
lpicinfo->dwSize = sizeof(ICINFO);
lpicinfo->fccType = fccType;
lpicinfo->dwFlags = 0;
/*
if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
char *s = buf;
while (*s) {
if (!lstrncmpiA(type,s,4)) {
if(!fccHandler--) {
lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
return TRUE;
}
}
s=s+lstrlenA(s)+1;
}
}
*/
return TRUE;
}
/***********************************************************************
* ICOpen [MSVFW.37]
* Opens an installable compressor. Return special handle.
*/
HIC VFWAPI
ICOpen(long fccType,long fccHandler,unsigned int wMode) {
char type[5],handler[5],codecname[20];
ICOPEN icopen;
HDRVR hdrv;
WINE_HIC *whic;
memcpy(type,&fccType,4);type[4]=0;
memcpy(handler,&fccHandler,4);handler[4]=0;
TRACE("(%s,%s,0x%08lx)\n",type,handler,(long)wMode);
sprintf(codecname,"%s.%s",type,handler);
/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
* same layout as ICOPEN
*/
icopen.fccType = fccType;
icopen.fccHandler = fccHandler;
icopen.dwSize = sizeof(ICOPEN);
icopen.dwFlags = wMode;
/* FIXME: do we need to fill out the rest too? */
// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
hdrv=OpenDriverA((long)&icopen);
/*
if (!hdrv) {
if (!strcasecmp(type,"vids")) {
sprintf(codecname,"vidc.%s",handler);
fccType = mmioFOURCC('v','i','d','c');
}
// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
hdrv=OpenDriverA((long)&icopen);
*/
if (!hdrv)
return 0;
// }
whic = (WINE_HIC*)my_mreq(sizeof(WINE_HIC), 0);
whic->hdrv = hdrv;
whic->driverproc= ((DRVR*)hdrv)->DriverProc;
// whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(long)&icopen);
whic->private = ((DRVR*)hdrv)->dwDriverID;
return (HIC)whic;
}
/***********************************************************************
* ICOpenFunction [MSVFW.38]
*/
HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode,
void* lpfnHandler) {
char type[5],handler[5];
HIC hic;
WINE_HIC *whic;
memcpy(type,&fccType,4);type[4]=0;
memcpy(handler,&fccHandler,4);handler[4]=0;
FIXME("(%s,%s,%d,%p), stub!\n",type,handler,wMode,lpfnHandler);
hic = ICOpen(fccType,fccHandler,wMode);
if (!hic)
return hic;
whic = (WINE_HIC*)hic;
whic->driverproc = lpfnHandler;
return hic;
}
/***********************************************************************
* ICGetInfo [MSVFW.30]
*/
LRESULT VFWAPI
ICGetInfo(HIC hic,ICINFO *picinfo,long cb) {
LRESULT ret;
TRACE("(0x%08lx,%p,%ld)\n",(long)hic,picinfo,cb);
ret = ICSendMessage(hic,ICM_GETINFO,(long)picinfo,cb);
TRACE(" -> 0x%08lx\n",ret);
return ret;
}
/***********************************************************************
* ICLocate [MSVFW.35]
*/
HIC VFWAPI
ICLocate(
long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn,
LPBITMAPINFOHEADER lpbiOut, short wMode
) {
char type[5],handler[5];
HIC hic;
long querymsg;
switch (wMode) {
case ICMODE_FASTCOMPRESS:
case ICMODE_COMPRESS:
querymsg = ICM_COMPRESS_QUERY;
break;
case ICMODE_DECOMPRESS:
case ICMODE_FASTDECOMPRESS:
querymsg = ICM_DECOMPRESS_QUERY;
break;
case ICMODE_DRAW:
querymsg = ICM_DRAW_QUERY;
break;
default:
FIXME("Unknown mode (%d)\n",wMode);
return 0;
}
/* Easy case: handler/type match, we just fire a query and return */
hic = ICOpen(fccType,fccHandler,wMode);
if (hic) {
if (!ICSendMessage(hic,querymsg,(long)lpbiIn,(long)lpbiOut))
return hic;
ICClose(hic);
}
type[4]='\0';memcpy(type,&fccType,4);
handler[4]='\0';memcpy(handler,&fccHandler,4);
if (fccType==streamtypeVIDEO) {
hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
if (hic)
return hic;
}
FIXME("(%s,%s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
return 0;
}
/***********************************************************************
* ICCompress [MSVFW.23]
*/
long VFWAPIV
ICCompress(
HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
) {
ICCOMPRESS iccmp;
iccmp.dwFlags = dwFlags;
iccmp.lpbiOutput = lpbiOutput;
iccmp.lpOutput = lpData;
iccmp.lpbiInput = lpbiInput;
iccmp.lpInput = lpBits;
iccmp.lpckid = lpckid;
iccmp.lpdwFlags = lpdwFlags;
iccmp.lFrameNum = lFrameNum;
iccmp.dwFrameSize = dwFrameSize;
iccmp.dwQuality = dwQuality;
iccmp.lpbiPrev = lpbiPrev;
iccmp.lpPrev = lpPrev;
return ICSendMessage(hic,ICM_COMPRESS,(long)&iccmp,sizeof(iccmp));
}
/***********************************************************************
* ICDecompress [MSVFW.26]
*/
long VFWAPIV
ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits) {
ICDECOMPRESS icd;
int result;
icd.dwFlags = dwFlags;
icd.lpbiInput = lpbiFormat;
icd.lpInput = lpData;
icd.lpbiOutput = lpbi;
icd.lpOutput = lpBits;
icd.ckid = 0;
STORE_ALL;
result=ICSendMessage(hic,ICM_DECOMPRESS,(long)&icd,sizeof(icd));
REST_ALL;
return result;
}
/***********************************************************************
* ICSendMessage [MSVFW.40]
*/
LRESULT VFWAPI
ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2) {
LRESULT ret;
WINE_HIC *whic = (WINE_HIC*)hic;
char qw[200];
#define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx)\n",(long)hic,lParam1,lParam2);break;
/*
switch (msg) {
XX(ICM_ABOUT)
XX(ICM_GETINFO)
XX(ICM_COMPRESS_FRAMES_INFO)
XX(ICM_COMPRESS_GET_FORMAT)
XX(ICM_COMPRESS_GET_SIZE)
XX(ICM_COMPRESS_QUERY)
XX(ICM_COMPRESS_BEGIN)
XX(ICM_COMPRESS)
XX(ICM_COMPRESS_END)
XX(ICM_DECOMPRESS_GET_FORMAT)
XX(ICM_DECOMPRESS_QUERY)
XX(ICM_DECOMPRESS_BEGIN)
XX(ICM_DECOMPRESS)
XX(ICM_DECOMPRESS_END)
XX(ICM_DECOMPRESS_SET_PALETTE)
XX(ICM_DECOMPRESS_GET_PALETTE)
XX(ICM_DRAW_QUERY)
XX(ICM_DRAW_BEGIN)
XX(ICM_DRAW_GET_PALETTE)
XX(ICM_DRAW_START)
XX(ICM_DRAW_STOP)
XX(ICM_DRAW_END)
XX(ICM_DRAW_GETTIME)
XX(ICM_DRAW)
XX(ICM_DRAW_WINDOW)
XX(ICM_DRAW_SETTIME)
XX(ICM_DRAW_REALIZE)
XX(ICM_DRAW_FLUSH)
XX(ICM_DRAW_RENDERBUFFER)
XX(ICM_DRAW_START_PLAY)
XX(ICM_DRAW_STOP_PLAY)
XX(ICM_DRAW_SUGGESTFORMAT)
XX(ICM_DRAW_CHANGEPALETTE)
XX(ICM_GETBUFFERSWANTED)
XX(ICM_GETDEFAULTKEYFRAMERATE)
XX(ICM_DECOMPRESSEX_BEGIN)
XX(ICM_DECOMPRESSEX_QUERY)
XX(ICM_DECOMPRESSEX)
XX(ICM_DECOMPRESSEX_END)
XX(ICM_SET_STATUS_PROC)
default:
FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(long)hic,(long)msg,lParam1,lParam2);
}
*/
// if (whic->driverproc) {
// FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx), calling %p\n",(long)hic,(long)msg,lParam1,lParam2,whic->driverproc);
// printf("private=%x\n", whic->private);
__asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw));
STORE_ALL;
/*__asm__
(
"pushl %eax\n\t"
"movl $0xf,%eax\n\t"
"movw %ax, %fs\n\t"
"popl %eax\n\t"
);*/
ret = whic->driverproc(whic->private,1,msg,lParam1,lParam2);
REST_ALL;
__asm__ __volatile__ ("frstor (%0)\n\t": :"r"(&qw));
// } else
// ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
// TRACE(" -> 0x%08lx\n",ret);
return ret;
}
/***********************************************************************
* ICClose [MSVFW.22]
*/
LRESULT VFWAPI ICClose(HIC hic) {
WINE_HIC *whic = (WINE_HIC*)hic;
TRACE("(%d).\n",hic);
/* FIXME: correct? */
// CloseDriver(whic->hdrv,0,0);
DrvClose(whic->hdrv);
//#warning FIXME: DrvClose
my_release(whic);
return 0;
}
int VFWAPI ICDoSomething()
{
}

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
int ext_unknown();

View file

@ -1,55 +0,0 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/***********************************************************************
* Wine specific - Win32
*/
typedef struct _WINE_ACMDRIVERID *PWINE_ACMDRIVERID;
typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER;
typedef struct _WINE_ACMOBJ
{
PWINE_ACMDRIVERID pACMDriverID;
} WINE_ACMOBJ, *PWINE_ACMOBJ;
typedef struct _WINE_ACMDRIVER
{
WINE_ACMOBJ obj;
HDRVR hDrvr;
DRIVERPROC pfnDriverProc;
PWINE_ACMDRIVER pNextACMDriver;
} WINE_ACMDRIVER;
typedef struct _WINE_ACMSTREAM
{
WINE_ACMOBJ obj;
PWINE_ACMDRIVER pDrv;
ACMDRVSTREAMINSTANCE drvInst;
HACMDRIVER hAcmDriver;
} WINE_ACMSTREAM, *PWINE_ACMSTREAM;
typedef struct _WINE_ACMDRIVERID
{
LPSTR pszDriverAlias;
LPSTR pszFileName;
HINSTANCE hInstModule; /* NULL if global */
DWORD dwProcessID; /* ID of process which installed a local driver */
WIN_BOOL bEnabled;
PWINE_ACMDRIVER pACMDriverList;
PWINE_ACMDRIVERID pNextACMDriverID;
PWINE_ACMDRIVERID pPrevACMDriverID;
} WINE_ACMDRIVERID;
/* From internal.c */
extern HANDLE MSACM_hHeap;
extern PWINE_ACMDRIVERID MSACM_pFirstACMDriverID;
extern PWINE_ACMDRIVERID MSACM_pLastACMDriverID;
PWINE_ACMDRIVERID MSACM_RegisterDriver(
LPSTR pszDriverAlias, LPSTR pszFileName,
HINSTANCE hinstModule);
void MSACM_RegisterAllDrivers(void);
PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p);
void MSACM_UnregisterAllDrivers(void);
PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID);
PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver);
PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj);