Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
GNOME
GIMP
Commits
bbc1c947
Commit
bbc1c947
authored
May 25, 2005
by
Sven Neumann
Committed by
Sven Neumann
May 25, 2005
Browse files
added more properties.
2005-05-26 Sven Neumann <sven@gimp.org> * app/core/gimpdata.c: added more properties.
parent
59cb5d75
Changes
4
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
bbc1c947
2005-05-26 Sven Neumann <sven@gimp.org>
* app/core/gimpdata.c: added more properties.
2005-05-26 Sven Neumann <sven@gimp.org>
* app/core/gimpdata.[ch]: added MIME type as a construct property
...
...
app/core/gimp-transform-resize.c
0 → 100644
View file @
bbc1c947
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include
"config.h"
#include
<glib-object.h>
#include
"libgimpmath/gimpmath.h"
#include
"core-types.h"
#include
"gimp-transform-resize.h"
#if defined (HAVE_FINITE)
#define FINITE(x) finite(x)
#elif defined (HAVE_ISFINITE)
#define FINITE(x) isfinite(x)
#elif defined (G_OS_WIN32)
#define FINITE(x) _finite(x)
#else
#error "no FINITE() implementation available?!"
#endif
#define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d))
#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d))
typedef
struct
{
gdouble
x
,
y
;
}
Point
;
typedef
struct
{
gint
xmin
,
xmax
;
gint
ymin
,
ymax
;
gdouble
m
,
b
;
/* y = mx + b */
gboolean
top
,
right
;
}
Edge
;
static
void
gimp_transform_resize_adjust
(
gdouble
dx1
,
gdouble
dy1
,
gdouble
dx2
,
gdouble
dy2
,
gdouble
dx3
,
gdouble
dy3
,
gdouble
dx4
,
gdouble
dy4
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
);
static
void
gimp_transform_resize_crop
(
gdouble
dx1
,
gdouble
dy1
,
gdouble
dx2
,
gdouble
dy2
,
gdouble
dx3
,
gdouble
dy3
,
gdouble
dx4
,
gdouble
dy4
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
);
/*
* This function wants to be passed the inverse transformation matrix!!
*/
void
gimp_transform_resize_boundary
(
const
GimpMatrix3
*
inv
,
GimpTransformResize
resize
,
gint
u1
,
gint
v1
,
gint
u2
,
gint
v2
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
)
{
gdouble
dx1
,
dx2
,
dx3
,
dx4
;
gdouble
dy1
,
dy2
,
dy3
,
dy4
;
g_return_if_fail
(
inv
!=
NULL
);
/* initialize with the original boundary */
*
x1
=
u1
;
*
y1
=
v1
;
*
x2
=
u2
;
*
y2
=
v2
;
if
(
resize
==
GIMP_TRANSFORM_SIZE_CLIP
)
return
;
gimp_matrix3_transform_point
(
inv
,
u1
,
v1
,
&
dx1
,
&
dy1
);
gimp_matrix3_transform_point
(
inv
,
u2
,
v1
,
&
dx2
,
&
dy2
);
gimp_matrix3_transform_point
(
inv
,
u1
,
v2
,
&
dx3
,
&
dy3
);
gimp_matrix3_transform_point
(
inv
,
u2
,
v2
,
&
dx4
,
&
dy4
);
/* check if the transformation matrix is valid at all */
if
(
!
FINITE
(
dx1
)
||
!
FINITE
(
dy1
)
||
!
FINITE
(
dx2
)
||
!
FINITE
(
dy2
)
||
!
FINITE
(
dx3
)
||
!
FINITE
(
dy3
)
||
!
FINITE
(
dx4
)
||
!
FINITE
(
dy4
))
{
g_warning
(
"invalid transform matrix"
);
resize
=
GIMP_TRANSFORM_SIZE_CLIP
;
}
switch
(
resize
)
{
case
GIMP_TRANSFORM_SIZE_ADJUST
:
gimp_transform_resize_adjust
(
dx1
,
dy1
,
dx2
,
dy2
,
dx3
,
dy3
,
dx4
,
dy4
,
x1
,
y1
,
x2
,
y2
);
break
;
case
GIMP_TRANSFORM_SIZE_CLIP
:
/* we are all done already */
break
;
case
GIMP_TRANSFORM_SIZE_CROP
:
gimp_transform_resize_crop
(
dx1
,
dy1
,
dx2
,
dy2
,
dx3
,
dy3
,
dx4
,
dy4
,
x1
,
y1
,
x2
,
y2
);
break
;
}
if
(
*
x1
==
*
x2
)
(
*
x2
)
++
;
if
(
*
y1
==
*
y2
)
(
*
y2
)
++
;
}
static
void
gimp_transform_resize_adjust
(
gdouble
dx1
,
gdouble
dy1
,
gdouble
dx2
,
gdouble
dy2
,
gdouble
dx3
,
gdouble
dy3
,
gdouble
dx4
,
gdouble
dy4
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
)
{
*
x1
=
(
gint
)
floor
(
MIN4
(
dx1
,
dx2
,
dx3
,
dx4
));
*
y1
=
(
gint
)
floor
(
MIN4
(
dy1
,
dy2
,
dy3
,
dy4
));
*
x2
=
(
gint
)
ceil
(
MAX4
(
dx1
,
dx2
,
dx3
,
dx4
));
*
y2
=
(
gint
)
ceil
(
MAX4
(
dy1
,
dy2
,
dy3
,
dy4
));
}
static
void
edge_init
(
Edge
*
edge
,
const
Point
*
p
,
const
Point
*
q
)
{
edge
->
xmin
=
MIN
(
ceil
(
p
->
x
),
ceil
(
q
->
x
));
edge
->
xmax
=
MAX
(
floor
(
p
->
x
),
floor
(
q
->
x
));
edge
->
ymin
=
MIN
(
ceil
(
p
->
y
),
ceil
(
q
->
y
));
edge
->
ymax
=
MAX
(
floor
(
p
->
y
),
floor
(
q
->
y
));
edge
->
top
=
p
->
x
>
q
->
x
;
edge
->
right
=
p
->
y
>
q
->
y
;
edge
->
m
=
(
q
->
y
-
p
->
y
)
/
(
q
->
x
-
p
->
x
);
edge
->
b
=
p
->
y
-
edge
->
m
*
p
->
x
;
}
static
const
Edge
*
find_edge
(
const
Edge
*
edges
,
gint
x
,
gboolean
top
)
{
const
Edge
*
emax
=
edges
;
gint
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
const
Edge
*
e
=
edges
+
i
;
if
(
e
->
xmin
==
x
&&
e
->
xmax
!=
e
->
xmin
&&
((
e
->
top
&&
top
)
||
(
!
e
->
top
&&
!
top
)))
emax
=
e
;
}
return
emax
;
}
/* find largest pixel completely inside;
* look through all edges for intersection
*/
static
gint
intersect_x
(
const
Edge
*
edges
,
gint
y
)
{
gdouble
x0
=
0
;
gdouble
x1
=
0
;
gint
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
if
(
edges
[
i
].
right
&&
edges
[
i
].
ymin
<=
y
&&
edges
[
i
].
ymax
>=
y
)
{
x0
=
(
double
)
(
y
+
0
.
5
-
edges
[
i
].
b
)
/
edges
[
i
].
m
;
x1
=
(
double
)
(
y
-
0
.
5
-
edges
[
i
].
b
)
/
edges
[
i
].
m
;
}
return
(
gint
)
floor
(
MIN
(
x0
,
x1
));
}
static
gint
intersect_y
(
const
Edge
*
edge
,
gint
xi
)
{
gdouble
yfirst
=
edge
->
m
*
(
xi
-
0
.
5
)
+
edge
->
b
;
gdouble
ylast
=
edge
->
m
*
(
xi
+
0
.
5
)
+
edge
->
b
;
return
(
gint
)
floor
(
edge
->
top
?
MAX
(
yfirst
,
ylast
)
:
MIN
(
yfirst
,
ylast
));
}
static
void
gimp_transform_resize_crop
(
gdouble
dx1
,
gdouble
dy1
,
gdouble
dx2
,
gdouble
dy2
,
gdouble
dx3
,
gdouble
dy3
,
gdouble
dx4
,
gdouble
dy4
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
)
{
Point
points
[
4
];
Edge
edges
[
4
];
const
Point
*
a
;
const
Point
*
b
;
const
Edge
*
top
;
const
Edge
*
bottom
;
gint
*
px
;
gint
xmin
,
ymin
;
gint
xmax
,
ymax
;
gint
maxarea
=
0
;
gint
xi
,
y
;
gint
i
;
/* fill in the points array */
points
[
0
].
x
=
dx1
;
points
[
0
].
y
=
dy1
;
points
[
1
].
x
=
dx2
;
points
[
1
].
y
=
dy2
;
points
[
2
].
x
=
dx3
;
points
[
2
].
y
=
dy3
;
points
[
3
].
x
=
dx4
;
points
[
3
].
y
=
dy4
;
/* create an array of edges */
for
(
i
=
0
,
a
=
points
+
3
,
b
=
points
;
i
<
4
;
i
++
,
a
=
b
,
b
++
)
edge_init
(
edges
+
i
,
a
,
b
);
/* determine the bounding box */
xmin
=
edges
[
0
].
xmin
;
xmax
=
edges
[
0
].
xmax
;
ymin
=
edges
[
0
].
ymin
;
ymax
=
edges
[
0
].
ymax
;
for
(
i
=
1
;
i
<
4
;
i
++
)
{
const
Edge
*
edge
=
edges
+
i
;
if
(
edge
->
xmin
<
xmin
)
xmin
=
edge
->
xmin
;
if
(
edge
->
xmax
>
xmax
)
xmax
=
edge
->
xmax
;
if
(
edge
->
ymin
<
ymin
)
ymin
=
edge
->
ymin
;
if
(
edge
->
ymax
>
ymax
)
ymax
=
edge
->
ymax
;
}
g_printerr
(
"%d, %d -> %d, %d
\n
"
,
xmin
,
ymin
,
xmax
,
ymax
);
px
=
g_new
(
gint
,
ymax
-
ymin
+
1
);
for
(
y
=
ymin
,
i
=
0
;
y
<=
ymax
;
y
++
,
i
++
)
px
[
i
]
=
intersect_x
(
edges
,
y
);
top
=
find_edge
(
edges
,
xmin
,
TRUE
);
bottom
=
find_edge
(
edges
,
xmax
,
FALSE
);
g_printerr
(
"top: %d, %d -> %d, %d
\n
"
,
top
->
xmin
,
top
->
ymin
,
top
->
xmax
,
top
->
ymax
);
g_printerr
(
"bottom: %d, %d -> %d, %d
\n
"
,
bottom
->
xmin
,
bottom
->
ymin
,
bottom
->
xmax
,
bottom
->
ymax
);
for
(
xi
=
xmin
;
xi
<
xmax
;
xi
++
)
{
gint
ylo
,
yhi
;
ymin
=
intersect_y
(
top
,
xi
);
ymax
=
intersect_y
(
bottom
,
xi
);
for
(
ylo
=
ymax
;
ylo
>=
ymin
;
ylo
--
)
{
for
(
yhi
=
ymin
;
yhi
<=
ymax
;
yhi
++
)
{
if
(
yhi
>
ylo
)
{
gint
xlo
=
px
[
ylo
-
ymin
];
gint
xhi
=
px
[
yhi
-
ymin
];
gint
width
=
MIN
(
xlo
,
xhi
)
-
xi
;
gint
height
=
yhi
-
ylo
;
gint
area
=
width
*
height
;
if
(
area
>
maxarea
)
{
maxarea
=
area
;
*
x1
=
xi
;
*
y1
=
ylo
;
*
x2
=
xi
+
width
;
*
y2
=
ylo
+
height
;
}
}
}
}
if
(
xi
==
top
->
xmax
)
top
=
find_edge
(
edges
,
xi
,
TRUE
);
if
(
xi
==
bottom
->
xmax
)
bottom
=
find_edge
(
edges
,
xi
,
FALSE
);
}
g_printerr
(
"%d, %d -> %d, %d
\n
"
,
*
x1
,
*
y1
,
*
x2
,
*
y2
);
g_free
(
px
);
}
app/core/gimp-transform-resize.h
0 → 100644
View file @
bbc1c947
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_TRANSFORM_RESIZE_H__
#define __GIMP_TRANSFORM_RESIZE_H__
void
gimp_transform_resize_boundary
(
const
GimpMatrix3
*
inv
,
GimpTransformResize
resize
,
gint
u1
,
gint
v1
,
gint
u2
,
gint
v2
,
gint
*
x1
,
gint
*
y1
,
gint
*
x2
,
gint
*
y2
);
#endif
/* __GIMP_TRANSFORM_RESIZE_H__ */
app/core/gimpdata.c
View file @
bbc1c947
...
...
@@ -54,6 +54,9 @@ enum
enum
{
PROP_0
,
PROP_FILENAME
,
PROP_WRITABLE
,
PROP_DELETABLE
,
PROP_MIME_TYPE
};
...
...
@@ -141,9 +144,23 @@ gimp_data_class_init (GimpDataClass *klass)
klass
->
get_extension
=
NULL
;
klass
->
duplicate
=
NULL
;
g_object_class_install_property
(
object_class
,
PROP_FILENAME
,
g_param_spec_string
(
"filename"
,
NULL
,
NULL
,
NULL
,
G_PARAM_READWRITE
));
g_object_class_install_property
(
object_class
,
PROP_WRITABLE
,
g_param_spec_boolean
(
"writable"
,
NULL
,
NULL
,
FALSE
,
G_PARAM_READWRITE
));
g_object_class_install_property
(
object_class
,
PROP_WRITABLE
,
g_param_spec_boolean
(
"deletable"
,
NULL
,
NULL
,
FALSE
,
G_PARAM_READWRITE
));
g_object_class_install_property
(
object_class
,
PROP_MIME_TYPE
,
g_param_spec_string
(
"mime-type"
,
NULL
,
NULL
,
g_param_spec_string
(
"mime-type"
,
NULL
,
NULL
,
NULL
,
G_PARAM_READWRITE
|
G_PARAM_CONSTRUCT_ONLY
));
...
...
@@ -192,6 +209,21 @@ gimp_data_set_property (GObject *object,
switch
(
property_id
)
{
case
PROP_FILENAME
:
gimp_data_set_filename
(
data
,
g_value_get_string
(
value
),
data
->
writable
,
data
->
deletable
);
break
;
case
PROP_WRITABLE
:
data
->
writable
=
g_value_get_boolean
(
value
);
break
;
case
PROP_DELETABLE
:
data
->
deletable
=
g_value_get_boolean
(
value
);
break
;
case
PROP_MIME_TYPE
:
if
(
g_value_get_string
(
value
))
data
->
mime_type
=
g_quark_from_string
(
g_value_get_string
(
value
));
...
...
@@ -215,6 +247,18 @@ gimp_data_get_property (GObject *object,
switch
(
property_id
)
{
case
PROP_FILENAME
:
g_value_set_string
(
value
,
data
->
filename
);
break
;
case
PROP_WRITABLE
:
g_value_set_boolean
(
value
,
data
->
writable
);
break
;
case
PROP_DELETABLE
:
g_value_set_boolean
(
value
,
data
->
deletable
);
break
;
case
PROP_MIME_TYPE
:
g_value_set_string
(
value
,
g_quark_to_string
(
data
->
mime_type
));
break
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment