Compare commits

...

483 Commits

Author SHA1 Message Date
Shyotl
69e0738096 Fix crash when using edit appearance. 2013-01-05 22:05:53 -06:00
Shyotl
0b31537bfe Updated llfile so that llofstream and llifstream actually work when given a file handle. 2013-01-05 17:13:35 -06:00
Shyotl
776a977824 Completed code migration to LLAvatarAppearance 2013-01-05 17:12:02 -06:00
Shyotl
5cf091b8b2 Completed code migration from LLViewerWearable to LLWearable. 2013-01-05 00:33:55 -06:00
Shyotl
bea4bc6a1a Brought over lltexglobalcolor 2013-01-04 21:15:35 -06:00
Shyotl
9596514c79 Dragged over lltexlayer, lldriverparam, lllocaltextureobject, llwearabledata 2013-01-04 20:50:35 -06:00
Shyotl
5ada2d4b6f OSX was choking on transformfeedback shaders. Make failure to load such shaders non-critical to the shader loading process. Also clean up glColorMask state properly in wlsky. 2012-12-24 17:55:05 -06:00
Shyotl
dd15b9234f Migrated LLTexLayerParams. Renamed LLTexLayerSet(Buffer) to LLViewerTexLayerSet(Buffer), and provided simple bases in llappearance/lltexlayer.h to mimic new usage. Reworked various bits to work with these changes, and performed some basic cleanup of LLVOAvatar(Self) 2012-12-24 17:20:46 -06:00
Shyotl
d03d145be4 Pulled LLAvatarJointMesh out of LLViewerJointMesh. 2012-12-23 18:33:35 -06:00
Shyotl
1083d7e0ef Added LLGLTexture. Virtually completely virtual for now. Also added LLTextureManagerBridge, although not yet utilized. 2012-12-22 23:58:42 -06:00
Shyotl
cdaa4b4e99 Clear up a few issues revealed upon forced full recompile. (VS is dumb sometimes) 2012-12-22 23:44:43 -06:00
Shyotl
295fcb53b0 Migrate llviewervisualparams to llappearance project. 2012-12-22 17:17:00 -06:00
Shyotl
389c35e08e Pulled LLAvatarJoint out of LLViewerJoint 2012-12-22 16:30:38 -06:00
Shyotl
003aa6a4eb Migrate llpoly* files to llappearance 2012-12-20 02:55:34 -06:00
Shyotl
f9d205b869 Intermediary commit. Exploit virtuals to 'emulate' real llavatarappearance.h. 2012-12-20 02:53:45 -06:00
Shyotl
e08afcb963 Created llappearance project. Migrated llvoavatardefines and llwearabletype. 2012-12-20 00:00:17 -06:00
Shyotl
3750123e43 Obsessive excessive clearing of glow rendertargets, as they still occasionally act weird. 2012-12-19 19:08:10 -06:00
Shyotl
b20f39d09f Retain shader error logs across entire session. 2012-12-19 19:06:59 -06:00
Shyotl
7eda762c28 Cheapo sun bloom contribution in deferred. 2012-12-19 02:30:44 -06:00
Shyotl
0460769eea Unified moon/star rendering to share same shader. Also now actually using deferred shader when performing deferred rendering. 2012-12-19 01:52:10 -06:00
Shyotl
d3939c785d Fixup scroll list column header resizing. 2012-12-18 18:27:59 -06:00
Shyotl
184882e916 Remove dead code from llfloaterworldmap, and a tweak to lluictrl that I could've sworn I already did. 2012-12-16 13:30:29 -06:00
Shyotl
6c9df4574c Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git 2012-12-14 16:59:49 -06:00
Shyotl
034c83f996 Added trivial diagnostic message regarding teleport handling. 2012-12-14 16:28:18 -06:00
Shyotl
2b582b169b Mute list, now with 100% more text-appearing-ness, and 20% new shinies (mute-type icons, multi-select unmute, and displayname support). 2012-12-14 16:24:51 -06:00
Inusaito Sayori
38f59e640c We canUndo and canRedo when we have a MoveableObject, not necessarily an EditableObject 2012-12-14 11:30:56 -05:00
Inusaito Sayori
af1e7b346e Vignette is Awesome, its panel should reflect that! 2012-12-13 16:53:19 -05:00
Shyotl
7a2f572eaa Merge branch 'master' of https://github.com/AlericInglewood/SingularityViewer.git 2012-12-12 13:13:26 -06:00
Aleric Inglewood
5fe0820e13 Login crash bug fix.
XMLRPCResponder constructor was missing.
This fixes the following crash signature:

VIEWER      : 2012-12-12T14:25:13Z INFO("AppInit"): setStartupState: Startup state changing from STATE_LOGIN_NO_DATA_YET to STATE_LOGIN_DOWNLOADING
VIEWER      : 2012-12-12T14:25:14Z INFO("AppInit"): transferRate: Buffer size:   1308 B
VIEWER      : 2012-12-12T14:25:14Z INFO("AppInit"): transferRate: Transfer rate: 11 kb/s

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff33df7f5 in XMLRPC_RequestGetData () from /usr/lib/x86_64-linux-gnu/libxmlrpc-epi.so.0
(gdb) bt

Reason was that if the server replied with some error code then
mResponse was undefined.

I also added code to retry three times in that case;
the http status code that I get was 503, which really
mean "Service *temporarily* unavailable", so a retry
is in order.
2012-12-12 16:14:32 +01:00
Shyotl
28a4101d4d Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git 2012-12-12 03:12:08 -06:00
Shyotl
cc22edcce3 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2012-12-12 03:11:50 -06:00
Shyotl
2424d2a082 A little bit of postprocess shader tinkering. 2012-12-12 03:10:05 -06:00
Lirusaito
b1ccb70277 Added isClipboardPasteableAsCopy() to decide when not to show Paste As Copy 2012-12-11 15:15:41 -05:00
Shyotl
c641cc6394 Fix object list in About Land floater. (whoops) 2012-12-10 20:02:47 -06:00
Shyotl
9a6568f5e8 A little bit of bloom on indirect shiny reflections in deferred. 2012-12-10 20:00:57 -06:00
Shyotl
3627b33eec Reworked flexi update handling a little bit. 2012-12-10 19:55:17 -06:00
Lirusaito
702eb95b84 Add Paste As Copy to inventory menu...
The opposite of Paste As Link, this will make copies of everything in the paste buffer,
allowing the user to copy bunches of items or links and simply paste them to make new copies.

Also appears when not needed... unsure how to go about removing, maybe comment out in release?
2012-12-10 19:39:55 -05:00
Lirusaito
03f191f47d Satisfy Issue 494: Inventory: Copy links (without "find original")
http://code.google.com/p/singularity-viewer/issues/detail?id=494
Patch by Kitty Barnett, slightly modified by myself.
2012-12-10 16:42:06 -05:00
Lirusaito
813a4b0200 Fix warning: unused variable ‘len’ in release builds. 2012-12-10 13:26:48 -05:00
Lirusaito
c24950b261 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer
Conflicts:
	indra/newview/llfloateravatarpicker.cpp - Includes to v-d style, since plain alphabetical just won't cut it. Shyotl's changes for name system, here.
	indra/newview/llpanelgroupinvite.cpp - Shyotl's changes for name system, here.

Also corrected new README to have less typos and be slightly more accurate.
2012-12-10 11:24:25 -05:00
Shyotl
806abb1985 Reduce required number of glow rendertargets by 1... 2012-12-10 01:31:57 -06:00
Shyotl
a4591a5eaa Fix for friends list not resorting upon avatar online status change. Also did some minor cleanup 2012-12-09 17:05:54 -06:00
Siana Gearz
018737eb15 Blind Windows compile fix 2012-12-09 04:53:35 +01:00
Siana Gearz
3e5bd4e13b Linux build fixes 2012-12-09 04:25:01 +01:00
Siana Gearz
98ec8b9910 Merge branch 'master' of https://github.com/Shyotl/SingularityViewer 2012-12-09 03:27:52 +01:00
Siana Gearz
d2a966f363 OpenJPEG 1.5.2 2012-12-09 02:10:16 +01:00
Shyotl
8a7cc9259c Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2012-12-08 17:13:07 -06:00
Shyotl
382fc710e5 Disable octree statistics gathering. 2012-12-08 17:07:15 -06:00
Shyotl
be4229867a Occlusion-fudge was incorrectly defaulting to zero. 2012-12-08 16:56:06 -06:00
Shyotl
6b05022530 Applied Tofu Linden's SSAO improvements. e189d55a7b 2012-12-08 16:51:38 -06:00
Shyotl
08a3828cc9 Applied Tofu Linden's water atmospherics improvements.
59f73ee6a1 &
43fdcb8d84
2012-12-08 16:50:35 -06:00
Shyotl
d5efedf51b Merge branch 'master' of https://github.com/AlericInglewood/SingularityViewer.git into CT3Merge 2012-12-08 13:39:55 -06:00
Aleric Inglewood
8394a96fa8 Fix of TEXTBOX of group owned object.
Fixes http://code.google.com/p/singularity-viewer/issues/detail?id=548
2012-12-08 20:30:00 +01:00
Shyotl
4f7e869509 Merge branch 'master' of https://github.com/AlericInglewood/SingularityViewer.git into CT3Merge 2012-12-08 01:03:29 -06:00
Shyotl
7aac61859f Avoid excess calls to gGL.flush when bound texture hasn't actually changed. 2012-12-08 01:01:47 -06:00
Shyotl
3ba967bdc1 Update to LLAvatarNameCache and consumers. 2012-12-08 00:59:37 -06:00
Shyotl
9fb4e677a6 Updates to LLScrollListCtrl and related inter-dependencies. Also added ability to set face texture to 'None' (LLUUID::null). 2012-12-08 00:56:58 -06:00
Lirusaito
1ffb5aa6fe LLFloaterAvatarList RLVa: Don't announce people are in range when the user is blind. 2012-12-06 22:17:44 -05:00
Lirusaito
0100cd2f36 More of e2b011590d
Fixing up the name system, missed two parts.
2012-12-06 21:04:06 -05:00
Aleric Inglewood
d6b486524c Fix include of reader.h 2012-12-07 00:31:10 +01:00
Shyotl
f80394fc02 llpreviewgesture.cpp changes snuck past me in an early commit. 2012-12-06 17:19:10 -06:00
Shyotl
e750c598be Updated avatar radar. Focusprev/focusnext now obey the order of the actual displayed avatar list. Cleaned up some commit callbacks. 2012-12-06 17:16:44 -06:00
Shyotl
26191dd274 Migrate to boost::bind for a bunch of CommitCallbacks. Converted several static member functions to nonstatic member functions 2012-12-06 17:13:17 -06:00
Aleric Inglewood
12171f6cd9 Merge commit '5947769812369a7988a7f1db30df79e6fc0e4787'
Adds important commits from llwebprofile branch
into master which need to go into the next release.
2012-12-05 22:27:21 +01:00
Lirusaito
457276fa5d Merge branch 'master' of https://github.com/DamianZhaoying/SingularityViewer 2012-12-05 13:59:36 -05:00
Lirusaito
7ba21ac4fd Show Highlight and Edit Axis at Root on build floater
Thanks for the help, Naudia Nadezda!
2012-12-05 12:06:10 -05:00
Lirusaito
e2b011590d Fix up the Name System just a little bit more.
Better viewed without space changes
Pretty much add support for sending LLAvatarName and std::string to become a name via the system...
Also a bit of a revert for llcallingcard.cpp in this regard, just allow it to use a callback along with the new support,
but still handle the actual name switching in LLAvatarNameCache.
Fixes a problem I was having with "[NAME] is Online" notifications appearing early on, only.
2012-12-05 01:48:09 -05:00
Shyotl
ef6f411b70 Removed LLUICtrl::setDoubleClickCallback and LLPanel::childSetDoubleClickCallback as they aren't used/needed and complicate things. Added LLPanel::childSetAction overload that accepts boost::singal2::signal (for boost::bind). Now using boost::function for various callbacks in LLScrollListCtrl (for boost::bind). 2012-12-04 21:54:01 -06:00
Lirusaito
2c48161595 Make Baker's Group code compile! Thanks Shyotl~
Note: Large groups still don't load?!
SimConsole cap is needed for Sim Console, won't work without it, keeping it in!
..But it should work with the new ASync one? Maybe needs tweaks, first?

Also switches opening IMs to the gCacheName->getFullName(id, name) system mentioned earlier, my connection has improved!
And makes the Avatar Picker show display names! Yay! (Rearranged the includes there, alphabetical~)
Also fallback to gCacheName->getFullName(id, name) if getting name fails in the new system.. hopefully this will combat occasional big failures.. but it may not work anyway.. maybe my connection is just awful again
2012-12-04 11:54:54 -05:00
Shyotl
ca3e0d2ba9 Use the correct font name. "SANSSERIF_SMALL", not "SANSSERIFSMALL" 2012-12-04 02:59:19 -06:00
Lirusaito
922e234fe9 Baker Linden's group update, added with some care, won't compile,
Note: These changesets removed the some caps in llviewerregion.cpp, I have made a note of these, but left them in.
Please take a look at the Singu Note:'s and Singu: TODO:'s when working on this.
2012-12-04 03:53:05 -05:00
Lirusaito
b9cfd2fae5 Replace the tricky copy-paste-everywhere Display Name system code with a unified function
Only does that, dun believe me? Take a look, oh... it also corrects improper interpretations of the PhoenixNameSystem value: 1 is both, 2 is displays, 0 and anything else is Legacy.
Also replaces a bit of the display name support code with new system... by definition this shouldn't change the log file, only the title of the session..
because of my bad connection during week days, I can not confirm this working 100%,
but if it does end up changing the logs under certain unseen conditions, replace the new name check with gCacheName->getFullName(id, name) but this reallllly shouldn't happen!
2012-12-04 00:36:12 -05:00
Shyotl
ce3511f7ea Misc changes via v3 merge. Nothing big. 2012-12-03 15:03:52 -06:00
Shyotl
a8e1bd1538 'Save scripts in inventory as Mono scripts instead of LSL2' checkbox was not functioning. For whatever reason it was not implemented in the actual panel, and referenced the incorrect setting. The proper setting will be 'SaveInventoryScriptsAsMono' not 'SaveScriptsAsMono' 2012-12-03 11:33:24 -06:00
Lirusaito
0876c8c2bf Go away when idle checkbox added to General Preferences. 2012-12-02 22:14:36 -05:00
Shyotl
0554ecae5c Added explicit texture reloading. Accessable in the 'tools' submenus for the agent, avatars, and selected objects. 2012-12-02 17:06:54 -06:00
Lirusaito
cfbc8a23f7 Transaction Notifications are now optionally Notify Tips for those who don't want them to collect at the top right of the screen, but still want a notification.
Debug setting LiruNoTransactionClutter has been added, and is toggled by checkbox in General preferences
This adds support for TransactionInfo message, to localize the server's transaction notifications.
Adds a notification called Payment, which unifies all three of v-d's Payment* notifications.

This is a fairly large change to view, keep in mind what was removed as it may just be in a slightly different order or position..
2012-12-02 17:52:36 -05:00
Shyotl
8b19f82c0b Trivial changes. Resolved some sign mismatch warnings, and now using LLCachedControl for 'SGIgnoreSimulatorCameraConstraint' setting lookup. 2012-11-29 11:58:41 -06:00
Shyotl
794dbacea3 Merge branch 'master' of https://github.com/AlericInglewood/SingularityViewer.git into testpit
Conflicts:
	indra/newview/lldrawpoolavatar.cpp
	indra/newview/llviewertexturelist.cpp
	indra/newview/llworldmap.cpp
	indra/newview/pipeline.cpp
2012-11-29 11:54:41 -06:00
Shyotl
3a4b6cf6b6 Hovertext updates marked objects as 'moved' when inappropriate. http://hg.secondlife.com/viewer-development/commits/8ccf2b0fa3857a6610f6ea03166e5a4494ca6d03 2012-11-29 10:07:25 -06:00
Shyotl
c0c9c51e43 Some minor syntax grooming in LLNetMap::draw 2012-11-29 10:03:48 -06:00
Aleric Inglewood
e17405d80a Fixed snapping of rotation in the edge-on case
Patch by https://codereview.secondlife.com/users/cron.stardust/
Jira: https://jira.secondlife.com/browse/STORM-1919
2012-11-28 17:04:24 +01:00
Shyotl
5e6ed2dc9f Large update to the worldmap. Essentially, v3 merge, and reimplemented legacy tile drawing and opensim-specific changes. Also added a diagnostic view. 2012-11-24 11:21:29 -06:00
Shyotl
adebc36bc7 Cheap workaround for osgrid giving us an invalid pure-white single-channel opaque water texture. First it purges the texture from the cache and attempts to refetch, and if it's still invalid it falls back to the transparent water texture (which won't actually be transparent due to blending being disabled). Also fixed some annoying console spam related to null textures, and also now using the correct glTexGen* function. More details in comments. 2012-11-24 01:00:25 -06:00
Aleric Inglewood
165bebda3e Compile error and warning fixes for DEBUG_CURLIO without CWDEBUG. 2012-11-23 03:19:39 +01:00
Aleric Inglewood
0f54e5fe46 Remove erroneous assertion. 2012-11-22 03:55:10 +01:00
Aleric Inglewood
aab195a6eb Fix deinitialization order fiasco. 2012-11-19 04:42:02 +01:00
Aleric Inglewood
2400d146ce Clear the command queue after flushing statemachines
Flushing the state machines can cause remove commands to be added to the
command queue, so clearing it needs to be after.
2012-11-19 04:01:54 +01:00
Shyotl
9a9b5ce61e LLRectBase<>::clipPointToRect could divide by zero, resulting in the resulting clampd values being invalid under some scenarios (worldmap panning could cause the mouse cursor to 'restore' to an invalid location upon mouseclick release.) 2012-11-18 02:48:55 -06:00
Shyotl
6b473c6edc Avoid clearing hud object rebuild states when teleporting. 2012-11-18 02:42:33 -06:00
Shyotl
9d8f31a0cb Some teleport reworking. Don't clear rebuild groups/resetVBO unless tp screen is up, or we've just changed sims. Also skip updateUI drawing if tp screen is up. 2012-11-18 02:41:37 -06:00
Aleric Inglewood
5947769812 Fix LLMimeDiscoveryResponder.
Extract Content-Type also from a 405 reply.
If all else fails, use a default mime-type for url's opened
in the browser (start with http: or https:) of "text/html" instead
of "none/none".
2012-11-18 03:29:01 +01:00
Aleric Inglewood
52673f5249 Slight update of README 2012-11-18 02:41:37 +01:00
Aleric Inglewood
f44de434c2 Always use followRedir() to determine if redirections should be followed.
Before every HEAD and GET request allowed redirection by default,
without setting a limit on the number of redirections. This caused
an infinite redirect loop when connecting to marketplace, in combination
with the bug that we did not allow cookies.
2012-11-18 02:07:19 +01:00
Siana Gearz
cbb27a5661 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2012-11-18 01:33:18 +01:00
Siana Gearz
48eaccc612 Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2012-11-18 01:33:11 +01:00
Aleric Inglewood
5499136677 Don't send an Accept header for HEAD requests. 2012-11-18 01:29:24 +01:00
Aleric Inglewood
57b66a9be9 Allow cookies when allowing redirects (next to when sending a Cookie ourselves). 2012-11-18 01:28:23 +01:00
Aleric Inglewood
746f419e80 Fix detection of mIsInProductionGrid and fix getMarketplaceDomain()
getMarketplaceDomain() should return aditi.lindenlab.com for aditi,
not secondlife.aditi.lindenlab.com.
mIsInProductionGrid wasn't set correctly.
2012-11-17 21:38:55 +01:00
Aleric Inglewood
5d1a138c5c Code clean up of code related to previous commit. 2012-11-17 05:16:21 +01:00
Aleric Inglewood
e781870da3 Fix Ratany Residents crash 2012-11-17 04:55:34 +01:00
Aleric Inglewood
e3f30fece9 Fix print_diagnostics for windows. 2012-11-16 16:06:30 +01:00
Lirusaito
7b2536eb0d Inventory cut support!
Also fixes a bunch of comments, implementation based off of v-d.
Added isOnClipboard and setCutMode functions to LLInventoryClipboard, in part from v-d's LLClipboard.
LLInventoryFilter has a few rearrangements of code; only real change is now it has checkAgainstClipboard and uses it to filter out cut items.
There is a massive retabbed block in llinventorymodel.cpp, view without space changes. Implements removeObject.
Note: We are not afflicted by MAINT-1197: Fix inventory deselection/reselection when cutting items
2012-11-16 02:47:05 -05:00
Damian Zhaoying
299382b907 Add Merchant Outbox text files 2012-11-15 22:13:17 -03:00
Aleric Inglewood
fce64f8f12 Add LLWebProfile and responders.
Adds finding and using libjsoncpp. Note that the old cmake file
found libjson, not the same thing.

Adds Debug Setting WebProfileNonProductionURL (next to already existing
WebProfileURL) to mimic V3's behavior and use a different URL for aditi.
These Debug Settings are using by (the new) getProfileURL() (copied
from V3 with just a minor fix).

Adds HippoGridInfo::isInProductionGrid() next to the existing
LLViewerLogin::isInProductionGrid that always returned true.
The former should only be called SL grids and then only returns
true for agni (and false for aditi et al). The latter was changed
to now always return true except on SL when the grid isn't agni.
The first is used for SL-only cases, the latter for things like
colors and for godmode decision logic.

V3's llwebprofile.cpp was fixed to compile on singu, with only real
difference that I dropped the Content-Type headers for the GET methods.
2012-11-16 02:00:06 +01:00
Aleric Inglewood
f8bf11d574 More clearly state the implications of the NoVerifySSLCert debug option 2012-11-15 14:14:25 +01:00
Aleric Inglewood
fdfe0cae87 More clearly state the implications of the NoVerifySSLCert debug option 2012-11-15 13:51:16 +01:00
Aleric Inglewood
66664660d7 Copied llwebprofile.{h,cpp} from v-d as-is. 2012-11-15 04:07:44 +01:00
Scott Meitz
760ac98ab6 missed another spot with trailing spaces in aa functions, TNX LightDrake and Shyot1 :) 2012-11-14 21:37:36 -05:00
Scott Meitz
2bd5d88dbf fix extra space in strings.xml en. Tooltip was not find them 2012-11-14 21:37:00 -05:00
Siana Gearz
5f78a36899 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2012-11-15 02:30:01 +01:00
Lirusaito
b897b9427f Fix unclickable explanatory link on Outbox floater
mOutboxInventoryPanel couldn't be setVisible(false) while it was NULL, thus it sat on top of the rest of the UI.
Set it to panel_outbox_inventory in postBuild, instead of setupOutbox.
2012-11-14 16:48:03 -05:00
Lirusaito
c33b1004d1 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2012-11-14 13:55:48 -05:00
Siana Gearz
19e8977fff Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2012-11-14 19:40:45 +01:00
Aleric Inglewood
c097d650dc Don't upload partial files 2012-11-14 19:26:16 +01:00
Aleric Inglewood
b7af32bee3 Use std::istream::read instead of readsome
According to the docs
(http://www.cplusplus.com/reference/iostream/istream/readsome/)
readsome would also set state flag eofbit, but apparently I'm
misinterpreting it.  Anyway, using read() and then gcount()
to get the number of bytes does work.
2012-11-14 18:37:44 +01:00
Shyotl
d2422b03be Don't flush rebuild queue nor flush pending texture requests if merely performing a local teleport (eg: doubleclick teleporting within current sim.) 2012-11-13 23:34:48 -06:00
Shyotl
97d2085735 Nullcheck in LLTextureFetch::removeRequest was returning without unlocking LLTextureFetch::mQueueMutex if called via LLTextureFetch::deleteRequest 2012-11-13 23:25:32 -06:00
Aleric Inglewood
e307df79a1 Ignore the body in case of internal errors 2012-11-14 04:00:26 +01:00
Aleric Inglewood
324fe06a06 Improved printed info when curl times out. 2012-11-14 02:12:27 +01:00
Shyotl
fe15371047 Update to LLTombstone/LLHandle/LLRootHandle/LLHandleProvider. 2012-11-13 17:55:52 -06:00
Siana Gearz
fbb7196100 Missed a piece of a fix for the case we receive complete texture data instead of what we asked for.
The rest of the fix landed in commit c37a473287 by accident.
2012-11-13 23:54:23 +01:00
Siana Gearz
8c9a9c9d12 Introducing SGIgnoreSimulatorCameraConstraints 2012-11-13 23:46:21 +01:00
Aleric Inglewood
6f8ea87c46 Add ResponderHeadersOnly.
ResponderHeadersOnly is a base class for responders that use
HTTPClient::head or HTTPClient::getHeaderOnly. It already
has a needsHeaders() that return true and only allows for
completedHeaders to be overridden.

I removed the CURLOPT_HEADER option for these cases, because
that only causes the headers to be send to the writeCallback
as if they are part of the body, in addition to the headerCallback;
That gave raise to some confusion for the existing code (ie,
unexpected errors when trying to decode the body as LLSD and
duplicated 'low speed' information for the Timeout policy code.
2012-11-13 21:46:35 +01:00
Siana Gearz
3d84157325 Revert "Probably antivirus-friendlier SLPlugin"
This reverts commit 817085c172.
2012-11-13 18:41:58 +01:00
Siana Gearz
9abf8ddf91 Merge git://github.com/Murf/SingularityViewer 2012-11-13 18:40:20 +01:00
Lirusaito
f289d5d9e7 Make MARKET_IMPORTER_UPDATE_FREQUENCY configurable as debug setting MarketImporterUpdateFreq
Change the default to a minute... that should be good? Right?
2012-11-13 00:16:04 -05:00
Lirusaito
821c03a389 Copy folders support!
Sync with v-d/rlva for Copy folder support
Also, guard against outboxy stuff, like when we're importing, don't show the Marketplace Send menu entry.
Fixed a few comments
Please view this commit with space/tab changes off! There were a lot of retabbing cases that don't need to waste anymore of anyone's time.
2012-11-13 00:06:47 -05:00
Siana Gearz
c37a473287 Add NickyD's fast j2k metadata reader 2012-11-13 05:38:27 +01:00
Shyotl
3eebedc4c3 Revert "Avoid re-requesting object-inventory items that already have a pending request."
This code was actually regression in viewer-dev and causes some issues.
This reverts commit cd5aa8f074.
2012-11-12 20:32:40 -06:00
Siana Gearz
5eb99b7d2f Attempt to fix frame timer on broken mainboards 2012-11-13 02:50:15 +01:00
Brett Murphy
3534706a59 get OSX building again 2012-11-13 11:38:28 +11:00
Brett Murphy
717a8a5cdb Merge branch 'master' of https://github.com/AlericInglewood/SingularityViewer 2012-11-13 11:03:38 +11:00
Aleric Inglewood
586d8fdf21 Compile fixes for gcc 4.2 (Mac) 2012-11-13 01:01:19 +01:00
Siana Gearz
f4016c2e1c Stop trying to package dbghelp.dll - windows always comes with one anyway 2012-11-12 19:37:31 +01:00
Siana Gearz
2bb08d7638 Merge branch 'master' of git://github.com/LightDrake/SingularityViewer 2012-11-12 19:34:06 +01:00
Aleric Inglewood
155cc56632 Do not put AICurlEasyRequest in a container. 2012-11-12 18:42:55 +01:00
Shyotl
4a4032f3b8 Hopefully allows better behavior when loading other avatars. This is from v3, and taking a cursory glance, it's useful as onFirstTEMessageReceived is called before LLVOAvatar::idleUpdate, which means that mLoadedCallbacksPaused hasn't been updated for that particualr frame yet. Using LLVOAvatar::isVisible() is more accurate. 2012-11-12 03:41:53 -06:00
Shyotl
cd5aa8f074 Avoid re-requesting object-inventory items that already have a pending request. 2012-11-12 03:18:02 -06:00
Shyotl
c2b26f6c15 GCC Fixes:
Only use C++0x/C++11 features if compiling for windows, or if GCC is configured to support such features (v4.7 onwards: '-std=c++11'. v4.3 through v4.6: '-std=c++0x')
Removed an assertion that's no longer possible to evaluate (queue doesn't support iterators).
2012-11-12 03:04:24 -06:00
Shyotl
f25ca2ac80 Fixed small #if/#ifdef typo. Also fixed formatting error in strings.xml 2012-11-12 00:12:39 -06:00
Siana Gearz
303c74f4c9 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer
Conflicts:
	indra/llmessage/llurlrequest.cpp
	indra/newview/llvoavatar.cpp
2012-11-12 06:46:58 +01:00
Siana Gearz
59d4d833f1 Made octree check optional 2012-11-12 04:48:00 +01:00
Siana Gearz
562acd6e2c Merge branch 'master' of https://github.com/Shyotl/SingularityViewer 2012-11-12 04:12:57 +01:00
Siana Gearz
c3d76669ca Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer
Conflicts:
	indra/llmessage/llavatarnamecache.cpp
2012-11-12 04:12:28 +01:00
Siana Gearz
14d8d14832 Texture fetch cleanup 2012-11-12 03:33:17 +01:00
Aleric Inglewood
cdc04ba413 Merge branch 'fasttimelock' 2012-11-11 19:06:14 +01:00
Aleric Inglewood
ab91525e7a Add missing needHeaders
The AIBufferedCurlEasyRequestEvents are not triggered unless
the derived class return true for needsHeaders().
That means, every class that implements received_HTTP_header(),
received_header() or completed_headers(), or implement
the virtual function completedHeaders(), or use the protected
member mReceivedHeaders directly.
This commits adds missing needsHeaders() for LLAvatarNameCache
(thanks Siana) and XMLRPCResponder. The former now uses
mReceivedHeaders directly instead of making a copy.
2012-11-11 17:36:43 +01:00
Shyotl
0a4b3487ea Resolve string substitutions failing for a few 'unsuccessful' startup dialogs. 2012-11-11 01:01:04 -06:00
Aleric Inglewood
0061055e73 Attempted to dereference a past-the-end iterator. 2012-11-11 01:54:50 +01:00
Aleric Inglewood
a16c4015ba Attempted to decrement past-the-end iterator of empty container. 2012-11-11 01:54:50 +01:00
Shyotl
0173c29630 Resolve compiler warning caused by silly temporary #define. 2012-11-09 23:32:57 -06:00
Aleric Inglewood
26a734a538 Add fasttimers around obtaining a mutex or waiting on a condition. 2012-11-10 02:33:48 +01:00
Aleric Inglewood
04e7dc1270 Collect and print stats about HTTP status code 2012-11-10 02:19:20 +01:00
Shyotl
1cdc11dae2 Added LLTextureFetch::deleteAllRequests procedure. Called upon teleport. 2012-11-09 18:45:57 -06:00
Shyotl
1cb75c4471 Tiny bit of code consolidation in lltexturefetch 2012-11-09 18:42:37 -06:00
Shyotl
b6efc9f583 Fixed buggyness regarding objects moved by scripts. http://hg.secondlife.com/viewer-development/changeset/1a874cd5d0a0616b979a571e810320cd35e69baf 2012-11-09 18:41:05 -06:00
Shyotl
01868e46fe Removed pointless redundant gGL.flush() calls from llworldmapview. 2012-11-09 18:33:44 -06:00
Shyotl
313cce23db Trivial. Changed LLOcclusionQueryPool::mAvailableName to std::queue, because it's being used as a queue, and it being a list makes little sense. 2012-11-09 18:32:57 -06:00
Shyotl
9aca1f41f3 Make occlusion boundingbox 'fudge' settings adjustable via SHOcclusionFudge saved setting. 2012-11-09 18:20:45 -06:00
Shyotl
81c7445744 image->hasFetcher() check reundant in LLViewerTextureList::clearFetchingRequests(). LLViewerFetchedTexture::forceToDeleteRequest() checks for this too. 2012-11-09 18:12:57 -06:00
Shyotl
d54daa19a0 Allow trial of trasform feedback (for testing/benchmark) on hardware that declares support for GL_EXT_transform_feedback. Performance is far less than satisfactory on my hd4870(ogl3.3 gpu), however. Also messes up texcoords. Don't add RenderUseTransformFeedback to settings.xml. 2012-11-09 18:10:39 -06:00
Shyotl
0c58a42b08 Added a couple needed nullchecks of gAgentAvatarp in LLAgent. 2012-11-09 16:32:26 -06:00
Aleric Inglewood
68cbf31c8b Add a PerHostRequestQueue object.
Adds a std::map for hostname (or urls) --> PerHostRequestQueue
objects. The latter keeps track of the number of added curl easy
requests and decides if a new request should be throttled or
not, as well as provides the queue to queue throttled requests.

At the moment CurlConcurrentConnectionsPerHost is set to 16,
because things really don't work without LL supporting connection
reuse if we limit it to 2. CurlConcurrentConnectionsPerHost is
also set to non-persistent so that we can easily change it in the future
(once we decide on it's final value it can be set to persistent).
2012-11-07 15:41:50 +01:00
Lirusaito
d518222340 Disable Group Fee Invites in antispam preferences, when appropriate. 2012-11-06 21:35:35 -05:00
Lirusaito
7a35a43bd4 Merchant Outbox!
Enter: LLFloaterOutbox, floater_merchant_outbox, LLMarketplaceFunctions, LLPanelMarketplaceOutboxInventory, and panel_outbox_inventory

LLView now has childFromPoint() from v-d.
LLInventoryBridge{
Sync includes with v-d.
Let's ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU for ease of access and tweak it to work.
Uncomment related code.
Catch if we're moving objects into the outbox during pasteFromClipboard()
}
LLInventoryPanel: start_folder attribute for inventory_panels, this could be quite useful in the future
Sync LLToolDragAndDrop with Catznip/v-d
Add the outbox to the World menu, since that seems to involve most commerce. Perhaps we should add a menu entry to the outbox itself to open its floater?
Fix the inventory merchant menu entries, thanks Shyotl..
Merchant Outbox Strings!
2012-11-06 20:23:36 -05:00
Aleric Inglewood
cb52e82a60 Moved and extended AICurlInterface::Stats
Moved AICurlPrivate::Stats to AICurlInterface::Stats and added several
counters to keep track of the number of existing instances of
respectively AICurlEasyRequest, AICurlEasyRequestStateMachine,
BufferedCurlEasyRequest, ResponderBase and
ThreadSafeBufferedCurlEasyRequest.
2012-11-07 02:15:23 +01:00
Aleric Inglewood
1a43bc8abf As AIStateMachine moved outside newview, there is no longer any need to pass AIStateMachine::flush to initCurl() 2012-11-07 02:08:52 +01:00
Aleric Inglewood
e88c39b090 AIStateMachine::flush can only make statemachines idle.
As idle statemachines aren't in any list, it's not possible
(without adding that list) to delete them. I don't think
that there are any active statemachines left at the end
of flush anyway, but killing them doesn't much sense if
we can't get them all: there will always be statemachines
left: those that were idle at the moment the viewer was
quit.
2012-11-07 01:53:12 +01:00
Aleric Inglewood
a1f5e6ba43 Rename AICurlResponderBufferEvents to AIBufferedCurlEasyRequestEvents
Since we changed CurlResponderBuffer to be derived from CurlEasyRequest
and therefore changed it's name to BufferedCurlEasyRequest, we should
also rename AICurlResponderBufferEvents to
AIBufferedCurlEasyRequestEvents.
This commit also fixes C++ comment in several places to reflex the
previous name change.
2012-11-07 01:49:45 +01:00
Lirusaito
d0a0aa7a65 Fix handle_secondlifeprotocol.sh, and sync with v-d.
More translation strings~
Log inventory offers to those we're not chatting with.
"SDL deiconification state switched to " now lldebugs instead of llinfos, far too spammy..

(Pre-outbox commit, may contain pieces of outbox work.. and unmentioned harmless sync)
2012-11-06 18:50:45 -05:00
Drake Arconis
8cf956e669 Fixed a crash 2012-11-06 07:20:24 -05:00
Shyotl
3bbb23b1bc Experiments with allocating octree nodes via memory pools. 2012-11-05 16:58:03 -06:00
Shyotl
a582b5996c Whoops. Forgot settings.xml 2012-11-05 14:54:48 -06:00
Siana Gearz
4cd10c34e2 Fix manifest when extra libs are empty on Windows 2012-11-05 12:15:42 +01:00
Shyotl
3ec1dbf51c Updated spatial partition and octrees to use std::vector. Also, added diagnostic spew to octrees. 2012-11-04 21:48:17 -06:00
Shyotl
71deb8925e Added some nullchecks, removed some dead code, and cleaned up a few small things. 2012-11-04 21:16:53 -06:00
Siana Gearz
abb562d1ab For extra safety 2012-11-05 03:22:57 +01:00
Aleric Inglewood
a495a6bfbc Short circuit llsd debug check. 2012-11-05 01:04:02 +01:00
Siana Gearz
e86b17be2d Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2012-11-04 18:56:15 +01:00
Aleric Inglewood
e62f805bcd Fix wrong assertion mAddedEasyRequests.size() >= (size_t)mRunningHandles
Rename check_run_count to check_msg_queue, because the whole 'run count'
approach is flawed anyway (the author of libcurl told me that THE way
to check for finished curl handles is to just call curl_multi_info_read
every time: it's extremely fast. Any test that attempts to avoid that
call is nonsense anyway.

The reason the assertion failed might have been caused by the fact
that we're comparing the current number of easy handles with the
number of running handles of 'a while ago'. It is possible that a
easy handle was removed in the meantime.

In order to check if that hypothesis is right, I moved the assertion
to directly below the call to curl_multi_socket_action where it
should hold. If this new assertion doesn't trigger than the hypothesis
was right and this is fixed.
2012-11-04 17:08:05 +01:00
Siana Gearz
6f8ae718d1 Forgotten files for message logger 2012-11-04 03:30:49 +01:00
Siana Gearz
1dcfa9e0ee Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer
Conflicts:
	indra/llmessage/llregionpresenceverifier.cpp
	indra/llmessage/llregionpresenceverifier.h
2012-11-04 02:10:31 +01:00
Siana Gearz
7f0664ff82 Bringing back message logger 2012-11-03 14:13:13 +01:00
Aleric Inglewood
03b3e60e23 Merge branch 'curlthreading3' 2012-11-02 18:54:07 +01:00
Aleric Inglewood
72bde5234a Rename CurlResponderBuffer to BufferedCurlEasyRequest and derive it from CurlEasyRequest
Every curl transaction is a AICurlEasyRequestStateMachine which has a
AICurlEasyRequest as member, which is a reference counting pointer to
a ThreadSafeBufferedCurlEasyRequest. And now BufferedCurlEasyRequest is
derived from CurlEasyRequest which is derived from CurlEasyHandle, but
neither are used separatedly.
2012-11-02 18:41:23 +01:00
Aleric Inglewood
1e1f5e8193 Fix windows compile errors/warnings 2012-11-01 03:18:00 +01:00
Aleric Inglewood
6c01b6da9b Merging CurlEasyRequest and CurlResponderBuffer, Step 1 2012-11-01 02:40:08 +01:00
Aleric Inglewood
756aac1f9a Remove AICurlInterface::strerror 2012-11-01 02:04:40 +01:00
Aleric Inglewood
c0ac428179 Code cleanup
* Moved Responder stuff to LLHTTPClient.
* Renamed LLHTTPClient::Responder to LLHTTPClient::ResponderWithResult.
* Deleted LLHTTPClientAdapter and LLHTTPClientInterface.
* Renamed AICurlInterface::TransferInfo to AITransferInfo and moved it
  to llhttpclient.h
* Removed 'CURLcode code' argument from completed_headers.
2012-10-31 23:11:42 +01:00
Aleric Inglewood
7549b471c3 Moved curl stuff from indra/aistatemachine to indra/llmessage. 2012-10-31 18:51:52 +01:00
Aleric Inglewood
0b265320a9 Code clean up.
* Removed LLCurlRequest and replaced it's last usage with LLHTTPClient API calls.
* Deleted dead code.
* Renamed all the get4/post4/put4/getByteRange4 etc, back to their
  original name without the '4'.
2012-10-31 05:01:24 +01:00
Aleric Inglewood
6033a76870 Print more debug output. Remove last AIFIXME 2012-10-30 21:37:49 +01:00
Aleric Inglewood
3708d55ef9 Allow changing CurlTimeout Debug Settings on the fly.
Same for NoVerifySSLCert and CurlConcurrentConnections.
2012-10-30 21:18:15 +01:00
Aleric Inglewood
9996cf6157 Bug fix 2012-10-30 21:17:25 +01:00
Aleric Inglewood
3e78b7c262 Allow people with last name "Resident" to login using Hippogrid manager. 2012-10-30 07:16:01 +01:00
Aleric Inglewood
65e012c540 More curl fixes and changes.
* Moved LegacyPolledResponder::mCode to ResponderBase::mCode.
* Added a parameter to ResponderBase::finished (and pubError*) to set mCode.
* Renamed ResponderBase::decode_body to decode_llsd_body and added ResponderBase::decode_raw_body.
* Use LegacyPolledResponder::finished instead of LegacyPolledResponder::completed_headers
  to set remaining cached values.
* Fixed assertion in case of -DCWDEBUG and upload finish detection failure in case of HEAD
  method (mDebugIsGetMethod -> mDebugIsHeadOrGetMethod).
* Add XmlTreeInjector : support for LLXmlTree.
* Split BlockingResponder into BlockingLLSDResponder and BlockingRawResponder.
* Final blocking responders are now: BlockingLLSDPostResponder, BlockingLLSDGetResponder
  and BlockingRawGetResponder.
* Added LLHTTPClient::blockingGetRaw
* Got rid of hipporestrequest.* -- and fixed hippogridmanager.cpp to use
  LLHTTPClient::blockingGetRaw instead, and fixed llviewermessage.cpp to use
  AICurlInterface::ResponderWithCompleted and decode_raw_body instead of
  HippoRestHandlerRaw and LLHTTPClient::get4 instead of HippoRestRequest::get5.
2012-10-28 17:38:25 +01:00
Aleric Inglewood
2a88f7d7c4 ResponderAdapter stuff
Renamed AICurlInterface::Responder to AICurlInterface::ResponderBase,
but without the virtual 'event' methods.
Derived from that: Responder and ReponderWithCompleted, where the
first defines result = 0, ErrorWithContent and error, and the latter
completedRaw and completed.
Added HttpClient::IgnoreBody, derived from Responder and implementing
'result' doing nothing; HttpClient::Ignore is now derived from
IgnoreBody and defines the still pure virtual getHTTPTimeoutPolicy.

Added ResponderBase::decode_body, which is now the sole place
where the code makes the decision wether some response data might be
LLSD or not based on the http status result. Before it just tried
to decode everything as LLSD, which seems a bit nonsense.

ResponderWithCompleted::completed no longer does anything, since
classes derived from ResponderWithCompleted are expected to override it,
or never call it by overriding completedRaw.

Entry point is now ResponderBase::finished = 0, instead of
completedRaw, where ResponderWithCompleted implements finished by
called completedRaw, but Responder doesn't: that directly calls
result/errorWithContent/error. Or, for the hack ResponderAdapter,
the entry points are pubResult/pubErrorWithContent.
Those are now the ONLY public methods, so more confusion.
mFinished is now set in all cases.

As a result of all that, it is no longer possible to accidently
pass a responder to ResponderAdapter that would break because it
expects completed() and completedRaw() to be called.

Added LLBufferArray::writeChannelTo.

Fixed bug for BlockingResponder::body (returned reference to temporary).

LLSDMessage::ResponderAdapter now allows a "timeoutpolicy" name
to be passed (not doing so results in the default timings), so
that the timeout policy of the used responder is retained.

Fixed llfasttimerview.cpp to test LLSDSerialize::fromXML() to return
a positive value instead of non-zero, because it may return -1 when the
parsing fails (three places).

Removed LLHTTPClient::Responder as base class from
LLFloaterRegionDebugConsole completely: it isn't a responder!

Several other responder classes were simplified a bit in order to
compile again with the above changes.
2012-10-26 04:13:29 +02:00
Shyotl
dca9501de7 Attempt to break viewer window out of 'maximized' mode when not actually maximized. There are old jiras about the previous workaround causing issues, so let's attempt a different method. 2012-10-25 20:52:14 -05:00
Shyotl
8ed6b549ee A few resolutions in the dropdown in the prefrences panel were not being parsed correctly. Use standard 'x' instead of '×' 2012-10-25 20:50:42 -05:00
Shyotl
1a741b97d2 Fixed LLGLState::checkStates() failing upon context re-creation:
-After new context creation, immediately call LLRender::refreshState() after LLViewerWindow::initGLDefaults() in order to force states to apply.
--LLRender::initGLDefaults optimizes out gl calls by caching states, but the cached values are only applicable to the old context, not the new, so this optimization must be skipped (LLRender::mDirty).
-LLViewerWindow::mStatesDirty also triggered a redundant shader reload, since restoreGL also called setShaders().
Fixed somewhat annoying flicker of a single frame whilst recovering from screen resizing.
-Skip frame if LLViewerWindow::checkSettings() called LLViewerWindow::reshape. (reshape will set gWindowResized to true)
--True optimal fix will require some refactoring.
Reworked how window position is saved in LLViewerWindow::changeDisplaySettings. Hopefully reduces chances of odd behavior (had WindowX and WindowY get stuck at massive negative values before)
2012-10-25 20:42:58 -05:00
Aleric Inglewood
33809f56c5 Comment out unused code. 2012-10-25 02:17:40 +02:00
Shyotl
67ee544231 Clear saved raw discard level upon texfetch cleanup. (missed this in an earlier commit) 2012-10-24 03:21:51 -05:00
Shyotl
94f61ce307 A few nullchecks in the particle system. Had a null drawable pop up. 2012-10-24 03:20:32 -05:00
Shyotl
b57f7cdc79 Fixed various specular/glow effects bleeding through fullbright objects in deferred. 2012-10-24 03:19:53 -05:00
Shyotl
c901a7136f I freaking swear LL breaks hud attachment lighting in some way every few months. *Grumble* 2012-10-23 17:24:08 -05:00
Aleric Inglewood
243db9a3a8 Moved mFinished/is_finished() from LegacyPolledResponder to Responder.
Slightly more robust, adds one boolean to all responders, 99%
of which don't need that though, and an extra call redirection,
but well... We might need it this way when I add the possibility
to abort a transfer.
2012-10-22 22:52:18 +02:00
Shyotl
a5ef61ac82 Avoid std::vector::erase in particle system (erase in any sequence-independent vector is a waste as it shifts all elements to maintain element-ordering and contiguity). Replaced with swap and pop. 2012-10-22 15:46:12 -05:00
Shyotl
9e272aeef0 Still need to initialize flexis upon their very first idle update, else you get an ugly polygon soup when they first appear. 2012-10-22 15:32:33 -05:00
Shyotl
5c45979783 Resolve issue with sculpties loading with incorrect discard levels. 2012-10-22 15:26:53 -05:00
Shyotl
02f214d8a7 Clear object rebuild queues upon teleport. 2012-10-22 15:25:02 -05:00
Aleric Inglewood
daac25c343 Bug fix, introduced in commit 0bee4a92 2012-10-22 20:31:33 +02:00
Aleric Inglewood
768f1b5710 Fixes blocking_request. Adds LegacyPolledResponder and BlockingResponder.
XMLRPCResponder also uses the new LegacyPolledResponder now.
Renamed http_result() -> http_status().
2012-10-22 20:19:44 +02:00
Shyotl
5b4b9fd169 Durr, missed a line when adding attached light muting. Clobbered when diffing. Incrementing in a for loop is kinda important! Our handling in this function differes from LL in the firstplace because they are performing iteration on an iterator that can be invalid after the erase. 2012-10-22 03:17:33 -05:00
Shyotl
7dea357f4c Picked up a few small changes from viewer-beta pertaining to pathfinding. 2012-10-22 03:08:51 -05:00
Shyotl
9ef10b1663 Muting an avatar now also removes their attached lights. Also cleaned up light update code(no change in behavior) 2012-10-22 03:07:07 -05:00
Shyotl
d2004e88f9 MatrixMode sanity checks and adjustments to physics debug display (fixes a crash with that debug view, too) 2012-10-22 03:05:18 -05:00
Shyotl
ef27cc54dd Fixed unsafe erasure from vector while iterating in llinventorybackup.cpp. 2012-10-22 02:56:41 -05:00
Shyotl
19390eaec3 Remove pointless framebuffer status check. glReadBuffer doesn't work with gl_depth_attachment, thus will always complain about readbuffer being absent. (it checks GL_COLOR_ATTACHMENT0, which isn't present because this check is before we attach color attachments.) 2012-10-22 02:55:21 -05:00
Shyotl
dff6171605 More alignment crap. 2012-10-22 02:51:41 -05:00
Shyotl
4fe84efafd Unbork shadow shaders by tweaking normal unpack. 2012-10-22 02:51:28 -05:00
Shyotl
ed4997168b LLViewerObject::idleUpdate now returns void. Texture animations/flexis now have their own update queues. 2012-10-22 02:50:04 -05:00
Aleric Inglewood
b92de9beb5 Done as part of AIHTTPTimeout 2012-10-22 02:20:20 +02:00
Aleric Inglewood
7f50b2ba7b Add XMLRPC support to LLHTTPClient and that instead of LLXMLRPCTransaction 2012-10-22 01:59:17 +02:00
Aleric Inglewood
c35bc71334 Fix crash when libcurl calls read callback before calling socket callback.
In days of usage this has never happened before, but apparently
it's possible. The solution chosen is to create the AIHTTPTimeout
object on the fly when it doesn't exist and let it be picked up
later when the CurlSocketInfo for the transfer is created.
2012-10-22 00:53:54 +02:00
Shyotl
413a8111c0 PASS_INVISI_SHINY never issued. Commented out some unused code. 2012-10-21 17:16:22 -05:00
Shyotl
5be31898f1 Don't compile avatar eye shader, as it isn't used anywhere. 2012-10-21 17:14:29 -05:00
Shyotl
44faf3e169 Removed annoying attribute consumption warnings. Alpha pass was leaving shader bound, which hosed up updateCull for water reflections (updateCull only binds occlusion shader if another shader isn't currently bound) 2012-10-21 17:14:00 -05:00
Aleric Inglewood
937a60c8f9 Add AIHTTPReceivedHeaders
This fixes the problem that existed with received headers:
The server sends some headers ("set-cookie") more than once
in the same reply, which cannot be stored in std::map.
The old code just ignored the additional cookies, while
curlthreading3 (since the introduction of AIHTTPHeaders)
caused an assertion.

AIHTTPReceivedHeaders is written around a std::multimap
and allows to retrieve multiple headers with the same key.
Also, it is case insensitive so that if a server sends
"Content-Type" it will still find it (the viewer looks for
"content-type").
2012-10-21 17:45:46 +02:00
Aleric Inglewood
f7626699da Bug fix: (correctly) revoke CurlResponderBuffer events. 2012-10-21 17:28:22 +02:00
Lirusaito
ad97c72821 Use smaller horizontal chat tabs, where possible. 2012-10-21 11:19:03 -04:00
Lirusaito
b7ce7b7dab Tiny LLWorld silliness fix up 2012-10-21 11:18:49 -04:00
Shyotl
b73f4dd8e4 Catch up with viewer-beta. Primarily sim transition alterations to reduce frame hitching, and some optimization in LLViewerObjectList (std::set -> std::vector and and some allocation tweakage). 2012-10-20 17:02:43 -05:00
Aleric Inglewood
a4bf92dae4 Add CURLcode and TransferInfo to completed_headers event. 2012-10-20 23:56:19 +02:00
Aleric Inglewood
1e745ba48b Curl work in progress.
Minor changes like comment fixes and addition of accessors
that will be needed for future commits.
Also removed Responder::fatalError as it was never used.
2012-10-20 23:52:34 +02:00
Aleric Inglewood
f8273e977e Make NoVerifySSLCert work for all LLURLRequest
Moved CURLOPT_ENCODING from CurlEasyRequest::setPost_raw, and
CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST from
CurlResponderBuffer::prepRequest, to LLURLRequest::configure,
enabling the debug setting NoVerifySSLCert for the latter
two to work as follows: old behavior if "NoVerifySSLCert"
is not set, and check neither if it is set. However, if
the (new) bool mIsAuth is set the behavior of LLXMLRPCTransaction::Impl::init
is used. This is so in a next commit we can replace
LLXMLRPCTransaction with LLURLRequest: LLXMLRPCTransaction::Impl::init
will be removed. For the same reason, when the new boolean
mNoCompression is set then CURLOPT_ENCODING is set to "identity",
otherwise the old behavior (of clearing it) is used.
2012-10-20 23:28:33 +02:00
Aleric Inglewood
605843b527 HTTP status of 400 is an error too. 2012-10-20 21:47:31 +02:00
Siana Gearz
71d2bd83aa Fix inconsistent link/unlink checking 2012-10-17 13:41:30 +02:00
Siana Gearz
a12704c6a3 Don't eat my mouse when i might be debugging 2012-10-17 13:39:54 +02:00
Shyotl
43271f290e A few more alignment bits and bobs. 2012-10-16 20:07:04 -05:00
Shyotl
7533b475be TCMalloc can now be manually disabled via develop.py -DDISABLE_TCMALLOC:BOOL=ON 2012-10-16 17:15:23 -05:00
Shyotl
1b89e5c973 Dragged in a bunch of alignment fixes from LL. Should allow disabling of tcmalloc on windows/linux32 if such is ever implemented. 2012-10-16 02:33:05 -05:00
Aleric Inglewood
8ba127d4c5 HTTPTimeout work in progress
* Avoid using CurlEasyRequest::mTimeout for HTTPTime::done and
  HTTPTime::print_diagnostics when it might be NULL.
* Comment fixes.
* Indentation fix.
2012-10-15 21:07:17 +02:00
Aleric Inglewood
bb8ea493d6 Fix top check in MultiHandle::check_run_count.
This check isn't really needed at all, since curl_multi_info_read
is fast enough, but well... The old check was flawed anyway.
2012-10-15 21:03:08 +02:00
Aleric Inglewood
02cffa9a71 Replace TimeOut with Timeout everywhere. 2012-10-15 21:01:16 +02:00
Aleric Inglewood
76fc30e460 HTTPTimeout work in progress.
* Moved DoutCurlEasy and DoutCurlEasyEntering from aicurl.cpp
  to aicurl.h and renamed them to DoutCurl and DoutCurlEntering
  respectively.
* Moved the callback functions from aicurl.cpp to aicurlthread.cpp.
* In CurlEasyRequest, renamed timeout_timings to print_curl_timings
  and mTimeoutLowercaseHostname to mLowercaseHostname.
* Put all remaining CurlEasyRequest::mTimeout* variables and
  timeout_* methods in curlthread::HTTPTimeout, stripping them
  of said prefix, and moved the definition to aicurlprivate.h.
  Added a ThreadSafeCurlEasyRequest* member and a get_lockobj()
  method so to that class so we can still use DoutCurl /
  DoutCurlEntering. timeout_add_easy_request was removed completely
  and reimplemented as the constructor of HTTPTimeout.
  timeout_has_stalled was renamed to HTTPTimeout::has_stalled,
  but also reimplemented as CurlEasyRequest::has_stalled.
* CurlEasyRequest::mRequestFinalized was removed and it's
  functionality taken over by CurlEasyRequest::mTimeoutPolicy.
* Fixed the indentation of struct Stats, class CurlEasyHandle
  and class CurlEasyRequest.
* Added CurlEasyRequest::set_timeout_opts
* Added CurlSocketInfo::mTimeout (LLPointer<HTTPTimeout>).
* mUploadFinished is now reset in HTTPTimeout::data_received,
  this was needed because "HEAD /something" header-only
  messages triggered upload_finished (unlike "GET ..."),
  and in combination with redirection that caused an assert.
2012-10-15 03:34:32 +02:00
Shyotl
e8ec81bf04 Experimentation with normalpacking and component precision. 2012-10-14 04:00:02 -05:00
Aleric Inglewood
9fba54ad5d On failed transfer, print CURLINFO_OS_ERRNO when available. 2012-10-14 03:13:32 +02:00
Aleric Inglewood
ccd98c3c3d Fix comment. 2012-10-14 02:55:45 +02:00
Aleric Inglewood
2539e41e59 Avoid problems in case a host also resolves to IPv6 2012-10-14 02:53:36 +02:00
Aleric Inglewood
83312fbb74 Allow getinfo() to be called on a const CurlEasyRequest. 2012-10-14 02:45:58 +02:00
Aleric Inglewood
6134162f1c Merge remote-tracking branch 'singu/exp' 2012-10-14 00:57:07 +02:00
Lirusaito
fb713226a0 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2012-10-12 13:50:56 -04:00
Aleric Inglewood
3ac46f5fa7 HTTP timeout work in progress. 2012-10-12 19:39:11 +02:00
Lirusaito
d5c507ca6b Merge branch 'master' of https://github.com/LightDrake/SingularityViewer 2012-10-12 12:59:42 -04:00
Drake Arconis
858bb15a6b Fixed issue 2012-10-12 12:36:31 -04:00
Aleric Inglewood
faee255730 HTTP timeout bug fix! Plus work in progress.
Use the better understandable alias CURLOPT_HTTPHEADER in debug output

Bug fix - finally!

This fixes a bug I've been looking for a week.
By accidently calling get_clock_count() for the mTimeoutLowSpeedClock
'event', the time difference 'now' - 'event' becomes negative, which
should be impossible; the result being that timeout_low_speed
stalled for 24 seconds while looping over the full 32 bit. That in
turn made SSL handshakes of libcurl fail, which seemed to be
impossible since the calls to libcurl had not changed!
2012-10-12 04:50:46 +02:00
Shyotl
eb5b1312bb Removed pointless asset fetches for expression-based gestures (opposed to animation based ones), since they don't have actual animation assets. 2012-10-11 02:40:00 -05:00
Siana Gearz
5445b4f97a Fix bandwidth estimation for texture fetch 2012-10-10 15:37:43 +02:00
Aleric Inglewood
02ead94848 HTTP timeout work in progress.
More debug output.
Avoid the new assert when exiting the viewer.
2012-10-08 19:14:22 +02:00
Aleric Inglewood
6a4f76a219 Bug fix for previous commit. 2012-10-08 05:00:11 +02:00
Aleric Inglewood
1252b0bde2 HTTP timeout work in progress.
* Remove progress meter call back, use read/write/header callbacks instead.
* Don't use timeout_lowspeed for ReplyDelay, instead use:
* Add timeout stuff to the main loop (CurlEasyRequest::mTimeoutStalled).

This patch fixes a few things compared to the previous version.
More things need to be fixed.
2012-10-08 02:19:32 +02:00
Aleric Inglewood
a40fbf0da1 Cache hostname of url in CurlEasyRequest::mTimeoutLowercaseHostname
Also add DoutCurlEasyEntering debug macro.
The caching is necessary because CURLINFO_EFFECTIVE_URL is unreliable
and can change several times during the transfer at any moment (as
a result of forwarding etc).
2012-10-06 01:21:33 +02:00
Aleric Inglewood
468f52a4f6 Merge branch 'master' into curlthreading3 2012-10-05 16:55:28 +02:00
Aleric Inglewood
3f1fb9a66e Add improved timeout handling for HTTP transactions.
Introduces AIHTTPTimeoutPolicy objects which do not just
specify a single "timeout" in seconds, but a plethora of
timings related to the life cycle of the average HTTP
transaction.

This knowledge is that moved to the Responder being
used instead of floating constants hardcoded in the
callers of http requests. This assumes that the same
timeout policy is wanted for each transaction that
uses the same Responder, which can be enforced is needed.

I added a AIHTTPTimeoutPolicy for EVERY responder,
only to make it easier later to tune timeout values
and/or to get feedback about which responder runs
into HTTP errors in debug output (especially time outs),
so that they can be tuned later. If we already understood
exactly what we were doing then most responders could
have been left alone and just return the default timeout
policy: by far most timeout policies are just a copy
of the default policy, currently.

This commit is not finished... It's a work in progress
(viewer runs fine with it though).
2012-10-05 15:53:29 +02:00
Drake Arconis
c181891549 New windlight presets 2012-10-04 18:28:51 -04:00
Drake Arconis
f84f4aa058 Updated/Fixed Cursors 2012-10-04 18:13:48 -04:00
Drake Arconis
5d5c3e2a48 LLCalcparser update 2012-10-04 17:56:43 -04:00
Drake Arconis
5b8b88e05a Nuked ancient uneeded things 2012-10-04 17:56:25 -04:00
Drake Arconis
0287e21c01 More python indentation fixing...DIE TABS DIE 2012-10-04 16:34:10 -04:00
Drake Arconis
7d2f2bd610 Fixed python indentation in newview 2012-10-04 16:25:44 -04:00
Drake Arconis
d56393b134 Merge remote-tracking branch 'singu/master'
Conflicts:
	indra/cmake/WebKitLibPlugin.cmake
	indra/llmessage/llurlrequest.cpp
	indra/plugins/webkit/media_plugin_webkit.cpp
2012-10-04 16:17:41 -04:00
Lirusaito
1f7ed035d3 Make translation more flexible
Also in this commit, unrelated updates to the building panel (so git sees the markup "just" move in my next commit)
2012-09-29 16:59:17 -04:00
Aleric Inglewood
8430328043 Add support for uploading JP2 files.
Recognizes .jp2, .j2c and .j2k extensions.
Adds image/jp2 files to file picker image filter (windows and Mac,
windows apparently already showed them).
Show preview for jpeg 2000 files.
Fixes error reporting for failed image uploads.
Enforces a power-of-two size for jpeg 2000 files (seemed to make sense to do that).
2012-09-29 17:47:15 +02:00
Lirusaito
f311852e9b Satiate Issue 474 by showing a more sensible number for ARC by default.
http://code.google.com/p/singularity-viewer/issues/detail?id=474
Adds LiruSensibleARC debug setting, defaults to true.
Code ported from Imprudence.
2012-09-28 20:13:38 -04:00
Shyotl
ac0a32e690 Add an antispam setting to block only group invites to groups that require an entry fee. 2012-09-27 19:30:54 -05:00
Shyotl
88482a2431 An extra rendertarget is needed when fxaa dof are used in conjunction. mDeferredScreens color attachment was being used for both input and output when doing DoF combine, which is undefined behavior. Using mDeferredScreen for this works as it's no longer needed after lighting has been applied. 2012-09-26 20:45:47 -05:00
Shyotl
efbd339dc8 No return value? VisualStudio don' care. 2012-09-26 19:52:17 -05:00
Shyotl
ff28ce8d65 Corrections of some stupids (harmless copy-paste shenanigans in this case). 2012-09-26 19:51:24 -05:00
Lirusaito
cb33470673 Strings fix-up~ 2012-09-25 16:02:17 -04:00
Lirusaito
e6389d62dc Add debian/ubuntu support to install-deps script.
Also make the script more portable.
2012-09-25 16:01:43 -04:00
Aleric Inglewood
2766f17cb9 Merge remote-tracking branch 'github/master' into curlthreading3 2012-09-24 17:52:46 +02:00
Aleric Inglewood
70c36716c9 Disable SSL/TLS session caching.
Fixes: VWR-28039, VWR-28629
2012-09-24 17:05:23 +02:00
Aleric Inglewood
48702b1ed9 Various stuff
Comment fixes
Added some more debug support, not used yet (linux/libcwd only),
I used it, but won't commit the code that did.
Pass time_time parameter from post2() to prepRequest; only
used by mesh uploading at the moment.
2012-09-24 16:55:34 +02:00
Shyotl
16216b2ed0 Removed lscript_compile, lscript_execute, and lscript_library dependencies from newview. 2012-09-24 04:08:57 -05:00
Aleric Inglewood
3e22553d7e Merge remote-tracking branch 'github/master' into curlthreading3 2012-09-23 17:40:07 +02:00
Aleric Inglewood
4744839a08 Bug fix for curl request queue of last commit.
In debug mode an assertion was triggered when a queued
request was being removed by the main thread; and rightfully
so: we should remove such request from the queue in that
case.
2012-09-23 17:31:41 +02:00
Lirusaito
cb0c13a1a1 Merge branch 'master' of https://github.com/LightDrake/SingularityViewer 2012-09-23 10:25:22 -04:00
Drake Arconis
f0497a2721 Merge branch 'llqtwebkit' 2012-09-23 05:58:47 -04:00
Drake Arconis
77d018dbc8 Dependency install script for linux. Currently only supports Arch. 2012-09-23 00:51:29 -04:00
Drake Arconis
4be8b50360 Merge branch 'master' into llqtwebkit 2012-09-22 22:45:56 -04:00
Lirusaito
2581935b36 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
Conflicts:
	indra/newview/skins/default/xui/en-us/floater_post_process.xml - Used Mine, because Shyotl's is the ancient one from "the before time" and because my last commit (worked on motionblur tab, then, too.)
2012-09-22 15:12:45 -04:00
Aleric Inglewood
a7cf09883e Merge branch 'master' into curlthreading3 2012-09-22 01:26:37 +02:00
Aleric Inglewood
1254a7bbe2 Merge remote-tracking branch 'github/master' into curlthreading3
Conflicts:
	indra/aistatemachine/aistatemachine.cpp
2012-09-22 01:25:54 +02:00
Aleric Inglewood
fb5ec1d1f5 Implement curl connection throttling (CurlConcurrentConnections) 2012-09-21 19:26:40 +02:00
Aleric Inglewood
5bcb350d89 Always print '(CURL*)' in front of CURL*'s in debug output. 2012-09-21 01:48:21 +02:00
Aleric Inglewood
81bc6b49f8 Debug code bug fix; removal of CurlEasyHandle::getErrorString()
CurlEasyHandle::mErrorBuffer (CURLOPT_ERRORBUFFER) can NOT be
used to retrieve information about an error returned by
curl_multi_info_read in CURLMsg::data::result. This buffer is
only initialized when a curl_easy_* call returns an error,
and those errors are already printed automagically.

Initialize the buffer with an empty string upon invokation
of an curl_easy_* call, so we are sure the error belongs to
the last call.
2012-09-21 01:28:26 +02:00
Shyotl
9019a1eb23 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2012-09-20 15:29:28 -05:00
Aleric Inglewood
f3780998ed Always reset stream state after using std::hex 2012-09-20 16:50:03 +02:00
Aleric Inglewood
27090c541f Remove inconsistent dll linkage (missing LL_COMMON_API) 2012-09-20 05:36:11 +02:00
Aleric Inglewood
ef73469700 Merge remote-tracking branch 'singu/master'
Abandonning curlthreading2 -- which is now in master.
2012-09-20 05:17:56 +02:00
Aleric Inglewood
2d12a82a54 Always flush LLBufferStream objects. 2012-09-20 04:49:43 +02:00
Aleric Inglewood
c5d9dc4732 Bug fix 2012-09-20 04:48:03 +02:00
Drake Arconis
84ec70e707 Revert "Breakpad cmake"
This reverts commit b0415370f8.
2012-09-19 20:50:54 -04:00
Siana Gearz
b7f5d7e415 Windows build fixes 2012-09-20 01:37:40 +02:00
Siana Gearz
8df7a52cf7 Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer
Conflicts:
	indra/llplugin/slplugin/CMakeLists.txt
2012-09-19 23:30:48 +02:00
Shyotl
9bb9292a41 Attempt to catch octree node manipulation while iterating over said nodes 2012-09-19 15:34:25 -05:00
Shyotl
438c499718 And the shader.. 2012-09-19 15:34:15 -05:00
Shyotl
ff81d9461a Added motionblur postprocess shader.
Conflicts:

	indra/newview/skins/default/xui/en-us/floater_post_process.xml
2012-09-19 15:33:58 -05:00
Shyotl
f4f85aa1fd Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git
Conflicts:
	indra/newview/llviewerobject.cpp
2012-09-19 15:24:33 -05:00
Aleric Inglewood
56f2f0b727 Merge branch 'curlthreading2' into curlthreading3 2012-09-19 04:14:25 +02:00
Aleric Inglewood
19f325aa09 Merge remote-tracking branch 'singu/master' into curlthreading2
Conflicts:
	indra/llcommon/CMakeLists.txt

Resolved with kdiff3 automatically.
2012-09-19 04:11:16 +02:00
Aleric Inglewood
1d5a63c180 Fixed showing TOS floater.
This creates a separate events interface structure
for CurlResponderBuffer (AICurlResponderBufferEvents)
for dealing with received HTTP headers.

The headers are passed to the Responder, but only
if the class derived from Responder implements
completedHeaders (otherwise it makes little sense
to even decode the headers).

Basically this is a reimplementation of the functionality
of the old LLHTTPClientURLAdaptor class.
2012-09-18 23:59:09 +02:00
Lirusaito
d7da5153f3 Fixed up the Post-Process floater~
Vertical tabs, as requested by Shyotl
2012-09-18 10:06:21 -04:00
Aleric Inglewood
c67f010302 Pass filename by reference when possible. 2012-09-18 05:01:34 +02:00
Drake Arconis
90a10b3508 Removed packaged dbghelp.dll 2012-09-17 22:40:30 -04:00
Drake Arconis
a09f7d274f Fixed a bit of cmake derpyness 2012-09-17 22:23:57 -04:00
Drake Arconis
daa9466b7a Spelling fixin a comment :D 2012-09-17 22:22:28 -04:00
Drake Arconis
efb252206b Cached controls in cmdline chatbar 2012-09-17 22:22:02 -04:00
Drake Arconis
ffb847bbc0 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2012-09-16 16:40:49 -04:00
Siana Gearz
a7b9b0da42 Version 1.7.2 2012-09-15 21:17:16 +02:00
Siana Gearz
5f8eac9dc8 Have i beaten you now, evil extortionists? 2012-09-15 21:15:59 +02:00
Aleric Inglewood
b5b6d3f85c Fix PluginAttachDebuggerToPlugins for linux.
This fixes the problem that many terminals require command line
parameters to be passed as command line parameters to the terminal
command. The old code would pass the whole gdb command including
all it's arguments (whatever replaces %s) as a single argument,
regardless of whether there are quotes around the %s or not.
Now those arguments are passed as separate arguments if there
are no quotes around the %s.

Updated documentation with an example on how to open a gdb terminal
on a different machines X display.
2012-09-14 19:38:05 +02:00
Drake Arconis
f50d23a0d4 Fast Timers brought up to linden equiv 2012-09-14 00:30:52 -04:00
Drake Arconis
cb9f972d13 BE GONE 2012-09-14 00:30:25 -04:00
Drake Arconis
e0a7c7e935 Renamed our log files to not conflict with linden 2012-09-13 19:39:02 -04:00
Drake Arconis
b0415370f8 Breakpad cmake 2012-09-13 18:19:38 -04:00
Drake Arconis
b7ff2fe3e3 Merge branch 'master' of https://github.com/LightDrake/SingularityViewer 2012-09-13 18:09:46 -04:00
Aleric Inglewood
a032bd28ad Merge branch 'curlthreading2' into curlthreading3 2012-09-11 17:05:13 +02:00
Aleric Inglewood
834a524a67 Compile fix.
This belongs to the latest merge with singu/master.
2012-09-11 17:03:57 +02:00
Aleric Inglewood
e3460bea09 Compile fix for openssl < 1.0.1 2012-09-11 15:51:18 +02:00
Aleric Inglewood
131959e388 Merge branch 'curlthreading2' into curlthreading3 2012-09-11 15:19:28 +02:00
Aleric Inglewood
d23835a6c2 Merge remote-tracking branch 'singu/master' into curlthreading2
Conflicts:
	indra/newview/statemachine/aistatemachine.cpp

Huh - you re-INDENTED a file that you didn't merge yet?
How about merging curlthreading2 and curlthreading3
before doing THAT? :/

Obviously I did an "use ours" here.
2012-09-11 15:15:46 +02:00
Aleric Inglewood
e17632e0d5 Merge branch 'curlthreading2' into curlthreading3 2012-09-11 14:56:07 +02:00
Aleric Inglewood
d57a3b101b Hide quilt patch directory 2012-09-11 14:54:51 +02:00
Aleric Inglewood
c2289c047b Only disable TLS1.1 for openssl1.0.1 and higher, leaving SSL3 alone. 2012-09-11 02:05:54 +02:00
Drake Arconis
9b358a1b39 Initial llqtwebkit 2012-09-08 02:03:07 -04:00
Aleric Inglewood
36c097744c Merge remote-tracking branch 'github/master' 2012-09-06 15:22:31 +02:00
Aleric Inglewood
e7cd445491 Merge branch 'curlthreading2' into curlthreading3 2012-09-06 15:12:22 +02:00
Aleric Inglewood
e3752aefed Fix loading Qt plugin on linux standalone.
For standalone there is no need to link libmedia_plugin_webkit.so
against Qt's plugins, and thus also not to add "random" paths
to LD_LIBRARY_PATH. Just let Qt do it's thing and find and
load the plugins it needs itself.
2012-09-05 19:29:47 +02:00
Aleric Inglewood
d8ff809092 Make webkit work with Qt 4.8 2012-09-05 04:12:13 +02:00
Aleric Inglewood
a8f5bf8baf Bug fix.
dlerror() returns NULL when no errors have occurred since the last call
to dlerror() (or since the last call to dlopen(), dlsym() or dlclose()).
2012-09-05 02:15:41 +02:00
Aleric Inglewood
3a3605b812 Cherry pick from curlthreading2 2012-09-04 23:34:56 +02:00
Aleric Inglewood
f1c635d103 Cherry pick from curlthreading2 2012-09-04 23:34:11 +02:00
Aleric Inglewood
15cce79040 Merge remote-tracking branch 'singu/master' into curlthreading2
Conflicts:
	indra/llmessage/llcurl.cpp

Changes to unused file (I'll remove it when I'm done).
2012-09-04 17:38:11 +02:00
Aleric Inglewood
dd9f7bba5d Merge branch 'curlthreading2' of github.com:AlericInglewood/SingularityViewer into curlthreading2 2012-09-01 04:02:45 +02:00
Aleric Inglewood
8051cd4194 Install fix for latest 32bitcompatibilitylibs 2012-09-01 03:56:52 +02:00
Aleric Inglewood
21ea923520 Compile fix for OSX 2012-08-31 05:50:42 +02:00
Aleric Inglewood
484fff444f Compile fix for OSX 2012-08-31 05:23:20 +02:00
Aleric Inglewood
83b13f6a3f WIP: make everything use AICurlEasyRequestStateMachine 2012-08-20 21:18:19 +02:00
Aleric Inglewood
05c32c7a62 Merge branch 'curlthreading2' into curlthreading3 2012-08-15 05:44:17 +02:00
Aleric Inglewood
ea4d32b4ad Compile fix. 2012-08-15 05:43:12 +02:00
Aleric Inglewood
536cb6febd Merge branch 'curlthreading2' into curlthreading3
Conflicts:
	indra/CMakeLists.txt
	indra/llcommon/llstring.h
	indra/llmessage/CMakeLists.txt
	indra/llmessage/llhttpclient.cpp
	indra/llmessage/llhttpclient.h
	indra/llmessage/llurlrequest.cpp
	indra/llmessage/llurlrequest.h
	indra/newview/hipporestrequest.cpp
	indra/newview/llappviewer.cpp
2012-08-15 00:51:40 +02:00
Aleric Inglewood
19293601b3 Manual pick of stuff from 'shycurl' (68ad5411) that seemed to make sense. 2012-08-14 02:38:06 +02:00
Shyotl
f2bcfa5275 Use cachedcontrol in LLViewerObjectList::update. 2012-08-13 18:51:37 -05:00
Siana Gearz
36ff4dcd11 Don't feed empty, non-working callback to CURL
Cherry-Pick of 96a4e16a

Conflicts:
	indra/llmessage/llurlrequest.cpp
	indra/llmessage/llurlrequest.h
	indra/newview/hipporestrequest.cpp

Clear reasons for conflicts, resolved.
2012-08-13 23:33:49 +02:00
Aleric Inglewood
35a53ef1d7 Bug fix (needed for libcwd with memory allocation debugging) 2012-08-13 21:59:57 +02:00
Aleric Inglewood
169670a58b Refurbish last merge. Fix compile for standalone and libcwd. 2012-08-13 19:30:35 +02:00
Aleric Inglewood
fbb5dced97 Merge remote-tracking branch 'singu/master' into curlthreading2
Conflicts:
	indra/llcommon/CMakeLists.txt
	indra/llmessage/llcurl.cpp
	indra/llmessage/llcurl.h
	indra/llmessage/llhttpclient.cpp
	indra/llmessage/llhttpclient.h
	indra/llmessage/llpumpio.cpp
	indra/llmessage/llpumpio.h
	indra/llmessage/llurlrequest.cpp
	indra/llmessage/llurlrequest.h
	indra/newview/hipporestrequest.cpp
	indra/newview/llappviewer.cpp
	indra/newview/llspatialpartition.cpp
	indra/newview/llviewermedia.cpp
	indra/newview/llxmlrpctransaction.cpp

Conflicts resolved by choosing curlthreading2
for any llmessage file regardless (which looks
correct upon investigation); the rest also
turned out to need to use curlthreading2, except
in one line where I added a semi-colon after
an assert(), and the assert was changed in
singu/master.
2012-08-13 17:07:25 +02:00
Shyotl
aa54a386f3 Fix regression introduced in pathfinding (avelocity bugs) 2012-08-13 02:55:47 -05:00
Aleric Inglewood
263a25fb87 Compile fix for DEBUG_CURLIO 2012-08-12 17:42:30 +02:00
Aleric Inglewood
fa10ce28d2 Missing header 2012-08-12 17:10:44 +02:00
Aleric Inglewood
304fa05094 Suppress "Expect:" header for POST and PUT. No longer use CURLOPT_COPYPOSTFIELDS.
For POST and PUT, libcurl adds by default a "Expect: 100-continue"
header and wait for the server to reply with a 100 response.
However, since the server never does that (LL comment in the
code "I'm not sure what it means") it's up to libcurl to continue
anyway after a while and that part is apparently bugged, causing
people not to be able to login sometimes. But suppressing the
header, libcurl doesn't wait for it and we worked around this bug.

The commit introduces a much improved CurlEasyRequest::setPost
method that enforces the above for POST, but that also no longer
uses CURLOPT_COPYPOSTFIELDS (but CURLOPT_POSTFIELDS), no longer
making a copy of the body of what we are going to send to the server.
Instead it uses a new object, derived from AIPostField, to keep track
of this data and to dispose of it once the transaction is complete
(and no sooner).

Copied from llcorehttp, we now also always set a "Connection:
keep-alive" and "Keep-alive: 300" header for POST.
This was already done for texture downloads (HttpOpRequest),
but now we do it always :p. Might need to be changed in the
future, but currently those headers are ignored by the server
anyway.
2012-08-12 16:34:20 +02:00
Aleric Inglewood
2fbe7ab6ce Only accept pointers to valid types for getinfo(). 2012-08-12 03:38:45 +02:00
Aleric Inglewood
164799e4c4 Curl debug output improvements and minor fixes. 2012-08-12 03:33:33 +02:00
Aleric Inglewood
8e1bbfe938 Amend last commit 2012-08-11 03:29:46 +02:00
Aleric Inglewood
3469d65f95 Windows compile and linker fixes.
* Do not include aithreadid.h from debug.h, because the latter is
  included everywhere (from linden_common.h) and aithreadid.h is
  heavy (includes among others windows.h).
* On windows, thread local members cannot be exported.
2012-08-11 03:23:31 +02:00
Aleric Inglewood
70717cb6c8 Compile bug fix for windows. 2012-08-10 14:49:34 +02:00
Aleric Inglewood
94ebcdeb6b Add eight missing headers...
How did you ever get this to compile if those
headers were removed from the precompiled header?
2012-08-10 07:23:29 +02:00
Aleric Inglewood
152238e67f Merge remote-tracking branch 'shyotl/breakforce' into breakforce 2012-08-10 05:56:28 +02:00
Shyotl
eef51e0bd0 Pulled llpacketring.h and llhttpclient.h out of the precompiled header. 2012-08-09 22:50:05 -05:00
Aleric Inglewood
91df8446b0 Oops bug fix for last commit. 2012-08-10 05:37:41 +02:00
Aleric Inglewood
ffb55f482a Compile fixes for windows. 2012-08-10 05:35:11 +02:00
Aleric Inglewood
b2c5a84964 Replace CURLOPT_POSTFIELDSIZE_LARGE with CURLOPT_POSTFIELDSIZE
Also adds a more robust interface for setopt that does
type checking based on the options used. This fixes one
bug where a F32 was passed and interpreted as long.
In many cases a U32 or S32 was passed as long, which
would fail (only) on a 64bit non-windows big endian machine.
2012-08-10 04:18:04 +02:00
Aleric Inglewood
0054e6a378 Bug fix.
Fixes an exit crash when the user clicks on Login and immediately
on Quit, because termination of the LLAuth curl request statemachine
access the CurlRequestTimeOut debug setting.
2012-08-09 07:04:23 +02:00
Aleric Inglewood
76e30150b9 Removed superfluous debug output 2012-08-09 07:02:42 +02:00
Aleric Inglewood
cd197a3807 Fix LL_REF_COUNT_DEBUG debug code.
This code was broken with respect to LLAPRPool.
Fix that, and also fixed it for the new AIThreadID API.
2012-08-09 07:00:51 +02:00
Aleric Inglewood
b9673df961 Clean up of debug.h: just use LL_COMMON_API. 2012-08-09 06:57:53 +02:00
Aleric Inglewood
37c8ea54eb Add AIThreadID - Cleanup of apr_os_thread* related code.
Apart from just really cleaning things up and moving
everything into one class regarding thread IDs (ie,
is_main_thread(), comparing ID's etc), this also
fixes an obscure bug where LL was casting thread ID's
to U32 and then compared those to find out if it
the same thread. It's theoretically possible that
such fails on a 64bit OS.

By generalizing the interface, I adopted the use
of a thread-local cache for the current thread ID
as used by LLMutex et al, so now all code benefits
from that. The idea was even extended to now also
be used for is_main_thread() tests and even resetting
a thread ID to the ID of the current thread.
2012-08-09 06:30:31 +02:00
Aleric Inglewood
f94f458922 Print CURL_SOCKET_TIMEOUT for that particular value. 2012-08-08 04:10:34 +02:00
Aleric Inglewood
89ef06fd3f Compiler warning fixes. Take into account that debug_libcurl.cpp is no longer linked dynamically. 2012-08-08 01:58:49 +02:00
Aleric Inglewood
ccd135b2a6 and again 2012-08-08 01:04:27 +02:00
Aleric Inglewood
80eb0851d9 Fix stupidity 2012-08-08 01:02:08 +02:00
Aleric Inglewood
b84f470fca Bug fix: curl_off_t has a different size than void* on 32 bit. 2012-08-08 00:40:01 +02:00
Aleric Inglewood
5caeccc007 Final compile/link bug fixes for debug_libcurl code.
renamed cwdebug/debug_libcurl.cc -> llmessage/debug_libcurl.cpp
    and cwdebug/debug_libcurl.h  -> llmessage/debug_libcurl.h,
because debug_libcurl.cpp does curl calls that do ares and
openssl calls, so we need to link with those libraries.
llmessage is already linking with those libraries, and contains
the main entry point aicurl.h, so it's a suitable place to put
this.

Bug fix: must always include llpreprocessor.h before including
curl/curl.h.

Bug fix: Added #include "debug_libcurl.h" to hipporestrequest.cpp
and llurlsimstring.cpp which I missed before because they
included "curl/curl.h" instead of <curl/curl.h>. Same in
llwaterparammanager.cpp, but removed include there because it
isn't needed.

Now test DEBUG_CURLIO before including debug_curlio, that
seems better, because otherwise it would make more sense to
replace all #include <curl/curl.h> with #include "mycurl.h"
and then do it there-- but I didn't want to do that.

Bug fix: we undef-ed CURLOPT_DNS_USE_GLOBAL_CACHE, while really
that is an enum, not a macro.

Fixed DEBUG_WINDOWS_CODE_ON_LINUX again by adding a hack for
ioctlsocket(), not instantiating dumb_socketpair unless
DEBUG_WINDOWS_CODE_ON_LINUX is defined and removing again ^M's
introduced with the new windows non-blocking code.
Also changed the type of flags passed to fcntl to int (was long).
2012-08-07 20:57:39 +02:00
Aleric Inglewood
477c657f60 Merge remote-tracking branch 'singu/breakforce' into breakforce 2012-08-07 16:19:20 +02:00
Aleric Inglewood
cc50e620c0 Merge branch 'curlthreading2' into breakforce 2012-08-07 05:22:10 +02:00
Aleric Inglewood
8646abb18b Merge branch 'curlthreading2' into curlthreading3 2012-08-07 05:21:52 +02:00
Aleric Inglewood
2fbf6b732e Fix undefined symbols linker error on linux / relwithdebinfo.
See http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Interface.html
With this patch, the #pragma will also be used with icc and clang,
I didn't test this.
2012-08-07 05:18:24 +02:00
Aleric Inglewood
93416e40a4 Compile fix: CURLOPT_SSL_OPTIONS was also added since 7.25.0 2012-08-07 05:16:59 +02:00
Aleric Inglewood
e14be5c8c2 Make debug_libcurl.cc compile with libcurl 7.21 and higher 2012-08-07 01:33:29 +02:00
Aleric Inglewood
95083e846b WIP 2012-08-06 23:19:09 +02:00
Aleric Inglewood
f479ea4bcf Merge branch 'curlthreading2' into curlthreading3 2012-08-06 19:55:19 +02:00
Aleric Inglewood
65a1aae629 Bug fix
curl_easy_setopt expects a long int. Before this patch,
uninitialized memory was read, leading to extreme long
time out, instead of the intended disabled time out (so,
in practise this patch has little effect).

This bug was discovered with the previous commit.
2012-08-05 18:55:27 +02:00
Aleric Inglewood
caef97ad36 Print all libcurl calls if -DDEBUG_CURLIO. Don't create static lib for cwdebug.
Basically, cmake doesn't support linking static libs into a shared lib.
The correct way is to just specify source files in subdirectories
directly as source files of the shared library. This patch changes that.

Also, after this commit, when DEBUG_CURLIO is defined, every call to
libcurl is printed to llinfos (or to dc::curl when using libcwd).
2012-08-05 18:51:21 +02:00
Siana Gearz
761439cc8d Setting socket pair non-blocking 2012-08-05 08:20:31 +02:00
Aleric Inglewood
98c740f204 Remove debug output 2012-08-03 00:56:41 +02:00
Aleric Inglewood
255742db26 Merge branch 'curlthreading2' into breakforce 2012-08-03 00:54:12 +02:00
Aleric Inglewood
af4ceb0658 Crash on exit fix. 2012-08-03 00:53:54 +02:00
Aleric Inglewood
08d72b12ab Fix compilation on linux. Remove trailing ^M's 2012-08-02 23:03:03 +02:00
Aleric Inglewood
5fb4badb7c WIP 2012-08-02 22:34:23 +02:00
Siana Gearz
4650636e5a Use TCP socket pair instead of UDP 2012-08-02 22:33:01 +02:00
Aleric Inglewood
725cdc2d69 Linux compile fixes 2012-07-31 23:04:45 +02:00
Siana Gearz
048c57cf0c Linktime fix 2012-07-31 22:40:20 +02:00
Siana Gearz
12dcbfbc79 Merge remote-tracking branch 'aleric/breakforce' into breakforce 2012-07-31 22:39:48 +02:00
Aleric Inglewood
32be05fa6c Compile warning fixes. Type fix (SLL -> SSL) 2012-07-31 22:37:49 +02:00
Aleric Inglewood
ae62b67554 Merge branch 'curlthreading2' into breakforce 2012-07-31 22:24:57 +02:00
Aleric Inglewood
29908533cd More work in progress 2012-07-31 22:23:52 +02:00
Siana Gearz
9c4f22d85b Attempt at fixing linker errors... 2012-07-31 21:30:05 +02:00
Siana Gearz
7f64668e55 Compile warning fix 2012-07-31 21:29:22 +02:00
Siana Gearz
0208942b84 Compile warning fix 2012-07-31 21:28:37 +02:00
Siana Gearz
783e86990c Compile fixes 2012-07-31 19:42:15 +02:00
Aleric Inglewood
cdefc0e384 Merge branch 'curlthreading2' into curlthreading3
Conflicts:
	indra/llmessage/llcurlrequest.cpp

Header file include changes collided. Fixed.
2012-07-31 17:46:07 +02:00
Aleric Inglewood
c9715c5b0b Print Dout() and DoutEntering() debug output on windows.
This is a bit of a hack currently and requires a
recompile with -DDEBUG_CURLIO.
2012-07-31 04:57:13 +02:00
Aleric Inglewood
dd47123bde Add possibility to suppress function name prefix in debug output.
Adds llinfos_nf et al.
2012-07-31 04:56:03 +02:00
Aleric Inglewood
3de21156b5 Windows code improvements and debugging.
Extended the DEBUG_WINDOWS_CODE_ON_LINUX hack to include ALL code.
memset-zero sockaddr_in, and use WSASocket as per suggestion of Shyotl.
2012-07-30 02:46:48 +02:00
Aleric Inglewood
ce2c6ab49e Don't crash when libcurl wasn't compiled with support for libz 2012-07-30 02:45:39 +02:00
Aleric Inglewood
d19c5a4a4a Move apr_os_thread_current_wrapper closer to where it's used, and fix a comment. 2012-07-30 02:44:51 +02:00
Aleric Inglewood
8945fe4857 Unbreak standalone install on 64bit linux 2012-07-30 01:47:27 +02:00
Aleric Inglewood
464919072d Use LLBufferArray instead of std::stringstream for CurlResponderBuffer::mInput
Note the changed code is never used yet.  CurlResponderBuffer::curlReadCallback
is only called when Request::post is being used, which is never used.
2012-07-29 22:52:20 +02:00
Siana Gearz
f8c2087d74 Preliminary Windows support for curlthreading 2012-07-29 22:47:19 +02:00
Siana Gearz
7adc0e24ab Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer into curlthreading 2012-07-29 21:32:24 +02:00
Aleric Inglewood
ba65f29a72 Fix draining of wake up pipe.
This is a bug fix, although not one we'd ever run into as normally
there is always just one byte to read, never an EAGAIN and certainly
never more than 256 bytes. Anyway, also those cases should work now.
2012-07-29 21:12:45 +02:00
Aleric Inglewood
76eef6fe59 Avoid crash on exit. 2012-07-29 18:38:59 +02:00
Aleric Inglewood
af4ac8fb5f WIP: work on rewriting LLURLRequest 2012-07-29 01:30:11 +02:00
Aleric Inglewood
adaf5cd69c Update of a few <edit> comments.
While comparing this function with v-d, I realized that
I editted these instances for Singularity, so I might
as well update the <edit> comments to be a bit more correct.
Not saying that there aren't other <edit> comments
still missing futher into the function.
2012-07-29 01:30:11 +02:00
Aleric Inglewood
516f5a40d0 Change mainloop to no longer use gIdleCallbacks 2012-07-29 01:30:11 +02:00
Aleric Inglewood
3b7887a041 Cleanup of some unnecessary dependencies. 2012-07-29 01:30:11 +02:00
Aleric Inglewood
fe38f59bbb Bug fix 2012-07-29 01:30:10 +02:00
Aleric Inglewood
cd93aba002 Created aistatemachine library and moved files. 2012-07-29 01:30:10 +02:00
Siana Gearz
2bcabce1d6 Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer into curlthreading 2012-07-28 17:28:18 +02:00
Aleric Inglewood
ed4c6b7c92 Removed dead code.
This code has been in the viewer source for a long time,
and hasn't been used for a long time (furtherest back that
I checked was Snowglobe 1.4).

Most notably, this removes LLContextURLExtractor and code
that used it because that required an API where AICurlEasyHandle
is created before an url is known, which gets in the way of
reusing connections.
2012-07-23 18:15:11 +02:00
Aleric Inglewood
785729abdf Merge branch 'master' into curlthreading2 2012-07-22 04:17:34 +02:00
Aleric Inglewood
fb38f6adea Always write curl I/O debug info for the login attempt. 2012-07-21 21:51:24 +02:00
Aleric Inglewood
3a30f1dc71 This is called when LLApp::sStatus == LLApp::APP_STATUS_STOPPED too. 2012-07-21 03:57:58 +02:00
Siana Gearz
8802d5033f Merge branch 'master' into curlthreading
Conflicts:
	indra/newview/viewer_manifest.py
2012-07-20 00:37:58 +02:00
Siana Gearz
3d39564605 Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer into curlthreading 2012-07-20 00:35:43 +02:00
Aleric Inglewood
9e5cbf330f Bug fix for windows code found with previous commit. 2012-07-19 17:28:45 +02:00
Aleric Inglewood
2fa9334090 Debug code to test the windows code path on linux 2012-07-19 17:27:37 +02:00
Aleric Inglewood
fcdf5d377e Move PollSet out of the header file 2012-07-19 17:26:02 +02:00
Aleric Inglewood
051263117d Don't force TLS v1 unless needed and then warn about it. 2012-07-19 00:13:43 +02:00
Aleric Inglewood
f772cbee51 Don't crash upon exit if we fail to cleanup. 2012-07-18 03:13:33 +02:00
Aleric Inglewood
7f78870295 Merge remote-tracking branch 'siana/master' into curlthreading2
Conflicts:
	indra/llcommon/llstring.cpp
	indra/llmessage/llcurl.cpp
	indra/newview/llviewertexturelist.cpp
	indra/newview/viewer_manifest.py
	install.xml

Resolved:
	indra/llcommon/llstring.cpp :
		two different ways to work around compile error.
	indra/llmessage/llcurl.cpp :
		this file is no longer used.. I deleted huge
		parts to mark that I implemented that. Siana
		apparently made a few changes in those parts.
	indra/newview/llviewertexturelist.cpp :
		manually copied patch. Mine also removed trailing
		spaces, keeping that.
	indra/newview/viewer_manifest.py:
		Collision with changes from Liru, which have been
		ignored (kept siana/master).
	install.xml:
		Collision with an earlier screw up. I kept the
		fix from siana/master.
2012-07-18 02:08:31 +02:00
Aleric Inglewood
706b9c55c2 Moving stuff around a bit... 2012-07-18 01:41:36 +02:00
Shyotl
48ae0d003d Made the Visual Studio compiler a bit more happy with aicurl. 2012-07-17 18:04:48 -05:00
Aleric Inglewood
0204d09a89 If curl thread is already awake, then don't write something to the pipe. 2012-07-17 23:39:44 +02:00
Aleric Inglewood
648ed00ce2 Don't call gSavedSettings.getU32() and calc_clock_frequency() so often anymore. 2012-07-17 19:58:34 +02:00
Aleric Inglewood
87c9358813 Add back erroneously removed comments. 2012-07-17 19:33:12 +02:00
Aleric Inglewood
64b968b262 process is no longer processing 2012-07-17 19:27:14 +02:00
Aleric Inglewood
900e533b4b Remove unused call to process(). 2012-07-17 08:01:06 +02:00
Aleric Inglewood
9deb3e433c LLCurlRequest time out fixes.
Also some more cleanup on exit improvements.
2012-07-16 22:35:04 +02:00
Aleric Inglewood
a34247ebf4 Bug fix.
Don't test on something that belongs in an assert.
is_main_thread() doesn't even exist unless --type=Debug.
2012-07-15 23:08:07 +02:00
Aleric Inglewood
53e96b02c0 Bug fix. Forgot to actually make it virtual. 2012-07-15 22:59:29 +02:00
Aleric Inglewood
7c022d6061 Don't crash on exit.
When a new state machine was just created, so run() had already
been called but it never did really run yet so running() would
return false; then abort() wasn't called in flush(), causing
the subsequent mainloop call to actually try and startup the
state machine, which then crashed because Debug Settings
mechanism is already destroyed at that point (and in general,
we really don't want anything to run: it does unpredictable
things).

With this fix, also state machines that were just created are
aborted, resulting actuall in a kill without delete, and subsequently
a clean delete from the mainloop.
2012-07-15 22:51:14 +02:00
Aleric Inglewood
14e5b46687 Fixed and adjusted remainders of isValid() code.
Note that in the code, and still, has_curl_request was always false.
However, instead of deleting all code paths that are only executed
when has_curl_request would be true, I fixed the code to work as
intended with my current implementation; which also results in
LLCurlRequests to never expire. This way things won't break
unexpectedly when this ever changes.

Since on this branch isValid was only called still (the rest was
removed already) to check if the curl download expired, I took
the liberty to rename isValid to hasNotExpired.
2012-07-15 22:46:38 +02:00
Aleric Inglewood
a6bb2604f6 Use our API, which makes more sense. 2012-07-15 16:58:47 +02:00
Aleric Inglewood
b2c71c099f Fixed typo in comment 2012-07-15 16:57:47 +02:00
Aleric Inglewood
7416d2aaf1 Timer, time out, and clean up improvements. 2012-07-14 04:29:37 +02:00
Aleric Inglewood
0419f8bee9 Add an AITimer to AICurlEasyRequestStateMachine.
Fixes AIStateMachine to work thread-safe with the timer.
2012-07-10 05:09:08 +02:00
Aleric Inglewood
f012f664d2 Threading voodoo: allow multiple concurrent calls to set_state().
This patch prepares AIStateMachine for the use of AITimer together
with calls to set_state() from other threads. The extra problem
in this case is that the main-thread CAN start running the state
machine again (when the timer times out), while before it was
assumed to be idle until a thread called set_state.

This also takes into account that a thread might call set_state()
and then AGAIN call set_state() before the main thread gets the
chance to call idle() inbetween.
2012-07-09 04:19:28 +02:00
Aleric Inglewood
744563a150 Use a newer libcurl version for linux. 2012-07-07 23:22:48 +02:00
Aleric Inglewood
389074d1e9 Fail at configure time when openGL is not found 2012-07-07 23:17:22 +02:00
Aleric Inglewood
93778eccbb Compile fix for g++ 4.7 2012-07-07 18:29:55 +02:00
Aleric Inglewood
f46d8e8a10 Try to be smart about not printing garbage (binary) received from the server. 2012-07-05 23:50:03 +02:00
Siana Gearz
f5bfab139c Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer into curlthreading 2012-07-05 06:06:04 +02:00
Aleric Inglewood
df20f918ba New libcwd channel 'curlio'.
Enable printing of libcurl 'IO' debug messages when libcwd channel
'curlio' is turned on (added to .libcwdrc). Avoiding a recompile.
2012-07-05 03:10:16 +02:00
Aleric Inglewood
b8fc1f634e Print the curl library found during configure.
Prints something like:
-- Found CURL: /usr/lib/x86_64-linux-gnu/libcurl.so (found version "7.25.0")
2012-07-05 01:41:01 +02:00
Aleric Inglewood
ae9dadb5d8 Improved layout of curl stats print out. 2012-07-04 16:56:33 +02:00
Siana Gearz
d31c062693 Fix building with libcwd 2012-07-04 12:44:05 +02:00
Siana Gearz
544928a039 Merge branch 'curlthreading2' of git://github.com/AlericInglewood/SingularityViewer into curlthreading 2012-07-04 10:45:48 +02:00
Aleric Inglewood
14276b3cf8 Bug fix 2012-07-04 08:44:22 +02:00
Aleric Inglewood
07e7eeedd1 Added some windows code.
Iterating directly over the elements of fd_set::fd_array in
windows is faster than using FD_ISSET.
2012-07-04 07:32:24 +02:00
Aleric Inglewood
125a10bb44 Code hardening, review, bug fixes, documentation, curl stats and cleanup.
Bug fixes:
AICurlEasyRequestStateMachine didn't delete itself.
curl_multi_socket_action calls were made for potentional removed sockets.
The curl thread wasn't terminated.
2012-07-04 00:10:43 +02:00
Aleric Inglewood
9b8e5c8719 Merge branch 'V2MultiWear' into curlthreading2
I picked a few non-curl related patches from curlthreading2
and applied them to V2MultiWear. Now merging back to avoid
collisions for others.
2012-07-03 14:27:12 +02:00
Aleric Inglewood
a803507d67 Use correct way to check if we logged in yet or not.
Without this fix, we trigger an assert, in debug mode, that was added
to Singularity exactly to find out if we called functions like
getExpandedFilename(LL_PATH_PER_SL_ACCOUNT ...) before logging in.
Checking if THAT function returns empty() is clearly not safe, but
very error prone.
2012-07-01 22:15:03 +02:00
Aleric Inglewood
cb5efad026 Turn llassert[_always] into a (single) statement and print line nr in decimal. 2012-06-30 21:14:18 +02:00
Aleric Inglewood
26922a1578 Merge remote-tracking branch 'lirusaito/curlthreading2' into curlthreading2 2012-06-29 05:28:58 +02:00
Aleric Inglewood
90493b6571 Add support for libopenSSL older than version 1.0.0. 2012-06-29 05:20:24 +02:00
Aleric Inglewood
2dee921cd5 Fix libcurl version check. 2012-06-29 01:33:38 +02:00
Lirusaito
433c7c3f99 Spelling fixes and stuff like that to AICurl* and llproxy.* documentations
Also removes a duplicate include from llares.cpp

Conflicts:
	indra/llmessage/aicurl.cpp
2012-06-28 04:08:25 -04:00
Lirusaito
fef461fd13 Grabbed openSSL-1.0.0d from upstream for linux, necessary for non-standalone compiles.
Also brought in linux64 version I had sitting around, collecting dust.
2012-06-28 03:46:22 -04:00
Aleric Inglewood
1f56645b69 Always set proxy settings for every HTTP curl connection.
Move applyProxySettings to CurlEasyRequest and call it from
applyDefaultOptions.

Use AIThreadSafe for LLProxy for a more robust threadsafeness.
(This forces correct locking, checks that the unshared vars
are indeed unshared and made it easy to use read/write locking,
which might be important in this case (we do a lot of read-only
accesses to it).
2012-06-28 05:56:21 +02:00
Aleric Inglewood
69ca6cd5b2 WIP: Make curl thread code robust and flexible.
Conflicts:

	indra/llmessage/llcurl.cpp
	indra/llmessage/llcurl.h
	indra/newview/app_settings/settings.xml
	indra/newview/llappviewer.cpp
	indra/newview/llmeshrepository.cpp

Resolved:

	indra/llmessage/llcurl.cpp:

	  Basically removed (not used anyway)

	indra/llmessage/llcurl.h:

	  Basically removed (just includes aiculr.h now)

	indra/newview/app_settings/settings.xml:

	  CurlUseMultipleThreads was remvoved.
	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are still in there, but unused at the moment.

	indra/newview/llappviewer.cpp:

	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are unused at the moment.

	indra/newview/llmeshrepository.cpp:

	  Lock mSignal always (is unlocked inside wait()).
	  Use mSignal lock to see if we are waiting; remove mWaiting.
	  Return false from the MeshFetch functions iff we have to retry
	  a HTTP fetch. Catch the error exception thrown by getByteRange
	  instead of using it's return value (always returns true
	  anyway).
2012-06-28 01:30:46 +02:00
812 changed files with 58589 additions and 28840 deletions

2
.gitignore vendored
View File

@@ -11,6 +11,7 @@
/bin-release
/indra/viewer-*
/indra/newview/vivox-runtime/
/indra/newview/dbghelp.dll
/libraries/
/lib/
*.pyc
@@ -22,3 +23,4 @@
/LICENSES/
/edited-files.txt
qtcreator-build/
/.pc

View File

@@ -0,0 +1,114 @@
Linden Research, Inc. ("Linden Lab") Viewer FLOSS License Exception v0.5
The Linden Lab Exception for Free/Libre and Open Source Software-only
Applications Using Linden Lab Viewer Software (the "FLOSS Exception").
Exception Intent
Linden Lab is releasing the source code for certain software that
enables users to view or otherwise access the Second Life virtual
world environment (the "Viewer Software"), under version 2 of the GNU
General Public License (the "GPL"). The creation or distribution of
works based on the Program (as defined under the GPL) of the Viewer
Software may require the use of certain Free/Libre and Open Source
Software ("FLOSS") works that are subject to license agreements not
compatible with re-licensing under the GPL. Because we want to allow
the Viewer Software to be distributed with these FLOSS works, this
FLOSS Exception following exception applies subject to the terms and
conditions below.
Legal Terms and Conditions
As a special exception to the terms and conditions of version 2.0 of
the GPL:
You are free to distribute a work based on the Program that is formed
entirely from the Viewer Software (and any modifications thereof) and
one or more works that are independent and separate works not derived
from the Viewer Software, and are licensed under one or more of the
licenses listed below in section 1 (each, a "FLOSS Work") , as long
as:
A. You obey the GPL in all respects for the Viewer Software and any
work based on the Program, except for the FLOSS Works, for which
you must comply with B below,
B. all FLOSS Works,
i. are distributed subject to one of the FLOSS licenses
listed below, and
ii. the object code or executable form of the FLOSS Works are
accompanied by the complete corresponding
machine-readable source code for those FLOSS Works on the
same medium and under the same FLOSS license as the
corresponding object code or executable forms thereof,
and
C. any works that are aggregated with the Viewer Software or a work
based on the Program on a volume of a storage or distribution
medium in accordance with the GPL, and are not licensed under
the FLOSS licenses listed below, are independent and separate
works in themselves which are not derivatives of either the
Viewer Software, a work based on the Program or a FLOSS Work.
If the above conditions are not met, then the Viewer Software may only
be copied, modified, distributed or used under the terms and
conditions of the GPL or another valid licensing option from Linden
Lab.
1. FLOSS License List
License name Version(s)/Copyright Date
Academic Free License 2.0
Apache Software License 1.0/1.1/2.0
Apple Public Source License 2.0
Artistic license From Perl 5.8.0
BSD license "July 22 1999"
Common Development and
Distribution License (CDDL) 1.0
Common Public License 1.0
GNU Library or "Lesser" General
Public License (LGPL) 2.0/2.1
Jabber Open Source License 1.0
MIT License (As listed in file MIT-License.txt) -
Mozilla Public License (MPL) 1.0/1.1
Open Software License 2.0
OpenSSL license (with
original SSLeay license) "2003" ("1998")
PHP License 3.0
Python license (CNRI Python License) -
Python Software Foundation License 2.1.1
Sleepycat License "1999"
W3C License "2001"
X11 License "2001"
Zlib/libpng License -
Zope Public License 2.0
Due to the many variants of some of the above licenses, we require
that any variant of the above licenses be identical in substance to
the form approved by the Open Source Initiative and follow the 2003
version of the Free Software Foundation's Free Software Definition
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of the
Open Source Definition by the Open Source Initiative
(http://www.opensource.org/docs/definition.php).
2. Definitions
Terms used, but not defined, herein shall have the meaning provided in
the GPL.
3. Applicability
This FLOSS Exception applies to all Viewer Software files that contain
a notice placed by Linden Lab saying that the Viewer Software may be
distributed under the terms of this FLOSS Exception. If you create or
distribute a work which is a work based on the Program for the Viewer
Software and any other work licensed under the GPL, then this FLOSS
Exception is not available for that work; thus, you must remove the
FLOSS Exception notice from that work and comply with the GPL in all
respects, including by retaining all GPL notices. You may choose to
redistribute a copy of the Viewer Software exclusively under the terms
of the GPL by removing the FLOSS Exception notice from that copy of
the Viewer Software, provided that the copy has never been modified by
you or any third party.

339
LICENSES/GPL-license.txt Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,36 @@
Source code
========
The license for the source code in this distribution should be clearly
marked on each source file. Unless otherwise specified, the source
code in this distribution ("Source Code") is provided by Linden Lab to
you under the terms of the GNU General Public License, version 2.0
("GPL"), unless you have obtained a separate licensing agreement
("Other License"), formally executed by you and Linden Lab. Terms of
the GPL can be found in GPL-license.txt in this distribution, or
online at http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
There are special exceptions to the terms and conditions of the GPL as
it is applied to this Source Code. View the full text of the exception
in the file FLOSS-exception.txt in this software distribution, or
online at http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
By copying, modifying or distributing this software, you acknowledge
that you have read and understood your obligations described above,
and agree to abide by those obligations.
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
COMPLETENESS OR PERFORMANCE.
Logos and trademarks
==============
"Second Life" and "Linden Lab" are registered trademarks of Linden
Research, Inc. Other trademarks include (but are not limited to): the
names Linden and Linden Research, as well as the Linden Lab Hexagon
Design and the Second Life Hand Design logos.
Use of logos and trademarks are subject to the Linden Lab trademark
policy, available at:
http://secondlife.com/corporate/trademark/

27
README
View File

@@ -9,15 +9,30 @@
Sin-gu-la-ri-ty (noun) - a distinctive feature, a uniqueness; a point at which
continuity breaks up; a point in history at which machine becomes smarter than
humanity and/or fuses with it indivisively; or simply a cool sounding word with
my initials in it :)
the initials S.G. in it :)
Singularity Viewer is a Second Life protocol compatible client application. It
can be used to access Second LIfe service as well as a number of other such as
those based upon OpenSim plattform. It is directly based upon source code of
Ascent Viewer by Balseraph Software Group, which is in turn based upon source
code released by Linden Lab, with contributions from various sources.
Singularity Viewer is a SecondLife(tm) protocol compatible client application.
It can be used to access SecondLife services as well as a number of others such
as those based upon the OpenSim platform.
Singulariy is maintained by a small group of volunteers who can be contacted
both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer
@ FreeNode). Bug requests and features requests can be submitted through our
Issue Tracker (http://code.google.com/p/singularity-viewer/issues/list or from
the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...)
As this Readme grows out of date, please refer to
http://www.singularityviewer.org/about
00000000011111111112222222222333333333344444444445555555555666666666677777777778
12345678901234567890123456789012345678901234567890123456789012345678901234567890
History
The Singularity viewer was started by Siana Gearz in November 2010 by forking it
from the Ascent Viewer, by Balseraph Software Group, which in turn was based upon
source code modified from the snowglobe source code released by Linden Lab.

View File

@@ -248,6 +248,7 @@ Celierra Darling
VWR-6975
Cron Stardust
VWR-10579
STORM-1919
Cypren Christenson
SNOW-129
SNOW-140

View File

@@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
cmake_policy(SET CMP0003 OLD)
set(ROOT_PROJECT_NAME "Singularity" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
"The root project/makefile/solution name. Defaults to Singularity.")
project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
@@ -46,8 +46,9 @@ endif(NOT STANDALONE)
add_custom_target(prepare DEPENDS ${prepare_depends})
add_subdirectory(cmake)
add_subdirectory(${LIBS_OPEN_PREFIX}cwdebug)
add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine)
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
@@ -62,11 +63,15 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
if(STANDALONE)
add_subdirectory(${LIBS_OPEN_PREFIX}llqtwebkit)
endif(STANDALONE)
if (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)
add_subdirectory(${LIBS_CLOSED_PREFIX}llkdu)
endif (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)
add_subdirectory(${LIBS_OPEN_PREFIX}lscript)
#add_subdirectory(${LIBS_OPEN_PREFIX}lscript)
if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_subdirectory(${LIBS_CLOSED_PREFIX}copy_win_scripts)

View File

@@ -0,0 +1,39 @@
# -*- cmake -*-
project(aistatemachine)
include(00-Common)
include(LLCommon)
include(LLMessage)
include(LLMath)
include(LLXML)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(aistatemachine_SOURCE_FILES
aistatemachine.cpp
aitimer.cpp
)
set(aistatemachine_HEADER_FILES
CMakeLists.txt
aistatemachine.h
aitimer.h
)
set_source_files_properties(${aistatemachine_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND aistatemachine_SOURCE_FILES ${aistatemachine_HEADER_FILES})
add_library (aistatemachine ${aistatemachine_SOURCE_FILES})
add_dependencies(aistatemachine prepare)

View File

@@ -0,0 +1,628 @@
/**
* @file aistatemachine.cpp
* @brief Implementation of AIStateMachine
*
* Copyright (c) 2010, Aleric Inglewood.
*
* 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, see <http://www.gnu.org/licenses/>.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution.
*
* CHANGELOG
* and additional copyright holders.
*
* 01/03/2010
* Initial version, written by Aleric Inglewood @ SL
*/
#include "linden_common.h"
#include <algorithm>
#include "llcontrol.h"
#include "llfasttimer.h"
#include "aithreadsafe.h"
#include "aistatemachine.h"
// Local variables.
namespace {
struct QueueElementComp;
class QueueElement {
private:
AIStateMachine* mStateMachine;
U64 mRuntime;
public:
QueueElement(AIStateMachine* statemachine) : mStateMachine(statemachine), mRuntime(0) { }
friend bool operator==(QueueElement const& e1, QueueElement const& e2) { return e1.mStateMachine == e2.mStateMachine; }
friend struct QueueElementComp;
AIStateMachine& statemachine(void) const { return *mStateMachine; }
void add(U64 count) { mRuntime += count; }
};
struct QueueElementComp {
bool operator()(QueueElement const& e1, QueueElement const& e2) const { return e1.mRuntime < e2.mRuntime; }
};
typedef std::vector<QueueElement> active_statemachines_type;
active_statemachines_type active_statemachines;
}
// static
U64 AIStateMachine::sMaxCount;
AIThreadSafeDC<AIStateMachine::csme_type> AIStateMachine::sContinuedStateMachinesAndMainloopEnabled;
// static
void AIStateMachine::setMaxCount(F32 StateMachineMaxTime)
{
llassert(is_main_thread());
Dout(dc::statemachine, "(Re)calculating AIStateMachine::sMaxCount");
sMaxCount = calc_clock_frequency() * StateMachineMaxTime / 1000;
}
//----------------------------------------------------------------------------
//
// Public methods
//
void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent, bool on_abort_signal_parent)
{
DoutEntering(dc::statemachine, "AIStateMachine::run(" << (void*)parent << ", " << (parent ? parent->state_str(new_parent_state) : "NA") << ", " << abort_parent << ") [" << (void*)this << "]");
// Must be the first time we're being run, or we must be called from a callback function.
llassert(!mParent || mState == bs_callback);
llassert(!mCallback || mState == bs_callback);
// Can only be run when in this state.
llassert(mState == bs_initialize || mState == bs_callback);
// Allow NULL to be passed as parent to signal that we want to reuse the old one.
if (parent)
{
mParent = parent;
// In that case remove any old callback!
if (mCallback)
{
delete mCallback;
mCallback = NULL;
}
mNewParentState = new_parent_state;
mAbortParent = abort_parent;
mOnAbortSignalParent = on_abort_signal_parent;
}
// If abort_parent is requested then a parent must be provided.
llassert(!abort_parent || mParent);
// If a parent is provided, it must be running.
llassert(!mParent || mParent->mState == bs_run);
// Mark that run() has been called, in case we're being called from a callback function.
mState = bs_initialize;
// Set mIdle to false and add statemachine to continued_statemachines.
mSetStateLock.lock();
locked_cont();
}
void AIStateMachine::run(callback_type::signal_type::slot_type const& slot)
{
DoutEntering(dc::statemachine, "AIStateMachine::run(<slot>) [" << (void*)this << "]");
// Must be the first time we're being run, or we must be called from a callback function.
llassert(!mParent || mState == bs_callback);
llassert(!mCallback || mState == bs_callback);
// Can only be run when in this state.
llassert(mState == bs_initialize || mState == bs_callback);
// Clean up any old callbacks.
mParent = NULL;
if (mCallback)
{
delete mCallback;
mCallback = NULL;
}
mCallback = new callback_type(slot);
// Mark that run() has been called, in case we're being called from a callback function.
mState = bs_initialize;
// Set mIdle to false and add statemachine to continued_statemachines.
mSetStateLock.lock();
locked_cont();
}
void AIStateMachine::idle(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::idle() [" << (void*)this << "]");
llassert(is_main_thread());
llassert(!mIdle);
mIdle = true;
mSleep = 0;
#ifdef SHOW_ASSERT
mCalledThreadUnsafeIdle = true;
#endif
}
void AIStateMachine::idle(state_type current_run_state)
{
DoutEntering(dc::statemachine, "AIStateMachine::idle(" << state_str(current_run_state) << ") [" << (void*)this << "]");
llassert(is_main_thread());
llassert(!mIdle);
mSetStateLock.lock();
// Only go idle if the run state is (still) what we expect it to be.
// Otherwise assume that another thread called set_state() and continue running.
if (current_run_state == mRunState)
{
mIdle = true;
mSleep = 0;
}
mSetStateLock.unlock();
}
// About thread safeness:
//
// The main thread initializes a statemachine and calls run, so a statemachine
// runs in the main thread. However, it is allowed that a state calls idle()
// and then allows one or more other threads to call cont() upon some
// event (only once, of course, as idle() has to be called before cont()
// can be called again-- and a non-main thread is not allowed to call idle()).
// Instead of cont() one may also call set_state().
// Of course, this may give rise to a race condition; if that happens then
// the thread that calls cont() (set_state()) first is serviced, and the other
// thread(s) are ignored, as if they never called cont().
void AIStateMachine::locked_cont(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::locked_cont() [" << (void*)this << "]");
llassert(mIdle);
// Atomic test mActive and change mIdle.
mIdleActive.lock();
#ifdef SHOW_ASSERT
mContThread.reset();
#endif
mIdle = false;
bool not_active = mActive == as_idle;
mIdleActive.unlock();
// mActive is only changed in AIStateMachine::mainloop, by the main-thread, and
// here, possibly by any thread. However, after setting mIdle to false above, it
// is impossible for any thread to come here, until after the main-thread called
// idle(). So, if this is the main thread then that certainly isn't going to
// happen until we left this function, while if this is another thread and the
// state machine is already running in the main thread then not_active is false
// and we're already at the end of this function.
// If not_active is true then main-thread is not running this statemachine.
// It might call cont() (or set_state()) but never locked_cont(), and will never
// start actually running until we are done here and release the lock on
// sContinuedStateMachinesAndMainloopEnabled again. It is therefore safe
// to release mSetStateLock here, with as advantage that if we're not the main-
// thread and not_active is true, then the main-thread won't block when it has
// a timer running that times out and calls set_state().
mSetStateLock.unlock();
if (not_active)
{
AIWriteAccess<csme_type> csme_w(sContinuedStateMachinesAndMainloopEnabled);
// See above: it is not possible that mActive was changed since not_active
// was set to true above.
llassert_always(mActive == as_idle);
Dout(dc::statemachine, "Adding " << (void*)this << " to continued_statemachines");
csme_w->continued_statemachines.push_back(this);
if (!csme_w->mainloop_enabled)
{
Dout(dc::statemachine, "Activating AIStateMachine::mainloop.");
csme_w->mainloop_enabled = true;
}
mActive = as_queued;
llassert_always(!mIdle); // It should never happen that the main thread calls idle(), while another thread calls cont() concurrently.
}
}
void AIStateMachine::set_state(state_type state)
{
DoutEntering(dc::statemachine, "AIStateMachine::set_state(" << state_str(state) << ") [" << (void*)this << "]");
// Stop race condition of multiple threads calling cont() or set_state() here.
mSetStateLock.lock();
// Do not call set_state() unless running.
llassert(mState == bs_run || !is_main_thread());
// If this function is called from another thread than the main thread, then we have to ignore
// it if we're not idle and the state is less than the current state. The main thread must
// be able to change the state to anything (also smaller values). Note that that only can work
// if the main thread itself at all times cancels thread callbacks that call set_state()
// before calling idle() again!
//
// Thus: main thead calls idle(), and tells one or more threads to do callbacks on events,
// which (might) call set_state(). If the main thread calls set_state first (currently only
// possible as a result of the use of a timer) it will set mIdle to false (here) then cancel
// the call backs from the other threads and only then call idle() again.
// Thus if you want other threads get here while mIdle is false to be ignored then the
// main thread should use a large value for the new run state.
//
// If a non-main thread calls set_state first, then the state is changed but the main thread
// can still override it if it calls set_state before handling the new state; in the latter
// case it would still be as if the call from the non-main thread was ignored.
//
// Concurrent calls from non-main threads however, always result in the largest state
// to prevail.
// If the state machine is already running, and we are not the main-thread and the new
// state is less than the current state, ignore it.
// Also, if abort() or finish() was called, then we should just ignore it.
if (mState != bs_run ||
(!mIdle && state <= mRunState && !AIThreadID::in_main_thread()))
{
#ifdef SHOW_ASSERT
// It's a bit weird if the same thread does two calls on a row where the second call
// has a smaller value: warn about that.
if (mState == bs_run && mContThread.equals_current_thread())
{
llwarns << "Ignoring call to set_state(" << state_str(state) <<
") by non-main thread before main-thread could react on previous call, "
"because new state is smaller than old state (" << state_str(mRunState) << ")." << llendl;
}
#endif
mSetStateLock.unlock();
return; // Ignore.
}
// Do not call idle() when set_state is called from another thread; use idle(state_type) instead.
llassert(!mCalledThreadUnsafeIdle || is_main_thread());
// Change mRunState to the requested value.
if (mRunState != state)
{
mRunState = state;
Dout(dc::statemachine, "mRunState set to " << state_str(mRunState));
}
// Continue the state machine if appropriate.
if (mIdle)
locked_cont(); // This unlocks mSetStateLock.
else
mSetStateLock.unlock();
// If we get here then mIdle is false, so only mRunState can still be changed but we won't
// call locked_cont() anymore. When the main thread finally picks up on the state change,
// it will cancel any possible callbacks from other threads and process the largest state
// that this function was called with in the meantime.
}
void AIStateMachine::abort(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::abort() [" << (void*)this << "]");
// It's possible that abort() is called before calling AIStateMachine::multiplex.
// In that case the statemachine wasn't initialized yet and we should just kill() it.
if (LL_UNLIKELY(mState == bs_initialize))
{
// It's ok to use the thread-unsafe idle() here, because if the statemachine
// wasn't started yet, then other threads won't call set_state() on it.
if (!mIdle)
idle();
// run() calls locked_cont() after which the top of the mainloop adds this
// state machine to active_statemachines. Therefore, if the following fails
// then either the same statemachine called run() immediately followed by abort(),
// which is not allowed; or there were two active statemachines running,
// the first created a new statemachine and called run() on it, and then
// the other (before reaching the top of the mainloop) called abort() on
// that freshly created statemachine. Obviously, this is highly unlikely,
// but if that is the case then here we bump the statemachine into
// continued_statemachines to prevent kill() to delete this statemachine:
// the caller of abort() does not expect that.
if (LL_UNLIKELY(mActive == as_idle))
{
mSetStateLock.lock();
locked_cont();
idle();
}
kill();
}
else
{
llassert(mState == bs_run);
mSetStateLock.lock();
mState = bs_abort; // Causes additional calls to set_state to be ignored.
mSetStateLock.unlock();
abort_impl();
mAborted = true;
finish();
}
}
void AIStateMachine::finish(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::finish() [" << (void*)this << "]");
mSetStateLock.lock();
llassert(mState == bs_run || mState == bs_abort);
// It is possible that mIdle is true when abort or finish was called from
// outside multiplex_impl. However, that only may be done by the main thread.
llassert(!mIdle || is_main_thread());
if (!mIdle)
idle(); // After calling this, we don't want other threads to call set_state() anymore.
mState = bs_finish; // Causes additional calls to set_state to be ignored.
mSetStateLock.unlock();
finish_impl();
// Did finish_impl call kill()? Then that is only the default. Remember it.
bool default_delete = (mState == bs_killed);
mState = bs_finish;
if (mParent)
{
// It is possible that the parent is not running when the parent is in fact aborting and called
// abort on this object from it's abort_impl function. It that case we don't want to recursively
// call abort again (or change it's state).
if (mParent->running())
{
if (mAborted && mAbortParent)
{
mParent->abort();
mParent = NULL;
}
else if (!mAborted || mOnAbortSignalParent)
{
mParent->set_state(mNewParentState);
}
}
}
// After this (bool)*this evaluates to true and we can call the callback, which then is allowed to call run().
mState = bs_callback;
if (mCallback)
{
// This can/may call kill() that sets mState to bs_kill and in which case the whole AIStateMachine
// will be deleted from the mainloop, or it may call run() that sets mState is set to bs_initialize
// and might change or reuse mCallback or mParent.
mCallback->callback(!mAborted);
if (mState != bs_initialize)
{
delete mCallback;
mCallback = NULL;
mParent = NULL;
}
}
else
{
// Not restarted by callback. Allow run() to be called later on.
mParent = NULL;
}
// Fix the final state.
if (mState == bs_callback)
mState = default_delete ? bs_killed : bs_initialize;
if (mState == bs_killed && mActive == as_idle)
{
// Bump the statemachine onto the active statemachine list, or else it won't be deleted.
mSetStateLock.lock();
locked_cont();
idle();
}
}
void AIStateMachine::kill(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::kill() [" << (void*)this << "]");
// Should only be called from finish() (or when not running (bs_initialize)).
// However, also allow multiple calls to kill() on a row (bs_killed) (which effectively don't do anything).
llassert(mIdle && (mState == bs_callback || mState == bs_finish || mState == bs_initialize || mState == bs_killed));
base_state_type prev_state = mState;
mState = bs_killed;
if (prev_state == bs_initialize && mActive == as_idle)
{
// We're not running (ie being deleted by a parent statemachine), delete it immediately.
delete this;
}
}
// Return stringified 'state'.
char const* AIStateMachine::state_str(state_type state)
{
if (state >= min_state && state < max_state)
{
switch (state)
{
AI_CASE_RETURN(bs_initialize);
AI_CASE_RETURN(bs_run);
AI_CASE_RETURN(bs_abort);
AI_CASE_RETURN(bs_finish);
AI_CASE_RETURN(bs_callback);
AI_CASE_RETURN(bs_killed);
}
}
return state_str_impl(state);
}
//----------------------------------------------------------------------------
//
// Private methods
//
void AIStateMachine::multiplex(U64 current_time)
{
// Return immediately when this state machine is sleeping.
// A negative value of mSleep means we're counting frames,
// a positive value means we're waiting till a certain
// amount of time has passed.
if (mSleep != 0)
{
if (mSleep < 0)
{
if (++mSleep)
return;
}
else
{
if (current_time < (U64)mSleep)
return;
mSleep = 0;
}
}
DoutEntering(dc::statemachine, "AIStateMachine::multiplex() [" << (void*)this << "] [with state: " << state_str(mState == bs_run ? mRunState : mState) << "]");
llassert(mState == bs_initialize || mState == bs_run);
// Real state machine starts here.
if (mState == bs_initialize)
{
mAborted = false;
mState = bs_run;
initialize_impl();
if (mAborted || mState != bs_run)
return;
}
multiplex_impl();
}
//static
void AIStateMachine::add_continued_statemachines(AIReadAccess<csme_type>& csme_r)
{
bool nonempty = false;
for (continued_statemachines_type::const_iterator iter = csme_r->continued_statemachines.begin(); iter != csme_r->continued_statemachines.end(); ++iter)
{
nonempty = true;
active_statemachines.push_back(QueueElement(*iter));
Dout(dc::statemachine, "Adding " << (void*)*iter << " to active_statemachines");
(*iter)->mActive = as_active;
}
if (nonempty)
AIWriteAccess<csme_type>(csme_r)->continued_statemachines.clear();
}
// static
void AIStateMachine::dowork(void)
{
llassert(!active_statemachines.empty());
// Run one or more state machines.
U64 total_clocks = 0;
for (active_statemachines_type::iterator iter = active_statemachines.begin(); iter != active_statemachines.end(); ++iter)
{
AIStateMachine& statemachine(iter->statemachine());
if (!statemachine.mIdle)
{
U64 start = get_clock_count();
// This might call idle() and then pass the statemachine to another thread who then may call cont().
// Hence, after this isn't not sure what mIdle is, and it can change from true to false at any moment,
// if it is true after this function returns.
statemachine.multiplex(start);
U64 delta = get_clock_count() - start;
iter->add(delta);
total_clocks += delta;
if (total_clocks >= sMaxCount)
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
llwarns << "AIStateMachine::mainloop did run for " << (total_clocks * 1000 / calc_clock_frequency()) << " ms." << llendl;
#endif
std::sort(active_statemachines.begin(), active_statemachines.end(), QueueElementComp());
break;
}
}
}
// Remove idle state machines from the loop.
active_statemachines_type::iterator iter = active_statemachines.begin();
while (iter != active_statemachines.end())
{
AIStateMachine& statemachine(iter->statemachine());
// Atomic test mIdle and change mActive.
bool locked = statemachine.mIdleActive.tryLock();
// If the lock failed, then another thread is in the middle of calling cont(),
// thus mIdle will end up false. So, there is no reason to block here; just
// treat mIdle as false already.
if (locked && statemachine.mIdle)
{
// Without the lock, it would be possible that another thread called cont() right here,
// changing mIdle to false again but NOT adding the statemachine to continued_statemachines,
// thinking it is in active_statemachines (and it is), while immediately below it is
// erased from active_statemachines.
statemachine.mActive = as_idle;
// Now, calling cont() is ok -- as that will cause the statemachine to be added to
// continued_statemachines, so it's fine in that case-- even necessary-- to remove it from
// active_statemachines regardless, and we can release the lock here.
statemachine.mIdleActive.unlock();
Dout(dc::statemachine, "Erasing " << (void*)&statemachine << " from active_statemachines");
iter = active_statemachines.erase(iter);
if (statemachine.mState == bs_killed)
{
Dout(dc::statemachine, "Deleting " << (void*)&statemachine);
delete &statemachine;
}
}
else
{
if (locked)
{
statemachine.mIdleActive.unlock();
}
llassert(statemachine.mActive == as_active); // It should not be possible that another thread called cont() and changed this when we are we are not idle.
llassert(statemachine.mState == bs_run || statemachine.mState == bs_initialize);
++iter;
}
}
if (active_statemachines.empty())
{
// If this was the last state machine, remove mainloop from the IdleCallbacks.
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled, true);
if (csme_r->continued_statemachines.empty() && csme_r->mainloop_enabled)
{
Dout(dc::statemachine, "Deactivating AIStateMachine::mainloop: no active state machines left.");
AIWriteAccess<csme_type>(csme_r)->mainloop_enabled = false;
}
}
}
// static
void AIStateMachine::flush(void)
{
DoutEntering(dc::curl, "AIStateMachine::flush(void)");
{
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled);
add_continued_statemachines(csme_r);
}
// Abort all state machines.
for (active_statemachines_type::iterator iter = active_statemachines.begin(); iter != active_statemachines.end(); ++iter)
{
AIStateMachine& statemachine(iter->statemachine());
if (statemachine.abortable())
{
// We can't safely call abort() here for non-running (run() was called, but they weren't initialized yet) statemachines,
// because that might call kill() which in some cases is undesirable (ie, when it is owned by a partent that will
// also call abort() on it when it is aborted itself).
if (statemachine.running())
statemachine.abort();
else
statemachine.idle(); // Stop the statemachine from starting, in the next loop with batch == 0.
}
}
for (int batch = 0;; ++batch)
{
// Run mainloop until all state machines are idle (batch == 0) or deleted (batch == 1).
for(;;)
{
{
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled);
if (!csme_r->mainloop_enabled)
break;
}
mainloop();
}
if (batch == 1)
break;
{
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled);
add_continued_statemachines(csme_r);
}
}
// At this point all statemachines should be idle.
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled);
llinfos << "Current number of continued statemachines: " << csme_r->continued_statemachines.size() << llendl;
llinfos << "Current number of active statemachines: " << active_statemachines.size() << llendl;
llassert(csme_r->continued_statemachines.empty() && active_statemachines.empty());
}

View File

@@ -192,6 +192,15 @@ class AIStateMachine {
as_active // State machine is on active_statemachines list.
};
//! Type of continued_statemachines.
typedef std::vector<AIStateMachine*> continued_statemachines_type;
//! Type of sContinuedStateMachinesAndMainloopEnabled.
struct csme_type
{
continued_statemachines_type continued_statemachines;
bool mainloop_enabled;
};
public:
typedef U32 state_type; //!< The type of mRunState
@@ -207,12 +216,17 @@ class AIStateMachine {
active_type mActive; //!< Whether statemachine is idle, queued to be added to the active list, or already on the active list.
S64 mSleep; //!< Non-zero while the state machine is sleeping.
LLMutex mIdleActive; //!< Used for atomic operations on the pair mIdle / mActive.
#ifdef SHOW_ASSERT
AIThreadID mContThread; //!< Thread that last called locked_cont().
bool mCalledThreadUnsafeIdle; //!< Set to true when idle() is called.
#endif
// Callback facilities.
// From within an other state machine:
AIStateMachine* mParent; //!< The parent object that started this state machine, or NULL if there isn't any.
state_type mNewParentState; //!< The state at which the parent should continue upon a successful finish.
bool mAbortParent; //!< If true, abort parent on abort(). Otherwise continue as normal.
bool mOnAbortSignalParent; //!< If true and mAbortParent is false, change state of parent even on abort.
// From outside a state machine:
struct callback_type {
typedef boost::signals2::signal<void (bool)> signal_type;
@@ -225,24 +239,34 @@ class AIStateMachine {
};
callback_type* mCallback; //!< Pointer to signal/connection, or NULL when not connected.
static AIThreadSafeSimpleDC<U64> sMaxCount; //!< Number of cpu clocks below which we start a new state machine within the same frame.
static U64 sMaxCount; //!< Number of cpu clocks below which we start a new state machine within the same frame.
static AIThreadSafeDC<csme_type> sContinuedStateMachinesAndMainloopEnabled; //!< Read/write locked variable pair.
protected:
LLMutex mSetStateLock; //!< For critical areas in set_state() and locked_cont().
//! State of the derived class. Only valid if mState == bs_run. Call set_state to change.
state_type mRunState;
volatile state_type mRunState;
public:
//! Create a non-running state machine.
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0), mParent(NULL), mCallback(NULL) { updateSettings(); }
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0), mParent(NULL), mCallback(NULL)
#ifdef SHOW_ASSERT
, mContThread(AIThreadID::none), mCalledThreadUnsafeIdle(false)
#endif
{ }
protected:
//! The user should call 'kill()', not delete a AIStateMachine (derived) directly.
virtual ~AIStateMachine() { llassert(mState == bs_killed && mActive == as_idle); }
virtual ~AIStateMachine() { llassert((mState == bs_killed && mActive == as_idle) || mState == bs_initialize); }
public:
//! Halt the state machine until cont() is called.
//! Halt the state machine until cont() is called (not thread-safe).
void idle(void);
//! Halt the state machine until cont() is called, provided it is still in 'cur_run_state'.
void idle(state_type current_run_state);
//! Temporarily halt the state machine.
void yield_frame(unsigned int frames) { mSleep = -(S64)frames; }
@@ -250,15 +274,25 @@ class AIStateMachine {
void yield_ms(unsigned int ms) { mSleep = get_clock_count() + calc_clock_frequency() * ms / 1000; }
//! Continue running after calling idle.
void cont(void);
void cont(void)
{
mSetStateLock.lock();
// Ignore calls to cont() if the statemachine isn't idle. See comments in set_state().
// Calling cont() twice or after calling set_state(), without first calling idle(), is an error.
if (mState != bs_run || !mIdle) { llassert(mState != bs_run || !mContThread.equals_current_thread()); mSetStateLock.unlock(); return; }
locked_cont();
}
private:
void locked_cont(void);
public:
//---------------------------------------
// Changing the state.
//! Change state to <code>bs_run</code>. May only be called after creation or after returning from finish().
// If <code>parent</code> is non-NULL, change the parent state machine's state to <code>new_parent_state</code>
// upon finish, or in the case of an abort and when <code>abort_parent</code> is true, call parent->abort() instead.
void run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent = true);
void run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent = true, bool on_abort_signal_parent = true);
//! Change state to 'bs_run'. May only be called after creation or after returning from finish().
// Does not cause a callback.
@@ -315,7 +349,7 @@ class AIStateMachine {
// Other.
//! Called whenever the StateMachineMaxTime setting is changed.
static void updateSettings(void);
static void setMaxCount(F32 StateMachineMaxTime);
//---------------------------------------
// Accessors.
@@ -326,11 +360,14 @@ class AIStateMachine {
//! Return true if the derived class is running (also when we are idle).
bool running(void) const { return mState == bs_run; }
//! Return true if it's safe to call abort.
bool abortable(void) const { return mState == bs_run || mState == bs_initialize; }
//! Return true if the derived class is running but idle.
bool waiting(void) const { return mState == bs_run && mIdle; }
// Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
typedef state_type AIStateMachine::* const bool_type;
typedef volatile state_type AIStateMachine::* const bool_type;
//! Return true if state machine successfully finished.
operator bool_type() const { return ((mState == bs_initialize || mState == bs_callback) && !mAborted) ? &AIStateMachine::mRunState : 0; }
@@ -338,9 +375,27 @@ class AIStateMachine {
char const* state_str(state_type state);
private:
static void mainloop(void*);
static void add_continued_statemachines(AIReadAccess<csme_type>& csme_r);
static void dowork(void);
void multiplex(U64 current_time);
public:
//! Call this once per frame to give the statemachines CPU cycles.
static void mainloop(void)
{
{
AIReadAccess<csme_type> csme_r(sContinuedStateMachinesAndMainloopEnabled, true);
if (!csme_r->mainloop_enabled)
return;
if (!csme_r->continued_statemachines.empty())
add_continued_statemachines(csme_r);
}
dowork();
}
//! Abort all running state machines and then run mainloop until all state machines are idle (called when application is exiting).
static void flush(void);
protected:
//---------------------------------------
// Derived class implementations.

View File

@@ -70,7 +70,6 @@ class AITimer : public AIStateMachine {
* @brief Set the interval after which the timer should expire.
*
* @param interval Amount of time in seconds before the timer will expire.
* @param True if the timer should be deleted after it expires; false means it will keep firing at regular intervals.
*
* Call abort() at any time to stop the timer (and delete the AITimer object).
*/

View File

@@ -1,4 +1,4 @@
# -*- cmake -*-
set(AISTATEMACHINE_INCLUDE_DIRS statemachine)
set(AISTATEMACHINE_LIBRARIES statemachine)
set(AISTATEMACHINE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/aistatemachine)
set(AISTATEMACHINE_LIBRARIES aistatemachine)

View File

@@ -41,6 +41,7 @@ set(cmake_SOURCE_FILES
Hunspell.cmake
JPEG.cmake
LLAddBuildTest.cmake
LLAppearance.cmake
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
@@ -54,13 +55,14 @@ set(cmake_SOURCE_FILES
LLMessage.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLQtWebkit.cmake
LLRender.cmake
LLScene.cmake
LLUI.cmake
LLVFS.cmake
LLWindow.cmake
LLXML.cmake
LScript.cmake
# LScript.cmake
Linking.cmake
NDOF.cmake
OPENAL.cmake
@@ -70,6 +72,7 @@ set(cmake_SOURCE_FILES
PNG.cmake
Python.cmake
Prebuilt.cmake
Qt4.cmake
RunBuildTest.cmake
TemplateCheck.cmake
Tut.cmake

View File

@@ -1,7 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
set(CURL_FIND_QUIETLY ON)
set(CURL_FIND_QUIETLY OFF)
set(CURL_FIND_REQUIRED ON)
if (STANDALONE)

View File

@@ -1 +1,18 @@
set(CWDEBUG_LIBRARIES cwdebug)
include_directories (${CMAKE_SOURCE_DIR}/cwdebug)
set(cwdebug_SOURCE_FILES
${CMAKE_SOURCE_DIR}/cwdebug/debug.cc
)
set(cwdebug_HEADER_FILES
${CMAKE_SOURCE_DIR}/cwdebug/cwdebug.h
${CMAKE_SOURCE_DIR}/cwdebug/sys.h
${CMAKE_SOURCE_DIR}/cwdebug/debug.h
${CMAKE_SOURCE_DIR}/cwdebug/debug_ostream_operators.h
)
set_source_files_properties(${cwdebug_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})

View File

@@ -3,16 +3,18 @@
# - Find JSONCpp
# Find the JSONCpp includes and library
# This module defines
# JSONCPP_INCLUDE_DIR, where to find json.h, etc.
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
# also defined, but not for general use are
# JSONCPP_LIBRARY, where to find the jsoncpp library.
# JSONCPP_FOUND, System has libjsoncpp.
# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories.
# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp.
# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp.
FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h
/usr/local/include
/usr/include
)
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_JSONCPP jsoncpp)
SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER})
FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h
HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS}
PATH_SUFFIXES jsoncpp)
# Get the GCC compiler version
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
@@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
)
# Try to find a library that was compiled with the same compiler version as we currently use.
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
IF (STANDALONE)
# On standalone, assume that the system installed library was compiled with the used compiler.
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
ENDIF (STANDALONE)
FIND_LIBRARY(JSONCPP_LIBRARY
NAMES ${JSONCPP_NAMES}
PATHS /usr/lib /usr/local/lib
)
NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so
HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS}
PATHS /usr/lib /usr/local/lib)
IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
SET(JSONCPP_FOUND "YES")
ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_FOUND "NO")
ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG
JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
IF (JSONCPP_FOUND)
IF (NOT JSONCPP_FIND_QUIETLY)
MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
ENDIF (NOT JSONCPP_FIND_QUIETLY)
ELSE (JSONCPP_FOUND)
IF (JSONCPP_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
ENDIF (JSONCPP_FIND_REQUIRED)
ENDIF (JSONCPP_FOUND)
# Deprecated declarations.
SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
MARK_AS_ADVANCED(
JSONCPP_LIBRARY
JSONCPP_INCLUDE_DIR
)
MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)

View File

@@ -11,10 +11,10 @@ else (STANDALONE)
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
use_prebuilt_binary(gperftools)
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
if (WINDOWS)
if (WINDOWS AND NOT DISABLE_TCMALLOC)
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
endif (WINDOWS)
endif (WINDOWS AND NOT DISABLE_TCMALLOC)
if (LINUX)
if(USE_GOOGLE_PERFTOOLS)
set(TCMALLOC_LIBRARIES tcmalloc)

View File

@@ -2,7 +2,7 @@
include(Prebuilt)
set(JSONCPP_FIND_QUIETLY ON)
set(JSONCPP_FIND_QUIETLY OFF)
set(JSONCPP_FIND_REQUIRED ON)
if (STANDALONE)

View File

@@ -0,0 +1,11 @@
# -*- cmake -*-
include(Variables)
set(LLAPPEARANCE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llappearance
)
set(LLAPPEARANCE_LIBRARIES llappearance)

View File

@@ -4,12 +4,14 @@ include(CARes)
include(CURL)
include(OpenSSL)
include(XmlRpcEpi)
include(AIStateMachine)
set(LLMESSAGE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llmessage
${CARES_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${AISTATEMACHINE_INCLUDE_DIRS}
)
set(LLMESSAGE_LIBRARIES llmessage)
set(LLMESSAGE_LIBRARIES llmessage aistatemachine)

View File

@@ -0,0 +1,11 @@
# -*- cmake -*-
if (STANDALONE)
set(LLQTWEBKIT_INCLUDE_DIR
${LIBS_OPEN_DIR}/llqtwebkit
)
set(LLQTWEBKIT_LIBRARY
llqtwebkit
)
endif (STANDALONE)

12
indra/cmake/Qt4.cmake Normal file
View File

@@ -0,0 +1,12 @@
# -*- cmake -*-
include(Prebuilt)
if (STANDALONE)
set(Qt4_FIND_REQUIRED ON)
include(FindQt4)
find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
endif (STANDALONE)

View File

@@ -0,0 +1,4 @@
# -*- cmake -*-
set(STATEMACHINE_INCLUDE_DIRS statemachine)
set(STATEMACHINE_LIBRARIES statemachine)

View File

@@ -30,6 +30,7 @@ set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)")
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)")

View File

@@ -19,8 +19,3 @@ else (NOT STANDALONE)
endif(LINUX AND ${ARCH} STREQUAL "x86_64")
set(STANDALONE ON)
endif(NOT STANDALONE)
if (WINDOWS)
use_prebuilt_binary(dbghelp)
endif (WINDOWS)

View File

@@ -1,31 +1,10 @@
# -*- cmake -*-
include(Linking)
include(Prebuilt)
include(LLQtWebkit)
include(Qt4)
if (STANDALONE)
# The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
include(${QT_USE_FILE})
set(QTDIR $ENV{QTDIR})
if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
"Qt is found by looking for qmake in your PATH. "
"Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
"or unset QTDIR if the found Qt is correct.")
endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
find_package(LLQtWebkit REQUIRED QUIET)
# Add the plugins.
set(QT_PLUGIN_LIBRARIES)
foreach(qlibname qgif qjpeg)
find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
if (QT_PLUGIN_${qlibname})
list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
else (QT_PLUGIN_${qtlibname})
message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
endif (QT_PLUGIN_${qlibname})
endforeach(qlibname)
# qjpeg depends on libjpeg
list(APPEND QT_PLUGIN_LIBRARIES jpeg)
set(WEBKITLIBPLUGIN OFF CACHE BOOL
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
else (STANDALONE)

View File

@@ -1,39 +0,0 @@
# -*- cmake -*-
project(cwdebug)
include(00-Common)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
set(cwdebug_SOURCE_FILES
debug.cc
)
set(cwdebug_HEADER_FILES
CMakeLists.txt
cwdebug.h
sys.h
debug.h
debug_ostream_operators.h
)
set_source_files_properties(${cwdebug_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif(WINDOWS)
endif (NOT WORD_SIZE EQUAL 32)
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})
add_library (cwdebug ${cwdebug_SOURCE_FILES})

View File

@@ -49,6 +49,8 @@
namespace debug {
#if CWDEBUG_LOCATION
ll_thread_local size_t BackTrace::S_number;
void BackTrace::dump_backtrace(void) const
{
for (int frame = 0; frame < frames(); ++frame)
@@ -67,6 +69,67 @@ void BackTrace::dump_backtrace(void) const
Dout(dc::finish, mangled_function_name);
}
}
void BackTraces::store_trace(size_t trace)
{
mBackTraces.push_back(trace);
}
void BackTraces::remove_trace(size_t trace)
{
trace_container_type::iterator iter = mBackTraces.begin();
while (iter != mBackTraces.end())
{
if (*iter == trace)
{
*iter = mBackTraces.back();
mBackTraces.pop_back();
return;
}
++iter;
}
DoutFatal(dc::core, "Trace doesn't exist!");
}
void BackTraces::dump(void) const
{
Dout(dc::backtrace|continued_cf, "Dump for (BackTraces*)" << (void*)this << " (" << mBackTraces.size() << " backtraces): ");
for (trace_container_type::const_iterator iter = mBackTraces.begin(); iter != mBackTraces.end(); ++iter)
{
Dout(dc::continued|nonewline_cf, *iter << ' ');
}
Dout(dc::finish, "");
}
BackTraceTracker::BackTraceTracker(BackTraces* back_traces) : mBackTraces(back_traces)
{
BACKTRACE;
mTrace = BackTrace::S_number;
mBackTraces->store_trace(mTrace);
}
BackTraceTracker::~BackTraceTracker()
{
mBackTraces->remove_trace(mTrace);
}
BackTraceTracker::BackTraceTracker(BackTraceTracker const& orig) : mBackTraces(orig.mBackTraces)
{
BACKTRACE;
mTrace = BackTrace::S_number;
mBackTraces->store_trace(mTrace);
}
BackTraceTracker& BackTraceTracker::operator=(BackTraceTracker const& orig)
{
mBackTraces->remove_trace(mTrace);
mBackTraces = orig.mBackTraces;
BACKTRACE;
mTrace = BackTrace::S_number;
mBackTraces->store_trace(mTrace);
return *this;
}
#endif // CWDEBUG_LOCATION
#if CWDEBUG_ALLOC && CWDEBUG_LOCATION
@@ -173,6 +236,8 @@ void stop_recording_backtraces(void)
channel_ct backtrace DDCN("BACKTRACE"); //!< This debug channel is used for backtraces.
channel_ct statemachine DDCN("STATEMACHINE"); //!< This debug channel is used for output related to class AIStateMachine.
channel_ct caps DDCN("CAPS"); //!< This debug channel is used for output related to Capabilities.
channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to Curl.
channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl.
} // namespace dc
} // namespace DEBUGCHANNELS
@@ -411,4 +476,94 @@ void cwdebug_backtrace(int n)
}
#endif
#endif // CWDEBUG
#elif defined(DEBUG_CURLIO)
#include "debug.h"
#include "aithreadid.h"
namespace debug
{
namespace libcwd { libcwd_do_type const libcw_do; }
ll_thread_local int Indent::S_indentation;
Indent::Indent(int indent) : M_indent(indent)
{
S_indentation += M_indent;
}
Indent::~Indent()
{
S_indentation -= M_indent;
}
std::ostream& operator<<(std::ostream& os, Indent::print_nt)
{
if (Indent::S_indentation)
os << std::string(Indent::S_indentation, ' ');
return os;
}
#ifdef DEBUG_CURLIO
std::ostream& operator<<(std::ostream& os, print_thread_id_t)
{
if (!AIThreadID::in_main_thread_inline())
{
os << std::hex << (size_t)AIThreadID::getCurrentThread_inline() << std::dec << ' ';
}
return os;
}
#endif
std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s)
{
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };
size_t size = b2s.mSize;
for (char const* p1 = b2s.mBuf; size > 0; --size, ++p1)
{
char c =*p1;
if ((c > 31 && c != 92 && c != 127) || (unsigned char)c > 159)
os.put(c);
else
{
os.put('\\');
if (c > 6 && c < 14)
{
os.put(c2s_tab[c - 7]);
return os;
}
else if (c == 27)
{
os.put('e');
return os;
}
else if (c == '\\')
{
os.put('\\');
return os;
}
std::ostream::char_type old_fill = os.fill('0');
std::ios_base::fmtflags old_flgs = os.flags();
os.width(3);
os << std::oct << (int)((unsigned char)c);
os.setf(old_flgs);
os.fill(old_fill);
}
}
return os;
}
namespace dc
{
fake_channel const warning(1, "WARNING ");
fake_channel const curl(1, "CURL ");
fake_channel const curlio(1, "CURLIO ");
fake_channel const statemachine(1, "STATEMACHINE");
fake_channel const notice(1, "NOTICE ");
} // namespace dc
} // namespace debug
#endif

View File

@@ -27,6 +27,94 @@
#ifndef CWDEBUG
#ifdef DEBUG_CURLIO
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
// some of the cwd macro's with something that generates viewer
// specific debug output. Note that this generates a LOT of
// output and should not normally be defined.
#include <string>
#include "llpreprocessor.h"
namespace debug {
namespace libcwd {
struct buf2str {
buf2str(char const* buf, int size) : mBuf(buf), mSize(size) { }
char const* mBuf;
int mSize;
};
struct libcwd_do_type {
void on() const { }
};
extern LL_COMMON_API libcwd_do_type const libcw_do;
} // namespace libcwd
enum print_thread_id_t { print_thread_id };
inline void init() { }
struct Indent {
int M_indent;
static ll_thread_local int S_indentation;
enum LL_COMMON_API print_nt { print };
LL_COMMON_API Indent(int indent);
LL_COMMON_API ~Indent();
};
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
namespace dc {
struct fake_channel {
int mOn;
char const* mLabel;
fake_channel(int on, char const* label) : mOn(on), mLabel(label) { }
fake_channel(void) : mOn(0) { }
bool is_on() const { return !!mOn; }
bool is_off() const { return !mOn; }
void on() const { }
void off() const { }
};
extern LL_COMMON_API fake_channel const warning;
extern LL_COMMON_API fake_channel const curl;
extern LL_COMMON_API fake_channel const curlio;
extern LL_COMMON_API fake_channel const statemachine;
extern LL_COMMON_API fake_channel const notice;
} // namespace dc
} // namespace debug
#define LIBCWD_DEBUG_CHANNELS debug
#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; using namespace debug::libcwd; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print;
#define LibcwDoutStream llcont
#define LibcwDoutScopeEnd llcont << llendl; } while(0)
#define Debug(x) do { using namespace debug; using namespace debug::libcwd; x; } while(0)
#define Dout(a, b) do { using namespace debug; using namespace debug::libcwd; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
#define DoutEntering(a, b) \
int __slviewer_debug_indentation = 2; \
{ \
using namespace debug; \
using namespace debug::libcwd; \
if ((a).mOn) \
llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
else \
__slviewer_debug_indentation = 0; \
} \
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
#else // !DEBUG_CURLIO
#define Debug(x)
#define Dout(a, b)
#define DoutEntering(a, b)
#endif // !DEBUG_CURLIO
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
#include <iostream>
@@ -36,9 +124,6 @@
#define AllocTag2(p, desc)
#define AllocTag_dynamic_description(p, x)
#define AllocTag(p, x)
#define Debug(x)
#define Dout(a, b)
#define DoutEntering(a, b)
#define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
#define ForAllDebugChannels(STATEMENT)
#define ForAllDebugObjects(STATEMENT)
@@ -88,7 +173,9 @@
#include <boost/shared_array.hpp>
#if CWDEBUG_LOCATION
#include <execinfo.h> // Needed for 'backtrace'.
#include "llpreprocessor.h"
#endif
#include <set>
#define CWD_API __attribute__ ((visibility("default")))
@@ -118,6 +205,8 @@ extern CWD_API channel_ct sdl;
extern CWD_API channel_ct backtrace;
extern CWD_API channel_ct statemachine;
extern CWD_API channel_ct caps;
extern CWD_API channel_ct curl;
extern CWD_API channel_ct curlio;
#endif
@@ -186,6 +275,8 @@ class BackTrace {
private:
boost::shared_array<void*> M_buffer;
int M_frames;
public:
static ll_thread_local size_t S_number;
public:
BackTrace(void** buffer, int frames) : M_buffer(new void* [frames]), M_frames(frames) { std::memcpy(M_buffer.get(), buffer, sizeof(void*) * frames); }
@@ -212,19 +303,81 @@ extern pthread_mutex_t backtrace_mutex;
using namespace debug; \
void* buffer[32]; \
int frames = backtrace(buffer, 32); \
size_t size; \
{ \
pthread_mutex_lock(&backtrace_mutex); \
backtraces.push_back(BackTrace(buffer, frames)); \
size = backtraces.size(); \
BackTrace::S_number = backtraces.size(); \
pthread_mutex_unlock(&backtrace_mutex); \
} \
Dout(dc::backtrace, "Stored backtrace #" << size); \
Dout(dc::backtrace, "Stored backtrace #" << BackTrace::S_number); \
} while(0)
class LL_COMMON_API BackTraces {
private:
typedef std::vector<size_t> trace_container_type;
trace_container_type mBackTraces;
public:
void store_trace(size_t trace);
void remove_trace(size_t trace);
void dump(void) const;
};
class LL_COMMON_API BackTraceTracker {
private:
BackTraces* mBackTraces;
size_t mTrace;
public:
BackTraceTracker(BackTraces* back_traces);
~BackTraceTracker();
BackTraceTracker(BackTraceTracker const&);
BackTraceTracker& operator=(BackTraceTracker const&);
void dump(void) const { mBackTraces->dump(); }
};
#else
#define BACKTRACE do { } while(0)
#endif // CWDEBUG_LOCATION
template<class T>
class LL_COMMON_API InstanceTracker {
private:
T const* mInstance;
static pthread_mutex_t sInstancesMutex;
static std::set<T const*> sInstances;
static void remember(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.insert(instance); pthread_mutex_unlock(&sInstancesMutex); }
static void forget(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.erase(instance); pthread_mutex_unlock(&sInstancesMutex); }
public:
InstanceTracker(T const* instance) : mInstance(instance) { remember(mInstance); }
~InstanceTracker() { forget(mInstance); }
InstanceTracker& operator=(InstanceTracker const& orig) { forget(mInstance); mInstance = orig.mInstance; remember(mInstance); return *this; }
static void dump(void);
private:
// Non-copyable. Instead of copying, call InstanceTracker(T const*) with the this pointer of the new instance.
InstanceTracker(InstanceTracker const& orig);
};
template<class T>
pthread_mutex_t InstanceTracker<T>::sInstancesMutex = PTHREAD_MUTEX_INITIALIZER;
template<class T>
std::set<T const*> InstanceTracker<T>::sInstances;
template<class T>
void InstanceTracker<T>::dump(void)
{
pthread_mutex_lock(&sInstancesMutex);
for (typename std::set<T const*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
std::cout << *iter << std::endl;
}
pthread_mutex_unlock(&sInstancesMutex);
}
} // namespace debug
//! Debugging macro.

View File

@@ -782,13 +782,14 @@ Commands:
Command-options for "configure":
We use cmake variables to change the build configuration.
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
-DVIEWER:BOOL=OFF Don't configure the viewer
-DPACKAGE:BOOL=ON Create "package" target to make installers
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
-VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
-DVIEWER:BOOL=OFF Don't configure the viewer
-DPACKAGE:BOOL=ON Create "package" target to make installers
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
-DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)
-DVISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
Examples:
Set up a viewer-only project for your system:

View File

@@ -7,14 +7,15 @@ include(00-Common)
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 1)
set(OPENJPEG_VERSION_MINOR 4)
set(OPENJPEG_VERSION_BUILD 0)
set(OPENJPEG_VERSION_MINOR 5)
set(OPENJPEG_VERSION_BUILD 2)
set(OPENJPEG_VERSION
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
set(openjpeg_SOURCE_FILES
bio.c
cio.c
cidx_manager.c
dwt.c
event.c
image.c
@@ -26,20 +27,26 @@ set(openjpeg_SOURCE_FILES
mqc.c
openjpeg.c
pi.c
phix_manager.c
ppix_manager.c
raw.c
t1.c
t2.c
tcd.c
tgt.c
thix_manager.c
tpix_manager.c
)
set(openjpeg_HEADER_FILES
bio.h
cio.h
cidx_manager.h
dwt.h
event.h
event.h
fix.h
image.h
indexbox_manager.h
int.h
j2k.h
j2k_lib.h
@@ -48,6 +55,7 @@ set(openjpeg_HEADER_FILES
mct.h
mqc.h
openjpeg.h
opj_config.h
opj_includes.h
opj_malloc.h
pi.h

View File

@@ -0,0 +1,211 @@
/*
* $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opj_includes.h"
/*
* Write CPTR Codestream finder box
*
* @param[in] coff offset of j2k codestream
* @param[in] clen length of j2k codestream
* @param[in] cio file output handle
*/
void write_cptr(int coff, int clen, opj_cio_t *cio);
/*
* Write main header index table (box)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] cio file output handle
* @return length of mainmhix box
*/
int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
/*
* Check if EPH option is used
*
* @param[in] coff offset of j2k codestream
* @param[in] markers marker information
* @param[in] marknum number of markers
* @param[in] cio file output handle
* @return true if EPH is used
*/
opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
{
int len, i, lenp;
opj_jp2_box_t *box;
int num_box = 0;
opj_bool EPHused;
(void)image; /* unused ? */
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
for (i=0;i<2;i++){
if(i)
cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_CIDX, 4); /* CIDX */
write_cptr( offset, cstr_info.codestream_size, cio);
write_manf( i, num_box, box, cio);
num_box = 0;
box[num_box].length = write_mainmhix( offset, cstr_info, cio);
box[num_box].type = JPIP_MHIX;
num_box++;
box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
box[num_box].type = JPIP_TPIX;
num_box++;
box[num_box].length = write_thix( offset, cstr_info, cio);
box[num_box].type = JPIP_THIX;
num_box++;
EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
box[num_box].type = JPIP_PPIX;
num_box++;
box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
box[num_box].type = JPIP_PHIX;
num_box++;
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free( box);
return len;
}
void write_cptr(int coff, int clen, opj_cio_t *cio)
{
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_CPTR, 4); /* T */
cio_write( cio, 0, 2); /* DR A PRECISER !! */
cio_write( cio, 0, 2); /* CONT */
cio_write( cio, coff, 8); /* COFF A PRECISER !! */
cio_write( cio, clen, 8); /* CLEN */
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
{
int len, lenp, i;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MANF,4); /* T */
if (second){ /* Write only during the second pass */
for( i=0; i<v; i++){
cio_write( cio, box[i].length, 4); /* Box length */
cio_write( cio, box[i].type, 4); /* Box type */
}
}
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
{
int i;
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MHIX, 4); /* MHIX */
cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8); /* TLEN */
for(i = 1; i < cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */
cio_write( cio, cstr_info.marker[i].type, 2);
cio_write( cio, 0, 2);
cio_write( cio, cstr_info.marker[i].pos-coff, 8);
cio_write( cio, cstr_info.marker[i].len, 2);
}
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
{
opj_bool EPHused = OPJ_FALSE;
int i=0;
int org_pos;
unsigned int Scod;
for(i = 0; i < marknum; i++){
if( markers[i].type == J2K_MS_COD){
org_pos = cio_tell( cio);
cio_seek( cio, coff+markers[i].pos+2);
Scod = cio_read( cio, 1);
if( ((Scod >> 2) & 1))
EPHused = OPJ_TRUE;
cio_seek( cio, org_pos);
break;
}
}
return EPHused;
}

View File

@@ -0,0 +1,56 @@
/*
* $Id: cidx_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.h from 2KAN indexer
*/
#ifndef CIDX_MANAGER_H_
# define CIDX_MANAGER_H_
#include "openjpeg.h"
/*
* Write Codestream index box (superbox)
*
* @param[in] offset offset of j2k codestream
* @param[in] cio file output handle
* @param[in] image image data
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @return length of cidx box
*/
int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen);
#endif /* !CIDX_MANAGER_H_ */

View File

@@ -126,13 +126,13 @@ unsigned char *cio_getbp(opj_cio_t *cio) {
/*
* Write a byte.
*/
bool cio_byteout(opj_cio_t *cio, unsigned char v) {
opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
if (cio->bp >= cio->end) {
opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
return false;
return OPJ_FALSE;
}
*cio->bp++ = v;
return true;
return OPJ_TRUE;
}
/*
@@ -152,7 +152,7 @@ unsigned char cio_bytein(opj_cio_t *cio) {
* v : value to write
* n : number of bytes to write
*/
unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) {
unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) {
int i;
for (i = n - 1; i >= 0; i--) {
if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )

View File

@@ -31,6 +31,13 @@
#ifndef __CIO_H
#define __CIO_H
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define int64 __int64
#else
#define int64 long long
#endif
/**
@file cio.h
@brief Implementation of a byte input-output process (CIO)
@@ -63,7 +70,7 @@ Write some bytes
@param n Number of bytes to write
@return Returns the number of bytes written or 0 if an error occured
*/
unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n);
unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n);
/**
Read some bytes
@param cio CIO handle

View File

@@ -64,12 +64,12 @@ typedef struct v4dwt_local {
int cas ;
} v4dwt_t ;
static const float dwt_alpha = 1.586134342f; // 12994
static const float dwt_beta = 0.052980118f; // 434
static const float dwt_gamma = -0.882911075f; // -7233
static const float dwt_delta = -0.443506852f; // -3633
static const float dwt_alpha = 1.586134342f; /* 12994 */
static const float dwt_beta = 0.052980118f; /* 434 */
static const float dwt_gamma = -0.882911075f; /* -7233 */
static const float dwt_delta = -0.443506852f; /* -3633 */
static const float K = 1.230174105f; // 10078
static const float K = 1.230174105f; /* 10078 */
/* FIXME: What is this constant? */
static const float c13318 = 1.625732422f;
@@ -527,7 +527,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
int w = tilec->x1 - tilec->x0;
h.mem = (int *)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
v.mem = h.mem;
while( --numres) {
@@ -570,7 +570,7 @@ static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, in
int count = w->sn;
int i, k;
for(k = 0; k < 2; ++k){
if (count + 3 * x < size && ((long) a & 0x0f) == 0 && ((long) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
/* Fast code path */
for(i = 0; i < count; ++i){
int j = i;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +26,42 @@
#include "opj_includes.h"
/* ==========================================================
Utility functions
==========================================================*/
#ifdef OPJ_CODE_NOT_USED
#ifndef _WIN32
static char*
i2a(unsigned i, char *a, unsigned r) {
if (i/r > 0) a = i2a(i/r,a,r);
*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
return a+1;
}
/**
Transforms integer i into an ascii string and stores the result in a;
string is encoded in the base indicated by r.
@param i Number to be converted
@param a String result
@param r Base of value; must be in the range 2 - 36
@return Returns a
*/
static char *
_itoa(int i, char *a, int r) {
r = ((r < 2) || (r > 36)) ? 10 : r;
if(i < 0) {
*a = '-';
*i2a(-i, a+1, r) = 0;
}
else *i2a(i, a, r) = 0;
return a;
}
#endif /* !_WIN32 */
#endif
/* ----------------------------------------------------------------------- */
opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) {
if(cinfo) {
opj_event_mgr_t *previous = cinfo->event_mgr;
@@ -37,7 +73,7 @@ opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_
return NULL;
}
bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
opj_msg_callback msg_handler = NULL;
@@ -57,30 +93,29 @@ bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
break;
}
if(msg_handler == NULL) {
return false;
return OPJ_FALSE;
}
} else {
return false;
return OPJ_FALSE;
}
if ((fmt != NULL) && (event_mgr != NULL)) {
va_list arg;
int str_length/*, i, j*/; /* UniPG */
char message[MSG_SIZE];
memset(message, 0, MSG_SIZE);
/* initialize the optional parameter list */
va_start(arg, fmt);
/* check the length of the format string */
str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt);
/* parse the format string and put the result in 'message' */
vsprintf(message, fmt, arg); /* UniPG */
str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */
/* deinitialize the optional parameter list */
va_end(arg);
/* output the message to the user program */
msg_handler(message, cinfo->client_data);
if( str_length > -1 && str_length < MSG_SIZE )
msg_handler(message, cinfo->client_data);
else return OPJ_FALSE;
}
return true;
return OPJ_TRUE;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@ Write formatted data to a string and send the string to a user callback.
@param fmt Format-control string (plus optionnal arguments)
@return Returns true if successful, returns false otherwise
*/
bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,6 @@
opj_image_t* opj_image_create0(void) {
opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t));
image->comps=NULL;
return image;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -0,0 +1,118 @@
/*
* $Id: indexbox_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#ifndef INDEXBOX_MANAGER_H_
# define INDEXBOX_MANAGER_H_
#include "openjpeg.h"
#include "j2k.h" /* needed to use jp2.h */
#include "jp2.h"
#define JPIP_CIDX 0x63696478 /* Codestream index */
#define JPIP_CPTR 0x63707472 /* Codestream Finder Box */
#define JPIP_MANF 0x6d616e66 /* Manifest Box */
#define JPIP_FAIX 0x66616978 /* Fragment array Index box */
#define JPIP_MHIX 0x6d686978 /* Main Header Index Table */
#define JPIP_TPIX 0x74706978 /* Tile-part Index Table box */
#define JPIP_THIX 0x74686978 /* Tile header Index Table box */
#define JPIP_PPIX 0x70706978 /* Precinct Packet Index Table box */
#define JPIP_PHIX 0x70686978 /* Packet Header index Table */
#define JPIP_FIDX 0x66696478 /* File Index */
#define JPIP_FPTR 0x66707472 /* File Finder */
#define JPIP_PRXY 0x70727879 /* Proxy boxes */
#define JPIP_IPTR 0x69707472 /* Index finder box */
#define JPIP_PHLD 0x70686c64 /* Place holder */
/*
* Write tile-part Index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of tpix box
*/
int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
/*
* Write tile header index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information pointer
* @param[in] cio file output handle
* @return length of thix box
*/
int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
/*
* Write precinct packet index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] EPHused true if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of ppix box
*/
int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
/*
* Write packet header index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] EPHused true if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of ppix box
*/
int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
/*
* Wriet manifest box (box)
*
* @param[in] second number to be visited
* @param[in] v number of boxes
* @param[in] box box to be manifested
* @param[in] cio file output handle
*/
void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio);
#endif /* !INDEXBOX_MANAGER_H_ */

View File

@@ -6,6 +6,7 @@
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -228,6 +229,23 @@ Read an unknown marker
@param j2k J2K handle
*/
static void j2k_read_unk(opj_j2k_t *j2k);
/**
Add main header marker information
@param cstr_info Codestream information structure
@param type marker type
@param pos byte offset of marker segment
@param len length of marker segment
*/
static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
/**
Add tile header marker information
@param tileno tile index number
@param cstr_info Codestream information structure
@param type marker type
@param pos byte offset of marker segment
@param len length of marker segment
*/
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
/*@}*/
@@ -258,80 +276,6 @@ char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
return po->str_prog;
}
void j2k_dump_image(FILE *fd, opj_image_t * img) {
int compno;
fprintf(fd, "image {\n");
fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1);
fprintf(fd, " numcomps=%d\n", img->numcomps);
for (compno = 0; compno < img->numcomps; compno++) {
opj_image_comp_t *comp = &img->comps[compno];
fprintf(fd, " comp %d {\n", compno);
fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy);
fprintf(fd, " prec=%d\n", comp->prec);
//fprintf(fd, " bpp=%d\n", comp->bpp);
fprintf(fd, " sgnd=%d\n", comp->sgnd);
fprintf(fd, " }\n");
}
fprintf(fd, "}\n");
}
void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) {
int tileno, compno, layno, bandno, resno, numbands;
fprintf(fd, "coding parameters {\n");
fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0);
fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy);
fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th);
for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
opj_tcp_t *tcp = &cp->tcps[tileno];
fprintf(fd, " tile %d {\n", tileno);
fprintf(fd, " csty=%x\n", tcp->csty);
fprintf(fd, " prg=%d\n", tcp->prg);
fprintf(fd, " numlayers=%d\n", tcp->numlayers);
fprintf(fd, " mct=%d\n", tcp->mct);
fprintf(fd, " rates=");
for (layno = 0; layno < tcp->numlayers; layno++) {
fprintf(fd, "%.1f ", tcp->rates[layno]);
}
fprintf(fd, "\n");
for (compno = 0; compno < img->numcomps; compno++) {
opj_tccp_t *tccp = &tcp->tccps[compno];
fprintf(fd, " comp %d {\n", compno);
fprintf(fd, " csty=%x\n", tccp->csty);
fprintf(fd, " numresolutions=%d\n", tccp->numresolutions);
fprintf(fd, " cblkw=%d\n", tccp->cblkw);
fprintf(fd, " cblkh=%d\n", tccp->cblkh);
fprintf(fd, " cblksty=%x\n", tccp->cblksty);
fprintf(fd, " qmfbid=%d\n", tccp->qmfbid);
fprintf(fd, " qntsty=%d\n", tccp->qntsty);
fprintf(fd, " numgbits=%d\n", tccp->numgbits);
fprintf(fd, " roishift=%d\n", tccp->roishift);
fprintf(fd, " stepsizes=");
numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
for (bandno = 0; bandno < numbands; bandno++) {
fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,
tccp->stepsizes[bandno].expn);
}
fprintf(fd, "\n");
if (tccp->csty & J2K_CCP_CSTY_PRT) {
fprintf(fd, " prcw=");
for (resno = 0; resno < tccp->numresolutions; resno++) {
fprintf(fd, "%d ", tccp->prcw[resno]);
}
fprintf(fd, "\n");
fprintf(fd, " prch=");
for (resno = 0; resno < tccp->numresolutions; resno++) {
fprintf(fd, "%d ", tccp->prch[resno]);
}
fprintf(fd, "\n");
}
fprintf(fd, " }\n");
}
fprintf(fd, " }\n");
}
fprintf(fd, "}\n");
}
/* ----------------------------------------------------------------------- */
static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
char *prog;
@@ -371,6 +315,9 @@ static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
/** mem allocation for TLM marker*/
int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
int pino,tileno,totnum_tp=0;
OPJ_ARG_NOT_USED(img_numcomp);
j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
int cur_totnum_tp = 0;
@@ -399,12 +346,14 @@ static void j2k_write_soc(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
cio_write(cio, J2K_MS_SOC, 2);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0);
/* UniPG>> */
#ifdef USE_JPWL
/* update markers struct */
j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
#endif /* USE_JPWL */
/* <<UniPG */
}
@@ -425,7 +374,7 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
opj_image_t *image = j2k->image;
opj_cp_t *cp = j2k->cp;
cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */
lenp = cio_tell(cio);
cio_skip(cio, 2);
@@ -448,6 +397,9 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lsiz */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len);
}
static void j2k_read_siz(opj_j2k_t *j2k) {
@@ -516,6 +468,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
}
#endif /* USE_JPWL */
/* prevent division by zero */
if (!(cp->tdx * cp->tdy)) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy);
return;
}
image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
for (i = 0; i < image->numcomps; i++) {
int tmp, w, h;
@@ -554,6 +512,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
}
#endif /* USE_JPWL */
/* prevent division by zero */
if (!(image->comps[i].dx * image->comps[i].dy)) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid component size (dx: %d, dy: %d)\n", image->comps[i].dx, image->comps[i].dy);
return;
}
/* TODO: unused ? */
w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
@@ -606,7 +570,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
#endif /* USE_JPWL */
cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
if (cp->tcps == NULL)
{
opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
return;
}
cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
if (cp->tileno == NULL)
{
opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
return;
}
cp->tileno_size = 0;
#ifdef USE_JPWL
@@ -678,6 +652,11 @@ static void j2k_write_com(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2);
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len);
}
}
@@ -721,12 +700,18 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */
// If user wants to remove more resolutions than the codestream contains, return error
/* If user wants to remove more resolutions than the codestream contains, return error*/
if (cp->reduce >= tccp->numresolutions) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
j2k->state |= J2K_STATE_ERR;
}
if( tccp->numresolutions > J2K_MAXRLVLS ) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
compno, tccp->numresolutions, J2K_MAXRLVLS);
j2k->state |= J2K_STATE_ERR;
tccp->numresolutions = J2K_MAXRLVLS;
}
tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */
tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */
@@ -781,6 +766,10 @@ static void j2k_write_cod(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lcod */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len);
}
static void j2k_read_cod(opj_j2k_t *j2k) {
@@ -846,6 +835,12 @@ static void j2k_read_coc(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Lcoc */
compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */
if (compno >= image->numcomps) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in COC (%d out of a maximum of %d)\n",
compno, image->numcomps);
return;
}
tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */
j2k_read_cox(j2k, compno);
}
@@ -909,6 +904,15 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
};
};
#else
/* We check whether there are too many subbands */
if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
opj_event_msg(j2k->cinfo, EVT_WARNING ,
"bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
"- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
}
#endif /* USE_JPWL */
for (bandno = 0; bandno < numbands; bandno++) {
@@ -921,8 +925,10 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
expn = tmp >> 11;
mant = tmp & 0x7ff;
}
tccp->stepsizes[bandno].expn = expn;
tccp->stepsizes[bandno].mant = mant;
if (bandno < J2K_MAXBANDS){
tccp->stepsizes[bandno].expn = expn;
tccp->stepsizes[bandno].mant = mant;
}
}
/* Add Antonin : if scalar_derived -> compute other stepsizes */
@@ -950,6 +956,9 @@ static void j2k_write_qcd(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lqcd */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len);
}
static void j2k_read_qcd(opj_j2k_t *j2k) {
@@ -986,7 +995,7 @@ static void j2k_read_qcc(opj_j2k_t *j2k) {
int len, compno;
int numcomp = j2k->image->numcomps;
opj_cio_t *cio = j2k->cio;
len = cio_read(cio, 2); /* Lqcc */
compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
@@ -1013,9 +1022,16 @@ static void j2k_read_qcc(opj_j2k_t *j2k) {
/* keep your private count of tiles */
backup_compno++;
};
}
#endif /* USE_JPWL */
if ((compno < 0) || (compno >= numcomp)) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in QCC (%d out of a maximum of %d)\n",
compno, j2k->image->numcomps);
return;
}
j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
}
@@ -1271,6 +1287,10 @@ static void j2k_write_sot(opj_j2k_t *j2k) {
j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2);
#endif /* USE_JPWL */
/* <<UniPG */
if( j2k->cstr_info && j2k->cur_tp_num==0){
j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len);
}
}
static void j2k_read_sot(opj_j2k_t *j2k) {
@@ -1354,6 +1374,11 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
partno = cio_read(cio, 1);
numparts = cio_read(cio, 1);
if (partno >= numparts) {
opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts);
numparts = partno+1;
}
j2k->curtileno = tileno;
j2k->cur_tp_num = partno;
@@ -1369,15 +1394,14 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
j2k->cstr_info->tile[tileno].tileno = tileno;
j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12;
j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
j2k->cstr_info->tile[tileno].num_tps = numparts;
if (numparts)
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
else
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
}
else {
} else {
j2k->cstr_info->tile[tileno].end_pos += totlen;
}
}
j2k->cstr_info->tile[tileno].num_tps = numparts;
if (numparts)
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t));
else
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/
j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12;
j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
@@ -1413,6 +1437,11 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) {
tcd->cur_tp_num = j2k->cur_tp_num;
cio_write(cio, J2K_MS_SOD, 2);
if( j2k->cstr_info && j2k->cur_tp_num==0){
j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0);
}
if (j2k->curtileno == 0) {
j2k->sod_start = cio_tell(cio) + j2k->pos_correction;
}
@@ -1489,6 +1518,24 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
truncate = 1; /* Case of a truncate codestream */
}
{/* chop padding bytes: */
unsigned char *s, *e;
s = cio_getbp(cio);
e = s + len;
if(len > 8) s = e - 8;
if(e[-2] == 0x00 && e[-1] == 0x00) /* padding bytes */
{
while(e > s)
{
if(e[-2] == 0xff && e[-1] == 0xd9) break;
--len; --e; truncate = 1;
}
}
}
data = j2k->tile_data[curtileno];
data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
@@ -1548,6 +1595,13 @@ static void j2k_read_rgn(opj_j2k_t *j2k) {
};
#endif /* USE_JPWL */
if (compno >= numcomps) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in RGN (%d out of a maximum of %d)\n",
compno, j2k->image->numcomps);
return;
}
tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */
}
@@ -1566,7 +1620,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) {
static void j2k_read_eoc(opj_j2k_t *j2k) {
int i, tileno;
bool success;
opj_bool success = OPJ_FALSE;
/* if packets should be decoded */
if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
@@ -1574,12 +1628,17 @@ static void j2k_read_eoc(opj_j2k_t *j2k) {
tcd_malloc_decode(tcd, j2k->image, j2k->cp);
for (i = 0; i < j2k->cp->tileno_size; i++) {
tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
tileno = j2k->cp->tileno[i];
success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
tcd_free_decode_tile(tcd, i);
if (success == false) {
if (j2k->cp->tileno[i] != -1)
{
tileno = j2k->cp->tileno[i];
success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
tcd_free_decode_tile(tcd, i);
}
else
success = OPJ_FALSE;
if (success == OPJ_FALSE) {
j2k->state |= J2K_STATE_ERR;
break;
}
@@ -1749,6 +1808,14 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) {
opj_free(j2k->tile_len);
}
if(j2k->tile_data != NULL) {
if(j2k->cp != NULL) {
for (i = 0; i < j2k->cp->tileno_size; i++) {
int tileno = j2k->cp->tileno[i];
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
}
}
opj_free(j2k->tile_data);
}
if(j2k->default_tcp != NULL) {
@@ -1834,7 +1901,7 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
if (j2k->cp->correct) {
int orig_pos = cio_tell(cio);
bool status;
opj_bool status;
/* call the corrector */
status = jpwl_correct(j2k);
@@ -1868,18 +1935,24 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
#endif /* USE_JPWL */
if (id >> 8 != 0xff) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
}
e = j2k_dec_mstab_lookup(id);
// Check if the marker is known
/* Check if the marker is known*/
if (!(j2k->state & e->states)) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
return 0;
}
// Check if the decoding is limited to the main header
/* Check if the decoding is limited to the main header*/
if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) {
opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n");
return image;
@@ -1889,7 +1962,10 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
(*e->handler)(j2k);
}
if (j2k->state & J2K_STATE_ERR)
{
opj_image_destroy(image);
return NULL;
}
if (j2k->state == J2K_STATE_MT) {
break;
@@ -1905,7 +1981,6 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
if (j2k->state != J2K_STATE_MT) {
opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
}
return image;
}
@@ -1917,9 +1992,10 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
opj_image_t *image = NULL;
opj_jpt_msg_header_t header;
int position;
opj_common_ptr cinfo = j2k->cinfo;
OPJ_ARG_NOT_USED(cstr_info);
j2k->cio = cio;
/* create an empty image */
@@ -1961,9 +2037,15 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
id = cio_read(cio, 2);
if (id >> 8 != 0xff) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
}
e = j2k_dec_mstab_lookup(id);
if (!(j2k->state & e->states)) {
@@ -2110,12 +2192,12 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
int i;
/* set JPWL on */
cp->epc_on = true;
cp->info_on = false; /* no informative technique */
cp->epc_on = OPJ_TRUE;
cp->info_on = OPJ_FALSE; /* no informative technique */
/* set EPB on */
if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
cp->epb_on = true;
cp->epb_on = OPJ_TRUE;
cp->hprot_MH = parameters->jpwl_hprot_MH;
for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
@@ -2136,7 +2218,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
/* set ESD writing */
if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
cp->esd_on = true;
cp->esd_on = OPJ_TRUE;
cp->sens_size = parameters->jpwl_sens_size;
cp->sens_addr = parameters->jpwl_sens_addr;
@@ -2150,10 +2232,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
/* always set RED writing to false: we are at the encoder */
cp->red_on = false;
cp->red_on = OPJ_FALSE;
} else {
cp->epc_on = false;
cp->epc_on = OPJ_FALSE;
}
#endif /* USE_JPWL */
@@ -2226,10 +2308,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
if(parameters->cp_cinema)
{
//Precinct size for lowest frequency subband=128
/*Precinct size for lowest frequency subband=128*/
tccp->prcw[0] = 7;
tccp->prch[0] = 7;
//Precinct size at all other resolutions = 256
/*Precinct size at all other resolutions = 256*/
for (j = 1; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 8;
tccp->prch[j] = 8;
@@ -2271,7 +2353,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
p++;
/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
} //end for
} /*end for*/
} else {
for (j = 0; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 15;
@@ -2285,7 +2367,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
}
bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
int tileno, compno;
opj_cp_t *cp = NULL;
@@ -2296,8 +2378,6 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
cp = j2k->cp;
/* j2k_dump_cp(stdout, image, cp); */
/* INDEX >> */
j2k->cstr_info = cstr_info;
if (cstr_info) {
@@ -2394,6 +2474,9 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
/* INDEX >> */
if(cstr_info) {
cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
cstr_info->tile[j2k->curtileno].maxmarknum = 10;
cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t));
cstr_info->tile[j2k->curtileno].marknum = 0;
}
/* << INDEX */
@@ -2500,11 +2583,46 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
}
#endif /* USE_JPWL */
return true;
return OPJ_TRUE;
}
static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
if (!cstr_info)
return;
/* expand the list? */
if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
}
/* add the marker */
cstr_info->marker[cstr_info->marknum].type = type;
cstr_info->marker[cstr_info->marknum].pos = pos;
cstr_info->marker[cstr_info->marknum].len = len;
cstr_info->marknum++;
}
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
opj_marker_info_t *marker;
if (!cstr_info)
return;
/* expand the list? */
if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) {
cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F);
cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum);
}
marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]);
/* add the marker */
marker->type = type;
marker->pos = pos;
marker->len = len;
cstr_info->tile[tileno].marknum++;
}

View File

@@ -265,15 +265,15 @@ typedef struct opj_cp {
/* UniPG>> */
#ifdef USE_JPWL
/** enables writing of EPC in MH, thus activating JPWL */
bool epc_on;
opj_bool epc_on;
/** enables writing of EPB, in case of activated JPWL */
bool epb_on;
opj_bool epb_on;
/** enables writing of ESD, in case of activated JPWL */
bool esd_on;
opj_bool esd_on;
/** enables writing of informative techniques of ESD, in case of activated JPWL */
bool info_on;
opj_bool info_on;
/** enables writing of RED, in case of activated JPWL */
bool red_on;
opj_bool red_on;
/** error protection method for MH (0,1,16,32,37-128) */
int hprot_MH;
/** tile number of header protection specification (>=0) */
@@ -299,7 +299,7 @@ typedef struct opj_cp {
/** sensitivity methods for TPHs (-1,0-7) */
int sens_TPH[JPWL_MAX_NO_TILESPECS];
/** enables JPWL correction at the decoder */
bool correct;
opj_bool correct;
/** expected number of components at the decoder */
int exp_comps;
/** maximum number of tiles at the decoder */
@@ -436,10 +436,8 @@ Encode an image into a JPEG-2000 codestream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
void j2k_dump_image(FILE *fd, opj_image_t * img);
void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,18 +24,18 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include "opj_includes.h"
double opj_clock(void) {
#ifdef WIN32
/* WIN32: use QueryPerformance (very accurate) */
#ifdef _WIN32
/* _WIN32: use QueryPerformance (very accurate) */
LARGE_INTEGER freq , t ;
/* freq is the clock speed of the CPU */
QueryPerformanceFrequency(&freq) ;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

File diff suppressed because it is too large Load Diff

View File

@@ -46,11 +46,64 @@
#define JP2_COLR 0x636f6c72 /**< Colour specification box */
#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */
#define JP2_URL 0x75726c20 /**< URL box */
#define JP2_DBTL 0x6474626c /**< ??? */
#define JP2_DTBL 0x6474626c /**< Data Reference box */
#define JP2_BPCC 0x62706363 /**< Bits per component box */
#define JP2_JP2 0x6a703220 /**< File type fields */
#define JP2_PCLR 0x70636c72 /**< Palette box */
#define JP2_CMAP 0x636d6170 /**< Component Mapping box */
#define JP2_CDEF 0x63646566 /**< Channel Definition box */
/* ----------------------------------------------------------------------- */
/**
Channel description: channel index, type, assocation
*/
typedef struct opj_jp2_cdef_info
{
unsigned short cn, typ, asoc;
} opj_jp2_cdef_info_t;
/**
Channel descriptions and number of descriptions
*/
typedef struct opj_jp2_cdef
{
opj_jp2_cdef_info_t *info;
unsigned short n;
} opj_jp2_cdef_t;
/**
Component mappings: channel index, mapping type, palette index
*/
typedef struct opj_jp2_cmap_comp
{
unsigned short cmp;
unsigned char mtyp, pcol;
} opj_jp2_cmap_comp_t;
/**
Palette data: table entries, palette columns
*/
typedef struct opj_jp2_pclr
{
unsigned int *entries;
unsigned char *channel_sign;
unsigned char *channel_size;
opj_jp2_cmap_comp_t *cmap;
unsigned short nr_entries, nr_channels;
} opj_jp2_pclr_t;
/**
Collector for ICC profile, palette, component mapping, channel description
*/
typedef struct opj_jp2_color
{
unsigned char *icc_profile_buf;
int icc_profile_len;
opj_jp2_cdef_t *jp2_cdef;
opj_jp2_pclr_t *jp2_pclr;
unsigned char jp2_has_colr;
} opj_jp2_color_t;
/**
JP2 component
@@ -87,6 +140,8 @@ typedef struct opj_jp2 {
opj_jp2_comps_t *comps;
unsigned int j2k_codestream_offset;
unsigned int j2k_codestream_length;
opj_bool jpip_on;
opj_bool ignore_pclr_cmap_cdef;
} opj_jp2_t;
/**
@@ -111,9 +166,10 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
Read the JP2H box - JP2 Header box (used in MJ2)
@param jp2 JP2 handle
@param cio Input buffer stream
@param ext Collector for profile, cdef and pclr data
@return Returns true if successful, returns false otherwise
*/
bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color);
/**
Creates a JP2 decompression structure
@param cinfo Codec context info
@@ -139,7 +195,7 @@ Decode an image from a JPEG-2000 file stream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns a decoded image if successful, returns NULL otherwise
*/
opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
/**
Creates a JP2 compression structure
@param cinfo Codec context info
@@ -167,7 +223,8 @@ Encode an image into a JPEG-2000 file stream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -521,22 +521,21 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
unsigned int c;
unsigned int *ip;
unsigned char *end = mqc->end - 1;
mqc->buffer = opj_realloc(mqc->buffer, (2 * len + 1) * sizeof(unsigned int));
mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int));
ip = (unsigned int *) mqc->buffer;
while (bp != end) {
while (bp < end) {
c = *(bp + 1);
if (*bp == 0xff) {
if (c > 0x8f) {
*ip = 0x0000ff18;
break;
} else {
bp++;
*ip = 0x00000017 | (c << 9);
}
} else {
bp++;
*ip = 0x00000018 | (c << 8);
}
bp++;
ip++;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,17 +24,22 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include "opj_config.h"
#include "opj_includes.h"
/* ---------------------------------------------------------------------- */
#ifdef WIN32
#ifdef _WIN32
#ifndef OPJ_STATIC
BOOL APIENTRY
DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
OPJ_ARG_NOT_USED(lpReserved);
OPJ_ARG_NOT_USED(hModule);
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH :
break;
@@ -48,19 +53,19 @@ DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}
#endif /* OPJ_STATIC */
#endif /* WIN32 */
#endif /* _WIN32 */
/* ---------------------------------------------------------------------- */
const char* OPJ_CALLCONV opj_version(void) {
return OPENJPEG_VERSION;
return PACKAGE_VERSION;
}
opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) {
opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_calloc(1, sizeof(opj_dinfo_t));
if(!dinfo) return NULL;
dinfo->is_decompressor = true;
dinfo->is_decompressor = OPJ_TRUE;
switch(format) {
case CODEC_J2K:
case CODEC_JPT:
@@ -120,9 +125,10 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete
parameters->decod_format = -1;
parameters->cod_format = -1;
parameters->flags = 0;
/* UniPG>> */
#ifdef USE_JPWL
parameters->jpwl_correct = false;
parameters->jpwl_correct = OPJ_FALSE;
parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS;
parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES;
#endif /* USE_JPWL */
@@ -159,7 +165,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci
case CODEC_JPT:
return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info);
case CODEC_JP2:
return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info);
return opj_jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info);
case CODEC_UNKNOWN:
default:
break;
@@ -171,7 +177,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci
opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) {
opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_calloc(1, sizeof(opj_cinfo_t));
if(!cinfo) return NULL;
cinfo->is_decompressor = false;
cinfo->is_decompressor = OPJ_FALSE;
switch(format) {
case CODEC_J2K:
/* get a J2K coder handle */
@@ -243,10 +249,10 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete
parameters->cp_disto_alloc = 0;
parameters->cp_fixed_alloc = 0;
parameters->cp_fixed_quality = 0;
parameters->jpip_on = OPJ_FALSE;
/* UniPG>> */
#ifdef USE_JPWL
parameters->jpwl_epc_on = false;
parameters->jpwl_epc_on = OPJ_FALSE;
parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */
{
int i;
@@ -296,7 +302,7 @@ void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *param
}
}
bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
if (index != NULL)
opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n"
"To extract the index, use the opj_encode_with_info() function.\n"
@@ -304,20 +310,20 @@ bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *im
return opj_encode_with_info(cinfo, cio, image, NULL);
}
bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
if(cinfo && cio && image) {
switch(cinfo->codec_format) {
case CODEC_J2K:
return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info);
case CODEC_JP2:
return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info);
return opj_jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info);
case CODEC_JPT:
case CODEC_UNKNOWN:
default:
break;
}
}
return false;
return OPJ_FALSE;
}
void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
@@ -328,6 +334,7 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
opj_free(tile_info->thresh);
opj_free(tile_info->packet);
opj_free(tile_info->tp);
opj_free(tile_info->marker);
}
opj_free(cstr_info->tile);
opj_free(cstr_info->marker);

View File

@@ -6,6 +6,7 @@
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +33,6 @@
#ifndef OPENJPEG_H
#define OPENJPEG_H
#define OPENJPEG_VERSION "1.4.0.635"
/*
==========================================================
@@ -40,7 +40,7 @@
==========================================================
*/
#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__))
#if defined(OPJ_STATIC) || !defined(_WIN32)
#define OPJ_API
#define OPJ_CALLCONV
#else
@@ -53,38 +53,19 @@ that uses this DLL. This way any other project whose source files include this f
OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
defined with this macro as being exported.
*/
#ifdef OPJ_EXPORTS
#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
#define OPJ_API __declspec(dllexport)
#else
#define OPJ_API __declspec(dllimport)
#endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !WIN32 */
#endif /* !OPJ_STATIC || !_WIN32 */
#ifndef __cplusplus
#if defined(HAVE_STDBOOL_H)
/*
The C language implementation does correctly provide the standard header
file "stdbool.h".
*/
#include <stdbool.h>
#else
/*
The C language implementation does not provide the standard header file
"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this
braindamage below.
*/
#if !defined(bool)
#define bool int
#endif
#if !defined(true)
#define true 1
#endif
#if !defined(false)
#define false 0
#endif
#endif
#endif /* __cplusplus */
typedef int opj_bool;
#define OPJ_TRUE 1
#define OPJ_FALSE 0
/* Avoid compile-time warning because parameter is not used */
#define OPJ_ARG_NOT_USED(x) (void)(x)
/*
==========================================================
Useful constant definitions
@@ -154,14 +135,18 @@ typedef enum COLOR_SPACE {
CLRSPC_SYCC = 3 /**< YUV */
} OPJ_COLOR_SPACE;
#define ENUMCS_SRGB 16
#define ENUMCS_GRAY 17
#define ENUMCS_SYCC 18
/**
Supported codec
*/
typedef enum CODEC_FORMAT {
CODEC_UNKNOWN = -1, /**< place-holder */
CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */
CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */
CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */
CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */
CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */
CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */
} OPJ_CODEC_FORMAT;
/**
@@ -244,7 +229,7 @@ Compression parameters
*/
typedef struct opj_cparameters {
/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
bool tile_size_on;
opj_bool tile_size_on;
/** XTOsiz */
int cp_tx0;
/** YTOsiz */
@@ -326,7 +311,7 @@ typedef struct opj_cparameters {
/**@name JPWL encoding parameters */
/*@{*/
/** enables writing of EPC in MH, thus activating JPWL */
bool jpwl_epc_on;
opj_bool jpwl_epc_on;
/** error protection method for MH (0,1,16,32,37-128) */
int jpwl_hprot_MH;
/** tile number of header protection specification (>=0) */
@@ -366,8 +351,12 @@ typedef struct opj_cparameters {
char tp_flag;
/** MCT (multiple component transform) */
char tcp_mct;
/** Enable JPIP indexing*/
opj_bool jpip_on;
} opj_cparameters_t;
#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG 0x0001
/**
Decompression parameters
*/
@@ -404,7 +393,7 @@ typedef struct opj_dparameters {
/**@name JPWL decoding parameters */
/*@{*/
/** activates the JPWL correction capabilities */
bool jpwl_correct;
opj_bool jpwl_correct;
/** expected number of components */
int jpwl_exp_comps;
/** maximum number of tiles */
@@ -420,6 +409,7 @@ typedef struct opj_dparameters {
*/
OPJ_LIMIT_DECODING cp_limit_decoding;
unsigned int flags;
} opj_dparameters_t;
/** Common fields between JPEG-2000 compression and decompression master structs. */
@@ -427,7 +417,7 @@ typedef struct opj_dparameters {
#define opj_common_fields \
opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\
void * client_data; /**< Available for use by application */\
bool is_decompressor; /**< So common code can tell which is which */\
opj_bool is_decompressor; /**< So common code can tell which is which */\
OPJ_CODEC_FORMAT codec_format; /**< selected codec */\
void *j2k_handle; /**< pointer to the J2K codec */\
void *jp2_handle; /**< pointer to the JP2 codec */\
@@ -555,6 +545,10 @@ typedef struct opj_image {
OPJ_COLOR_SPACE color_space;
/** image components */
opj_image_comp_t *comps;
/** 'restricted' ICC profile */
unsigned char *icc_profile_buf;
/** size of ICC profile */
int icc_profile_len;
} opj_image_t;
/**
@@ -601,6 +595,21 @@ typedef struct opj_packet_info {
double disto;
} opj_packet_info_t;
/* UniPG>> */
/**
Marker structure
*/
typedef struct opj_marker_info_t {
/** marker type */
unsigned short int type;
/** position in codestream */
int pos;
/** length, marker val included */
int len;
} opj_marker_info_t;
/* <<UniPG */
/**
Index structure : Information concerning tile-parts
*/
@@ -645,26 +654,18 @@ typedef struct opj_tile_info {
int numpix;
/** add fixed_quality */
double distotile;
/** number of markers */
int marknum;
/** list of markers */
opj_marker_info_t *marker;
/** actual size of markers array */
int maxmarknum;
/** number of tile parts */
int num_tps;
/** information concerning tile parts */
opj_tp_info_t *tp;
} opj_tile_info_t;
/* UniPG>> */
/**
Marker structure
*/
typedef struct opj_marker_info_t {
/** marker type */
unsigned short int type;
/** position in codestream */
int pos;
/** length, marker val included */
int len;
} opj_marker_info_t;
/* <<UniPG */
/**
Index structure of the codestream
*/
@@ -883,13 +884,13 @@ Setup the encoder parameters using the current image and using user parameters.
OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image);
/**
Encode an image into a JPEG-2000 codestream
@param cinfo compressor handle
3@param cinfo compressor handle
@param cio Output buffer stream
@param image Image to encode
@param index Depreacted -> Set to NULL. To extract index, used opj_encode_wci()
@return Returns true if successful, returns false otherwise
*/
OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index);
OPJ_API opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index);
/**
Encode an image into a JPEG-2000 codestream and extract the codestream information
@param cinfo compressor handle
@@ -898,13 +899,14 @@ Encode an image into a JPEG-2000 codestream and extract the codestream informati
@param cstr_info Codestream information structure if needed afterwards, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
OPJ_API bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
OPJ_API opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/**
Destroy Codestream information after compression or decompression
@param cstr_info Codestream information structure
*/
OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,36 @@
/* create config.h for CMake */
#define PACKAGE_VERSION "1.5.2"
#define HAVE_INTTYPES_H
#define HAVE_MEMORY_H
#define HAVE_STDINT_H
#define HAVE_STDLIB_H
#define HAVE_STRINGS_H
#define HAVE_STRING_H
#define HAVE_SYS_STAT_H
#define HAVE_SYS_TYPES_H
#define HAVE_UNISTD_H
/* #define HAVE_LIBPNG */
/* #define HAVE_PNG_H */
/* #define HAVE_LIBTIFF */
/* #define HAVE_TIFF_H */
/* #undef HAVE_LIBLCMS1 */
/* #undef HAVE_LIBLCMS2 */
/* #undef HAVE_LCMS1_H */
/* #undef HAVE_LCMS2_H */
/* Byte order. */
/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or
* __LITTLE_ENDIAN__ to match the endianness of the architecture being
* compiled for. This is not necessarily the same as the architecture of the
* machine doing the building. In order to support Universal Binaries on
* Mac OS X, we prefer those defines to decide the endianness.
* On other platforms we use the result of the TRY_RUN. */
#if !defined(__APPLE__)
/* #undef OPJ_BIG_ENDIAN */
#elif defined(__BIG_ENDIAN__)
# define OPJ_BIG_ENDIAN
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -89,20 +89,25 @@ Most compilers implement their own version of this keyword ...
/* MSVC and Borland C do not have lrintf */
#if defined(_MSC_VER) || defined(__BORLANDC__)
static INLINE long lrintf(float f){
int i;
_asm{
fld f
fistp i
};
return i;
#ifdef _M_X64
return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
#else
int i;
_asm{
fld f
fistp i
};
return i;
#endif
}
#endif
#include "j2k_lib.h"
#include "opj_malloc.h"
#include "event.h"
#include "bio.h"
#include "cio.h"
#include "image.h"
@@ -123,9 +128,12 @@ static INLINE long lrintf(float f){
#include "int.h"
#include "fix.h"
#include "cidx_manager.h"
#include "indexbox_manager.h"
/* JPWL>> */
#ifdef USE_JPWL
#include "../jpwl/jpwl.h"
#include "./jpwl/jpwl.h"
#endif /* USE_JPWL */
/* <<JPWL */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
* All rights reserved.
*
@@ -69,7 +69,7 @@ Allocate memory aligned to a 16 byte boundry
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
#ifdef WIN32
#ifdef _WIN32
/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
#ifdef __GNUC__
#include <mm_malloc.h>
@@ -80,11 +80,13 @@ Allocate memory aligned to a 16 byte boundry
#define HAVE_MM_MALLOC
#endif
#endif
#else /* Not WIN32 */
#else /* Not _WIN32 */
#if defined(__sun)
#define HAVE_MEMALIGN
#elif defined(__FreeBSD__)
#define HAVE_POSIX_MEMALIGN
/* Linux x86_64 and OSX always align allocations to 16 bytes */
#elif !defined(__amd64__) && !defined(__APPLE__)
#elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
#define HAVE_MEMALIGN
#include <malloc.h>
#endif
@@ -130,22 +132,22 @@ Allocate memory aligned to a 16 byte boundry
/**
Reallocate memory blocks.
@param memblock Pointer to previously allocated memory block
@param size New size in bytes
@param m Pointer to previously allocated memory block
@param s New size in bytes
@return Returns a void pointer to the reallocated (and possibly moved) memory block
*/
#ifdef ALLOC_PERF_OPT
void * OPJ_CALLCONV opj_realloc(void * _Memory, size_t NewSize);
void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
#else
#define opj_realloc(m, s) realloc(m, s)
#endif
/**
Deallocates or frees a memory block.
@param memblock Previously allocated memory block to be freed
@param m Previously allocated memory block to be freed
*/
#ifdef ALLOC_PERF_OPT
void OPJ_CALLCONV opj_free(void * _Memory);
void OPJ_CALLCONV opj_free(void * m);
#else
#define opj_free(m) free(m)
#endif

View File

@@ -0,0 +1,170 @@
/*
* $Id: phix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdlib.h>
#include <math.h>
#include "opj_includes.h"
/*
* Write faix box of phix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] EPHused true if if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp=0, compno, i;
opj_jp2_box_t *box;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
for( i=0;i<2;i++){
if (i) cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_PHIX, 4); /* PHIX */
write_manf( i, cstr_info.numcomps, box, cio);
for( compno=0; compno<cstr_info.numcomps; compno++){
box[compno].length = write_phixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
box[compno].type = JPIP_FAIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8 */
opj_tile_info_t *tile_Idx;
opj_packet_info_t packet;
int resno, precno, layno, num_packet;
int numOfres, numOfprec, numOflayers;
packet.end_ph_pos = packet.start_pos = -1;
(void)EPHused; /* unused ? */
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = 1;
}
else{
size_of_coding = 4;
version = 0;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version,1); /* Version 0 = 4 bytes */
nmax = 0;
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
tile_Idx = &cstr_info.tile[ tileno];
num_packet = 0;
numOfres = cstr_info.numdecompos[compno] + 1;
for( resno=0; resno<numOfres ; resno++){
numOfprec = tile_Idx->pw[resno]*tile_Idx->ph[resno];
for( precno=0; precno<numOfprec; precno++){
numOflayers = cstr_info.numlayers;
for( layno=0; layno<numOflayers; layno++){
switch ( cstr_info.prog){
case LRCP:
packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RLCP:
packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RPCL:
packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
break;
case PCRL:
packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
break;
case CPRL:
packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
break;
default:
fprintf( stderr, "failed to ppix indexing\n");
}
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */
num_packet++;
}
}
}
/* PADDING */
while( num_packet < nmax){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -43,31 +43,31 @@ Get next packet in layer-resolution-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_lrcp(opj_pi_iterator_t * pi);
static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-layer-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_rlcp(opj_pi_iterator_t * pi);
static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-precinct-component-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_rpcl(opj_pi_iterator_t * pi);
static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi);
/**
Get next packet in precinct-component-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_pcrl(opj_pi_iterator_t * pi);
static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi);
/**
Get next packet in component-precinct-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_cprl(opj_pi_iterator_t * pi);
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi);
/*@}*/
@@ -79,7 +79,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi);
==========================================================
*/
static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -108,7 +108,7 @@ static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -116,10 +116,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -147,7 +147,7 @@ static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -155,10 +155,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -229,7 +229,7 @@ if (!pi->tp_on){
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -238,10 +238,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -310,7 +310,7 @@ static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -319,10 +319,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_cprl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -389,7 +389,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -398,7 +398,7 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
/*
@@ -707,7 +707,7 @@ void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
}
}
bool pi_next(opj_pi_iterator_t * pi) {
opj_bool pi_next(opj_pi_iterator_t * pi) {
switch (pi->poc.prg) {
case LRCP:
return pi_next_lrcp(pi);
@@ -720,13 +720,13 @@ bool pi_next(opj_pi_iterator_t * pi) {
case CPRL:
return pi_next_cprl(pi);
case PROG_UNKNOWN:
return false;
return OPJ_FALSE;
}
return false;
return OPJ_FALSE;
}
bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){
opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){
char prog[4];
int i;
int incr_top=1,resetX=0;
@@ -748,7 +748,7 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,
case RPCL: strncpy(prog, "RPCL",4);
break;
case PROG_UNKNOWN:
return true;
return OPJ_TRUE;
}
if(!(cp->tp_on && ((!cp->cinema && (t2_mode == FINAL_PASS)) || cp->cinema))){
@@ -958,6 +958,6 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,
}
}
}
return false;
return OPJ_FALSE;
}

View File

@@ -115,12 +115,14 @@ Modify the packet iterator for enabling tile part generation
@param pi Handle to the packet iterator generated in pi_initialise_encode
@param cp Coding parameters
@param tileno Number that identifies the tile for which to list the packets
@param pino Iterator index for pi
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
@param cur_totnum_tp The total number of tile parts in the current tile
@return Returns true if an error is detected
*/
bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
opj_bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
/**
Create a packet iterator for Decoder
@param image Raw image for which the packets will be listed
@@ -145,7 +147,7 @@ Modify the packet iterator to point to the next packet
@param pi Packet iterator to modify
@return Returns false if pi pointed to the last packet or else returns true
*/
bool pi_next(opj_pi_iterator_t * pi);
opj_bool pi_next(opj_pi_iterator_t * pi);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -0,0 +1,173 @@
/*
* $Id: ppix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "opj_includes.h"
/*
* Write faix box of ppix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] EPHused true if if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, compno, i;
opj_jp2_box_t *box;
/* printf("cstr_info.packno %d\n", cstr_info.packno); //NMAX? */
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
for (i=0;i<2;i++){
if (i) cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_PPIX, 4); /* PPIX */
write_manf( i, cstr_info.numcomps, box, cio);
for (compno=0; compno<cstr_info.numcomps; compno++){
box[compno].length = write_ppixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
box[compno].type = JPIP_FAIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8*/
opj_tile_info_t *tile_Idx;
opj_packet_info_t packet;
int resno, precno, layno, num_packet;
int numOfres, numOfprec, numOflayers;
packet.end_pos = packet.end_ph_pos = packet.start_pos = -1;
(void)EPHused; /* unused ? */
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = 1;
}
else{
size_of_coding = 4;
version = 0;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
nmax = 0;
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
tile_Idx = &cstr_info.tile[ tileno];
num_packet=0;
numOfres = cstr_info.numdecompos[compno] + 1;
for( resno=0; resno<numOfres ; resno++){
numOfprec = tile_Idx->pw[resno]*tile_Idx->ph[resno];
for( precno=0; precno<numOfprec; precno++){
numOflayers = cstr_info.numlayers;
for( layno=0; layno<numOflayers; layno++){
switch ( cstr_info.prog){
case LRCP:
packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RLCP:
packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RPCL:
packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
break;
case PCRL:
packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
break;
case CPRL:
packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
break;
default:
fprintf( stderr, "failed to ppix indexing\n");
}
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */
num_packet++;
}
}
}
while( num_packet < nmax){ /* PADDING */
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -123,20 +123,20 @@ static void t1_enc_refpass_step(
/**
Decode refinement pass
*/
static void INLINE t1_dec_refpass_step_raw(
static INLINE void t1_dec_refpass_step_raw(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
int poshalf,
int neghalf,
int vsc);
static void INLINE t1_dec_refpass_step_mqc(
static INLINE void t1_dec_refpass_step_mqc(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
int poshalf,
int neghalf);
static void INLINE t1_dec_refpass_step_mqc_vsc(
static INLINE void t1_dec_refpass_step_mqc_vsc(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
@@ -240,6 +240,7 @@ Encode 1 code-block
@param stepsize
@param cblksty Code-block style
@param numcomps
@param mct
@param tile
*/
static void t1_encode_cblk(
@@ -381,9 +382,10 @@ static INLINE void t1_dec_sigpass_step_raw(
int vsc)
{
int v, flag;
opj_raw_t *raw = t1->raw; /* RAW component */
OPJ_ARG_NOT_USED(orient);
flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
if (raw_decode(raw)) {
@@ -822,9 +824,10 @@ static void t1_dec_clnpass_step_partial(
int oneplushalf)
{
int v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
OPJ_ARG_NOT_USED(orient);
flag = *flagsp;
mqc_setcurctx(mqc, t1_getctxno_sc(flag));
v = mqc_decode(mqc) ^ t1_getspb(flag);
@@ -1088,34 +1091,21 @@ static double t1_getwmsedec(
int numcomps,
int mct)
{
double w1 = 1, w2, wmsedec;
// Prevent running an MCT on more than 3 components. NB openjpeg v2.0 will support this via
// custom MCT tables that can be passed as encode parameters, 1.3 cannot support this as it
// uses a static table of 3 entries and there for can only cope with 3 components with out an
// array overflow
if(numcomps==3) {
if (qmfbid == 1) {
w1 = (numcomps > 1) ? mct_getnorm(compno) : 1.0;
} else {
w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1.0;
}
}
double w1, w2, wmsedec;
if (qmfbid == 1) {
w1 = (mct && numcomps==3) ? mct_getnorm(compno) : 1.0;
w2 = dwt_getnorm(level, orient);
} else { /* if (qmfbid == 0) */
w1 = (mct && numcomps==3) ? mct_getnorm_real(compno) : 1.0;
w2 = dwt_getnorm_real(level, orient);
}
wmsedec = w1 * w2 * stepsize * (1 << bpno);
wmsedec *= wmsedec * nmsedec / 8192.0;
return wmsedec;
}
static bool allocate_buffers(
static opj_bool allocate_buffers(
opj_t1_t *t1,
int w,
int h)
@@ -1127,7 +1117,7 @@ static bool allocate_buffers(
opj_aligned_free(t1->data);
t1->data = (int*) opj_aligned_malloc(datasize * sizeof(int));
if(!t1->data){
return false;
return OPJ_FALSE;
}
t1->datasize=datasize;
}
@@ -1140,7 +1130,7 @@ static bool allocate_buffers(
opj_aligned_free(t1->flags);
t1->flags = (flag_t*) opj_aligned_malloc(flagssize * sizeof(flag_t));
if(!t1->flags){
return false;
return OPJ_FALSE;
}
t1->flagssize=flagssize;
}
@@ -1149,7 +1139,7 @@ static bool allocate_buffers(
t1->w=w;
t1->h=h;
return true;
return OPJ_TRUE;
}
/** mod fixed_quality */
@@ -1425,6 +1415,7 @@ void t1_encode_cblks(
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_band_t* restrict band = &res->bands[bandno];
int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192));
for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_t *prc = &band->precincts[precno];
@@ -1475,7 +1466,7 @@ void t1_encode_cblks(
datap[(j * cblk_w) + i] =
fix_mul(
tmp,
8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (11 - T1_NMSEDEC_FRACBITS);
bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
}
}
}
@@ -1586,6 +1577,7 @@ void t1_decode_cblks(
opj_free(cblk->segs);
} /* cblkno */
opj_free(precinct->cblks.dec);
precinct->cblks.dec = NULL;
} /* precno */
} /* bandno */
} /* resno */

View File

@@ -135,8 +135,8 @@ void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
/**
Decode the code-blocks of a tile
@param t1 T1 handle
@param tile The tile to decode
@param tcp Tile coding parameters
@param tilec The tile to decode
@param tccp Tile coding parameters
*/
void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp);
/* ----------------------------------------------------------------------- */

View File

@@ -59,11 +59,12 @@ Encode a packet of a tile to a destination buffer
*/
static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno);
/**
@param seg
@param cblk
@param index
@param cblksty
@param first
*/
static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
/**
Decode a packet of a tile from a source buffer
@param t2 T2 handle
@@ -72,6 +73,7 @@ Decode a packet of a tile from a source buffer
@param tile Tile for which to write the packets
@param tcp Tile coding parameters
@param pi Packet identity
@param pack_info Packet information
@return
*/
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
@@ -147,8 +149,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
c[1] = 145;
c[2] = 0;
c[3] = 4;
c[4] = (tile->packno % 65536) / 256;
c[5] = (tile->packno % 65536) % 256;
c[4] = (unsigned char)((tile->packno % 65536) / 256);
c[5] = (unsigned char)((tile->packno % 65536) % 256);
c += 6;
}
/* </SOP> */
@@ -253,8 +255,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
/* </EPH> */
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value */
if(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->end_ph_pos = (int)(c - dest);
@@ -294,9 +296,17 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
return (c - dest);
}
static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
opj_tcd_seg_t* seg;
cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
opj_tcd_seg_t* segs;
segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
if (segs == NULL)
{
return OPJ_FALSE;
}
cblk->segs = segs;
seg = &cblk->segs[index];
seg->data = NULL;
seg->dataindex = 0;
@@ -314,6 +324,8 @@ static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int fi
} else {
seg->maxpasses = 109;
}
return OPJ_TRUE;
}
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
@@ -401,8 +413,8 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
}
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value*/
if(pack_info) {
pack_info->end_ph_pos = (int)(c - src);
}
@@ -460,12 +472,22 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
cblk->numlenbits += increment;
segno = 0;
if (!cblk->numsegs) {
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
} else {
segno = cblk->numsegs - 1;
if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) {
++segno;
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
}
}
n = cblk->numnewpasses;
@@ -476,7 +498,12 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
n -= cblk->segs[segno].numnewpasses;
if (n > 0) {
++segno;
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
}
} while (n > 0);
}
@@ -494,14 +521,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
if (tcp->csty & J2K_CP_CSTY_EPH) {
if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");
return -999;
} else {
hd += 2;
}
}
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value*/
if(pack_info) {
pack_info->end_ph_pos = (int)(hd - src);
}
@@ -565,7 +593,7 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
#endif /* USE_JPWL */
cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char*));
cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char));
memcpy(cblk->data + cblk->len, c, seg->newlen);
if (seg->numpasses == 0) {
seg->data = &cblk->data;
@@ -659,8 +687,8 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye
info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
}
info_PK->end_pos = info_PK->start_pos + e - 1;
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet
info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet*/
}
cstr_info->packno++;
@@ -711,7 +739,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
} else {
e = 0;
}
if(e == -999)
{
pi_destroy(pi, cp, tileno);
return -999;
}
/* progression in resolution */
image->comps[pi[pino].compno].resno_decoded =
(e > 0) ?
@@ -725,8 +757,9 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
if (!cstr_info->packno) {
info_PK->start_pos = info_TL->end_header + 1;
} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ // New tile part
info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part
} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/
info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/
info_TL->tp[curtp].tp_start_pack = tp_start_packno;
tp_start_packno = cstr_info->packno;
curtp++;
info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1;
@@ -734,8 +767,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
}
info_PK->end_pos = info_PK->start_pos + e - 1;
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet
info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet*/
cstr_info->packno++;
}
/* << INDEX */
@@ -749,7 +782,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
}
/* INDEX >> */
if(cstr_info) {
cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in last tile-part
cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/
cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno;
}
/* << INDEX */

View File

@@ -67,6 +67,7 @@ Encode the packets of a tile to a destination buffer
@param cstr_info Codestream information structure
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param pino
@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
@param cur_totnum_tp The total number of tile parts in the current tile
*/
@@ -78,6 +79,7 @@ Decode the packets of a tile from a source buffer
@param len length of the source buffer
@param tileno number that identifies the tile for which to decode the packets
@param tile tile for which to decode the packets
@param cstr_info Codestream information structure
*/
int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info);

View File

@@ -30,10 +30,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define _ISOC99_SOURCE /* lrintf is C99 */
#include "opj_includes.h"
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
int tileno, compno, resno, bandno, precno;//, cblkno;
int tileno, compno, resno, bandno, precno;/*, cblkno;*/
fprintf(fd, "image {\n");
fprintf(fd, " tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n",
@@ -290,6 +291,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
for (i = 0; i < res->pw * res->ph * 3; i++) {
band->precincts[i].imsbtree = NULL;
band->precincts[i].incltree = NULL;
band->precincts[i].cblks.enc = NULL;
}
for (precno = 0; precno < res->pw * res->ph; precno++) {
@@ -332,8 +334,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
cblk->y0 = int_max(cblkystart, prc->y0);
cblk->x1 = int_min(cblkxend, prc->x1);
cblk->y1 = int_min(cblkyend, prc->y1);
cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
cblk->data[0] = 0;
cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -593,6 +597,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
cblk->y1 = int_min(cblkyend, prc->y1);
cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
cblk->data[0] = 0;
cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -613,7 +619,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
tcd->image = image;
tcd->tcd_image->tw = cp->tw;
tcd->tcd_image->th = cp->th;
tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t));
tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t));
/*
Allocate place to store the decoded data = final image
@@ -656,7 +662,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
tilec->y1 = int_ceildiv(tile->y1, image->comps[i].dy);
x0 = j == 0 ? tilec->x0 : int_min(x0, (unsigned int) tilec->x0);
y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->x0);
y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->y0);
x1 = j == 0 ? tilec->x1 : int_max(x1, (unsigned int) tilec->x1);
y1 = j == 0 ? tilec->y1 : int_max(y1, (unsigned int) tilec->y1);
}
@@ -676,6 +682,8 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
opj_tcp_t *tcp;
opj_tcd_tile_t *tile;
OPJ_ARG_NOT_USED(cstr_info);
tcd->cp = cp;
tcp = &(cp->tcps[cp->tileno[tileno]]);
@@ -687,6 +695,12 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
opj_tccp_t *tccp = &tcp->tccps[compno];
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
if (tccp->numresolutions <= 0)
{
cp->tileno[tileno] = -1;
return;
}
/* border of each tile component (global) */
tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
@@ -997,7 +1011,7 @@ void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
}
}
bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
int compno, resno, bandno, precno, cblkno, passno, layno;
double min, max;
double cumdisto[100]; /* fixed_quality */
@@ -1149,7 +1163,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre
}
if (!success) {
return false;
return OPJ_FALSE;
}
if(cstr_info) { /* Threshold for Marcela Index */
@@ -1161,7 +1175,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre
cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
}
return true;
return OPJ_TRUE;
}
int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
@@ -1313,7 +1327,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
return l;
}
bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) {
opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) {
int l;
int compno;
int eof = 0;
@@ -1349,7 +1363,7 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
}
else {
cstr_info->tile[tileno].pdx[resno] = 15;
cstr_info->tile[tileno].pdx[resno] = 15;
cstr_info->tile[tileno].pdy[resno] = 15;
}
}
}
@@ -1373,14 +1387,24 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
t1_time = opj_clock(); /* time needed to decode a tile */
t1 = t1_create(tcd->cinfo);
if (t1 == NULL)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
t1_destroy(t1);
return OPJ_FALSE;
}
for (compno = 0; compno < tile->numcomps; ++compno) {
opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
/* The +3 is headroom required by the vectorized DWT */
tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int));
if(tilec->data)
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
else
opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: tile size invalid\n");
if (tilec->data == NULL)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
return OPJ_FALSE;
}
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
}
t1_destroy(t1);
t1_time = opj_clock() - t1_time;
@@ -1394,18 +1418,15 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
int numres2decode;
if (tcd->cp->reduce != 0) {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
if (tcd->image->comps[compno].resno_decoded < 0) {
if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number "
" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
return false;
return OPJ_FALSE;
}
}
if(!tilec->data) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. null data\n");
return false;
else {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
}
}
numres2decode = tcd->image->comps[compno].resno_decoded + 1;
@@ -1424,18 +1445,23 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
if (tcd->tcp->mct) {
int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0);
if (tcd->tcp->tccps[0].qmfbid == 1) {
mct_decode(
tile->comps[0].data,
tile->comps[1].data,
tile->comps[2].data,
n);
} else {
mct_decode_real(
(float*)tile->comps[0].data,
(float*)tile->comps[1].data,
(float*)tile->comps[2].data,
n);
if (tile->numcomps >= 3 ){
if (tcd->tcp->tccps[0].qmfbid == 1) {
mct_decode(
tile->comps[0].data,
tile->comps[1].data,
tile->comps[2].data,
n);
} else {
mct_decode_real(
(float*)tile->comps[0].data,
(float*)tile->comps[1].data,
(float*)tile->comps[2].data,
n);
}
} else{
opj_event_msg(tcd->cinfo, EVT_WARNING,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",tile->numcomps);
}
}
@@ -1459,6 +1485,11 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
if(!imagec->data){
imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int));
}
if (!imagec->data)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
return OPJ_FALSE;
}
if(tcd->tcp->tccps[compno].qmfbid == 1) {
for(j = res->y0; j < res->y1; ++j) {
for(i = res->x0; i < res->x1; ++i) {
@@ -1484,40 +1515,59 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);
if (eof) {
return false;
return OPJ_FALSE;
}
return true;
return OPJ_TRUE;
}
void tcd_free_decode(opj_tcd_t *tcd) {
opj_tcd_image_t *tcd_image = tcd->tcd_image;
int i = 0;
for (i = 0; i < tcd_image->tw * tcd_image->th; i++)
{
tcd_free_decode_tile(tcd, i);
}
opj_free(tcd_image->tiles);
}
void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) {
int compno,resno,bandno,precno;
int compno,resno,bandno,precno,cblkno;
opj_tcd_image_t *tcd_image = tcd->tcd_image;
opj_tcd_tile_t *tile = &tcd_image->tiles[tileno];
for (compno = 0; compno < tile->numcomps; compno++) {
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];
for (precno = 0; precno < res->ph * res->pw; precno++) {
opj_tcd_precinct_t *prec = &band->precincts[precno];
if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
if (prec->incltree != NULL) tgt_destroy(prec->incltree);
if (tile->comps != NULL) {
for (compno = 0; compno < tile->numcomps; compno++) {
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];
for (precno = 0; precno < res->ph * res->pw; precno++) {
opj_tcd_precinct_t *prec = &band->precincts[precno];
if (prec->cblks.dec != NULL) {
for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) {
opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno];
opj_free(cblk->data);
opj_free(cblk->segs);
}
opj_free(prec->cblks.dec);
}
if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
if (prec->incltree != NULL) tgt_destroy(prec->incltree);
}
opj_free(band->precincts);
}
opj_free(band->precincts);
}
opj_free(tilec->resolutions);
}
opj_free(tilec->resolutions);
opj_free(tile->comps);
tile->comps = NULL;
}
opj_free(tile->comps);
}

View File

@@ -251,7 +251,7 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
void tcd_rateallocate_fixed(opj_tcd_t *tcd);
void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final);
bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
/**
Encode a tile from the raw image into a buffer
@param tcd TCD handle
@@ -268,8 +268,9 @@ Decode a tile from a buffer into a raw image
@param src Source buffer
@param len Length of source buffer
@param tileno Number that identifies one of the tiles to be decoded
@param cstr_info Codestream information structure
*/
bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info);
opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info);
/**
Free the memory allocated for decoding
@param tcd TCD handle

View File

@@ -0,0 +1,120 @@
/*
* $Id: thix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "opj_includes.h"
/*
* Write tile-part headers mhix box
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] tileno tile number
* @param[in] cio file output handle
* @return length of mhix box
*/
int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio);
int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
{
int len, lenp, i;
int tileno;
opj_jp2_box_t *box;
lenp = 0;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.tw*cstr_info.th, sizeof(opj_jp2_box_t));
for ( i = 0; i < 2 ; i++ ){
if (i)
cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_THIX, 4); /* THIX */
write_manf( i, cstr_info.tw*cstr_info.th, box, cio);
for (tileno = 0; tileno < cstr_info.tw*cstr_info.th; tileno++){
box[tileno].length = write_tilemhix( coff, cstr_info, tileno, cio);
box[tileno].type = JPIP_MHIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio)
{
int i;
opj_tile_info_t tile;
opj_tp_info_t tp;
int len, lenp;
opj_marker_info_t *marker;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MHIX, 4); /* MHIX */
tile = cstr_info.tile[tileno];
tp = tile.tp[0];
cio_write( cio, tp.tp_end_header-tp.tp_start_pos+1, 8); /* TLEN */
marker = cstr_info.tile[tileno].marker;
for( i=0; i<cstr_info.tile[tileno].marknum; i++){ /* Marker restricted to 1 apparition */
cio_write( cio, marker[i].type, 2);
cio_write( cio, 0, 2);
cio_write( cio, marker[i].pos-coff, 8);
cio_write( cio, marker[i].len, 2);
}
/* free( marker);*/
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -0,0 +1,153 @@
/*
* $Id: tpix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <math.h>
#include "opj_includes.h"
#define MAX(a,b) ((a)>(b)?(a):(b))
/*
* Write faix box of tpix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
{
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_TPIX, 4); /* TPIX */
write_tpixfaix( coff, 0, cstr_info, j2klen, cio);
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
/*
* Get number of maximum tile parts per tile
*
* @param[in] cstr_info codestream information
* @return number of maximum tile parts per tile
*/
int get_num_max_tile_parts( opj_codestream_info_t cstr_info);
int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
{
int len, lenp;
int i, j;
int Aux;
int num_max_tile_parts;
int size_of_coding; /* 4 or 8 */
opj_tp_info_t tp;
int version;
num_max_tile_parts = get_num_max_tile_parts( cstr_info);
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = num_max_tile_parts == 1 ? 1:3;
}
else{
size_of_coding = 4;
version = num_max_tile_parts == 1 ? 0:2;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
cio_write( cio, num_max_tile_parts, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for (i = 0; i < cstr_info.tw*cstr_info.th; i++){
for (j = 0; j < cstr_info.tile[i].num_tps; j++){
tp = cstr_info.tile[i].tp[j];
cio_write( cio, tp.tp_start_pos-coff, size_of_coding); /* start position */
cio_write( cio, tp.tp_end_pos-tp.tp_start_pos+1, size_of_coding); /* length */
if (version & 0x02){
if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1)
Aux = cstr_info.numdecompos[compno] + 1;
else
Aux = j + 1;
cio_write( cio, Aux,4);
/*cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4);*/ /* Aux_i,j : Auxiliary value */
/* fprintf(stderr,"AUX value %d\n",Aux);*/
}
/*cio_write(0,4);*/
}
/* PADDING */
while (j < num_max_tile_parts){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
if (version & 0x02)
cio_write( cio, 0,4); /* Aux_i,j : Auxiliary value */
j++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
int get_num_max_tile_parts( opj_codestream_info_t cstr_info)
{
int num_max_tp = 0, i;
for( i=0; i<cstr_info.tw*cstr_info.th; i++)
num_max_tp = MAX( cstr_info.tile[i].num_tps, num_max_tp);
return num_max_tp;
}

View File

@@ -0,0 +1,89 @@
# -*- cmake -*-
project(llappearance)
include(00-Common)
include(LLCommon)
include(LLCharacter)
include(LLImage)
include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLRender)
include(LLVFS)
include(LLWindow)
include(LLXML)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(llappearance_SOURCE_FILES
llavatarappearance.cpp
llavatarjoint.cpp
llavatarjointmesh.cpp
lldriverparam.cpp
lllocaltextureobject.cpp
llpolyskeletaldistortion.cpp
llpolymesh.cpp
llpolymorph.cpp
lltexglobalcolor.cpp
lltexlayer.cpp
lltexlayerparams.cpp
lltexturemanagerbridge.cpp
llwearable.cpp
llwearabledata.cpp
llwearabletype.cpp
llviewervisualparam.cpp
llavatarappearancedefines.cpp
)
set(llappearance_HEADER_FILES
CMakeLists.txt
llavatarappearance.h
llavatarjoint.h
llavatarjointmesh.h
lldriverparam.h
lljointpickname.h
lllocaltextureobject.h
llpolyskeletaldistortion.h
llpolymesh.h
llpolymorph.h
lltexglobalcolor.h
lltexlayer.h
lltexlayerparams.h
lltexturemanagerbridge.h
llwearable.h
llwearabledata.h
llwearabletype.h
llviewervisualparam.h
llavatarappearancedefines.h
)
set_source_files_properties(${llappearance_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
add_library (llappearance ${llappearance_SOURCE_FILES})
target_link_libraries(llappearance
${LLCHARACTER_LIBRARIES}
${LLINVENTORY_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLRENDER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLXML_LIBRARIES}
${LLCOMMON_LIBRARIES}
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,454 @@
/**
* @file llavatarappearance.h
* @brief Declaration of LLAvatarAppearance class
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_AVATAR_APPEARANCE_H
#define LL_AVATAR_APPEARANCE_H
#include "llcharacter.h"
#include "llavatarappearancedefines.h"
#include "llavatarjointmesh.h"
#include "lldriverparam.h"
#include "lltexlayer.h"
#include "llviewervisualparam.h"
#include "llxmltree.h"
class LLTexLayerSet;
class LLTexGlobalColor;
class LLTexGlobalColorInfo;
class LLWearableData;
class LLAvatarBoneInfo;
class LLAvatarSkeletonInfo;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLAvatarAppearance
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLAvatarAppearance : public LLCharacter
{
LOG_CLASS(LLAvatarAppearance);
protected:
struct LLAvatarXmlInfo;
/********************************************************************************
** **
** INITIALIZATION
**/
private:
// Hide default constructor.
LLAvatarAppearance() {}
public:
LLAvatarAppearance(LLWearableData* wearable_data);
virtual ~LLAvatarAppearance();
static void initClass(); // initializes static members
static void cleanupClass(); // Cleanup data that's only init'd once per class.
virtual void initInstance(); // Called after construction to initialize the instance.
virtual BOOL loadSkeletonNode();
BOOL loadMeshNodes();
BOOL loadLayersets();
/** Initialization
** **
*******************************************************************************/
/********************************************************************************
** **
** INHERITED
**/
//--------------------------------------------------------------------
// LLCharacter interface and related
//--------------------------------------------------------------------
public:
/*virtual*/ LLJoint* getCharacterJoint(U32 num);
/*virtual*/ const char* getAnimationPrefix() { return "avatar"; }
/*virtual*/ LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
/*virtual*/ LLJoint* findCollisionVolume(U32 volume_id);
/*virtual*/ S32 getCollisionVolumeID(std::string &name);
/*virtual*/ LLPolyMesh* getHeadMesh();
/*virtual*/ LLPolyMesh* getUpperBodyMesh();
LLPolyMesh* getMesh( LLPolyMeshSharedData *shared_data );
typedef std::map<S32, std::string> lod_mesh_map_t;
typedef std::map<std::string, lod_mesh_map_t> mesh_info_t;
static void getMeshInfo(mesh_info_t* mesh_info);
/** Inherited
** **
*******************************************************************************/
/********************************************************************************
** **
** STATE
**/
public:
virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
virtual BOOL isValid() const;
//virtual BOOL isUsingServerBakes() const = 0;
//virtual BOOL isUsingLocalAppearance() const = 0;
//virtual BOOL isEditingAppearance() const = 0;
BOOL isUsingLocalAppearance() const {return isEditingAppearance();}
virtual BOOL isEditingAppearance() const {return FALSE;}
bool isBuilt() const { return mIsBuilt; }
virtual std::string getFullname() const = 0;
/** State
** **
*******************************************************************************/
/********************************************************************************
** **
** SKELETON
**/
protected:
virtual LLAvatarJoint* createAvatarJoint() = 0;
virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0;
virtual LLAvatarJointMesh* createAvatarJointMesh() = 0;
public:
F32 getPelvisToFoot() const { return mPelvisToFoot; }
/*virtual*/ LLJoint* getRootJoint() { return mRoot; }
LLVector3 mHeadOffset; // current head position
LLAvatarJoint *mRoot;
typedef std::map<std::string, LLJoint*> joint_map_t;
joint_map_t mJointMap;
void computeBodySize();
protected:
static BOOL parseSkeletonFile(const std::string& filename);
virtual void buildCharacter();
virtual BOOL loadAvatar();
virtual void bodySizeChanged() = 0;
BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
BOOL allocateCharacterJoints(U32 num);
BOOL buildSkeleton(const LLAvatarSkeletonInfo *info);
protected:
void clearSkeleton();
BOOL mIsBuilt; // state of deferred character building
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
avatar_joint_list_t mSkeleton;
//--------------------------------------------------------------------
// Pelvis height adjustment members.
//--------------------------------------------------------------------
public:
LLVector3 mBodySize;
protected:
F32 mPelvisToFoot;
//--------------------------------------------------------------------
// Cached pointers to well known joints
//--------------------------------------------------------------------
public:
LLJoint* mPelvisp;
LLJoint* mTorsop;
LLJoint* mChestp;
LLJoint* mNeckp;
LLJoint* mHeadp;
LLJoint* mSkullp;
LLJoint* mEyeLeftp;
LLJoint* mEyeRightp;
LLJoint* mHipLeftp;
LLJoint* mHipRightp;
LLJoint* mKneeLeftp;
LLJoint* mKneeRightp;
LLJoint* mAnkleLeftp;
LLJoint* mAnkleRightp;
LLJoint* mFootLeftp;
LLJoint* mFootRightp;
LLJoint* mWristLeftp;
LLJoint* mWristRightp;
//--------------------------------------------------------------------
// XML parse tree
//--------------------------------------------------------------------
protected:
static LLXmlTree sXMLTree; // avatar config file
static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
static LLAvatarSkeletonInfo* sAvatarSkeletonInfo;
static LLAvatarXmlInfo* sAvatarXmlInfo;
/** Skeleton
** **
*******************************************************************************/
/********************************************************************************
** **
** RENDERING
**/
public:
BOOL mIsDummy; // for special views
//--------------------------------------------------------------------
// Morph masks
//--------------------------------------------------------------------
public:
void addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
virtual void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
/** Rendering
** **
*******************************************************************************/
//--------------------------------------------------------------------
// Composites
//--------------------------------------------------------------------
public:
virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0;
/********************************************************************************
** **
** MESHES
**/
public:
virtual void updateMeshTextures() = 0;
virtual void dirtyMesh() = 0; // Dirty the avatar mesh
protected:
virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
protected:
typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
polymesh_map_t mPolyMeshes;
avatar_joint_list_t mMeshLOD;
/** Meshes
** **
*******************************************************************************/
/********************************************************************************
** **
** APPEARANCE
**/
//--------------------------------------------------------------------
// Clothing colors (convenience functions to access visual parameters)
//--------------------------------------------------------------------
public:
void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
//--------------------------------------------------------------------
// Global colors
//--------------------------------------------------------------------
public:
LLColor4 getGlobalColor(const std::string& color_name ) const;
virtual void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0;
protected:
LLTexGlobalColor* mTexSkinColor;
LLTexGlobalColor* mTexHairColor;
LLTexGlobalColor* mTexEyeColor;
//--------------------------------------------------------------------
// Visibility
//--------------------------------------------------------------------
public:
static LLColor4 getDummyColor();
/** Appearance
** **
*******************************************************************************/
/********************************************************************************
** **
** WEARABLES
**/
public:
LLWearableData* getWearableData() { return mWearableData; }
const LLWearableData* getWearableData() const { return mWearableData; }
virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0;
virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
private:
LLWearableData* mWearableData;
/********************************************************************************
** **
** BAKED TEXTURES
**/
public:
LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
protected:
virtual LLTexLayerSet* createTexLayerSet() = 0;
protected:
class LLMaskedMorph;
typedef std::deque<LLMaskedMorph *> morph_list_t;
struct BakedTextureData
{
LLUUID mLastTextureID;
LLTexLayerSet* mTexLayerSet; // Only exists for self
bool mIsLoaded;
bool mIsUsed;
LLAvatarAppearanceDefines::ETextureIndex mTextureIndex;
U32 mMaskTexName;
// Stores pointers to the joint meshes that this baked texture deals with
avatar_joint_mesh_list_t mJointMeshes;
morph_list_t mMaskedMorphs;
};
typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
bakedtexturedata_vec_t mBakedTextureDatas;
/********************************************************************************
** **
** PHYSICS
**/
//--------------------------------------------------------------------
// Collision volumes
//--------------------------------------------------------------------
public:
S32 mNumCollisionVolumes;
LLAvatarJointCollisionVolume* mCollisionVolumes;
protected:
BOOL allocateCollisionVolumes(U32 num);
/** Physics
** **
*******************************************************************************/
/********************************************************************************
** **
** SUPPORT CLASSES
**/
struct LLAvatarXmlInfo
{
LLAvatarXmlInfo();
~LLAvatarXmlInfo();
BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
BOOL parseXmlColorNodes(LLXmlTreeNode* root);
BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
struct LLAvatarMeshInfo
{
typedef std::pair<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here
typedef std::vector<morph_info_pair_t> morph_info_list_t;
LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
~LLAvatarMeshInfo()
{
morph_info_list_t::iterator iter;
for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
{
delete iter->first;
}
mPolyMorphTargetInfoList.clear();
}
std::string mType;
S32 mLOD;
std::string mMeshFileName;
std::string mReferenceMeshName;
F32 mMinPixelArea;
morph_info_list_t mPolyMorphTargetInfoList;
};
typedef std::vector<LLAvatarMeshInfo*> mesh_info_list_t;
mesh_info_list_t mMeshInfoList;
typedef std::vector<LLViewerVisualParamInfo*> skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here
skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
struct LLAvatarAttachmentInfo
{
LLAvatarAttachmentInfo()
: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
std::string mName;
std::string mJointName;
LLVector3 mPosition;
LLVector3 mRotationEuler;
S32 mGroup;
S32 mAttachmentID;
S32 mPieMenuSlice;
BOOL mVisibleFirstPerson;
BOOL mIsHUDAttachment;
BOOL mHasPosition;
BOOL mHasRotation;
};
typedef std::vector<LLAvatarAttachmentInfo*> attachment_info_list_t;
attachment_info_list_t mAttachmentInfoList;
LLTexGlobalColorInfo *mTexSkinColorInfo;
LLTexGlobalColorInfo *mTexHairColorInfo;
LLTexGlobalColorInfo *mTexEyeColorInfo;
typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
layer_info_list_t mLayerInfoList;
typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
driver_info_list_t mDriverInfoList;
struct LLAvatarMorphInfo
{
LLAvatarMorphInfo()
: mInvert(FALSE) {}
std::string mName;
std::string mRegion;
std::string mLayer;
BOOL mInvert;
};
typedef std::vector<LLAvatarMorphInfo*> morph_info_list_t;
morph_info_list_t mMorphMaskInfoList;
};
class LLMaskedMorph
{
public:
LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer);
LLVisualParam *mMorphTarget;
BOOL mInvert;
std::string mLayer;
};
/** Support Classes
** **
*******************************************************************************/
};
#endif // LL_AVATAR_APPEARANCE_H

View File

@@ -1,51 +1,43 @@
/**
* @file llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
* @file llavatarappearancedefines.cpp
* @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llvoavatardefines.h"
#include "llviewercontrol.h" // gSavedSettings
#include "linden_common.h"
#include "llavatarappearancedefines.h"
const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2;
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
using namespace LLVOAvatarDefines;
using namespace LLAvatarAppearanceDefines;
/*********************************************************************************
* Edit this function to add/remove/change textures and mesh definitions for avatars.
* If these are changed, they MUST be changed in floater_avatar_textures.xml as well!
*/
LLVOAvatarDictionary::Textures::Textures()
LLAvatarAppearanceDictionary::Textures::Textures()
{
addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", LLWearableType::WT_SHIRT));
@@ -73,15 +65,15 @@ LLVOAvatarDictionary::Textures::Textures()
addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD));
addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER));
addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER));
addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES));
addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR));
addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT));
addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head"));
addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper"));
addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower"));
addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes"));
addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair"));
addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt"));
}
LLVOAvatarDictionary::BakedTextures::BakedTextures()
LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
{
// Baked textures
addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
@@ -117,36 +109,36 @@ LLVOAvatarDictionary::BakedTextures::BakedTextures()
2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
}
LLVOAvatarDictionary::Meshes::Meshes()
LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
{
// Meshes
addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4));
addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5));
addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0)); // no baked mesh associated currently
addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1));
addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2));
addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3));
addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5));
// MeshEntries
addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, PN_4));
addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, PN_5));
addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, PN_0)); // no baked mesh associated currently
addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, PN_1));
addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, PN_2));
addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, PN_3));
addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, PN_3));
addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, PN_5));
}
/*
*
*********************************************************************************/
LLVOAvatarDictionary::LLVOAvatarDictionary()
LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary()
{
createAssociations();
}
//virtual
LLVOAvatarDictionary::~LLVOAvatarDictionary()
LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary()
{
}
// Baked textures are composites of textures; for each such composited texture,
// map it to the baked texture.
void LLVOAvatarDictionary::createAssociations()
void LLAvatarAppearanceDictionary::createAssociations()
{
for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
{
@@ -167,11 +159,11 @@ void LLVOAvatarDictionary::createAssociations()
}
LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
bool is_local_texture,
EBakedTextureIndex baked_texture_index,
const std::string &default_image_name,
LLWearableType::EType wearable_type) :
LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,
bool is_local_texture,
EBakedTextureIndex baked_texture_index,
const std::string &default_image_name,
LLWearableType::EType wearable_type) :
LLDictionaryEntry(name),
mIsLocalTexture(is_local_texture),
mIsBakedTexture(!is_local_texture),
@@ -182,17 +174,17 @@ LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
{
}
LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
const std::string &name,
U8 level,
LLViewerJoint::PickName pick) :
LLJointPickName pick) :
LLDictionaryEntry(name),
mBakedID(baked_index),
mLOD(level),
mPickName(pick)
{
}
LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
const std::string &name,
const std::string &hash_name,
U32 num_local_textures,
@@ -223,18 +215,18 @@ LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
}
// static
ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
{
return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
}
//static
EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
// static
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
{
const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
if (be && be->mName.compare(name) == 0)
{
// baked texture found
@@ -246,23 +238,31 @@ EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
return BAKED_NUM_INDICES;
}
//static
const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
// static
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
{
const TextureEntry *texture_dict = getInstance()->getTexture(index);
const std::string &default_image_name = texture_dict->mDefaultImageName;
if (default_image_name == "")
U8 index = 0;
while (index < BAKED_NUM_INDICES)
{
return IMG_DEFAULT_AVATAR;
}
else
{
return LLUUID(gSavedSettings.getString(default_image_name));
const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
if (be)
{
const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
if (te && te->mDefaultImageName.compare(name) == 0)
{
// baked texture found
return (EBakedTextureIndex) index;
}
}
index++;
}
// baked texture could not be found
return BAKED_NUM_INDICES;
}
// static
LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
{
return getInstance()->getTexture(index)->mWearableType;
}

View File

@@ -1,45 +1,40 @@
/**
* @file llvoavatar.h
* @brief Declaration of LLVOAvatar class which is a derivation fo
* @file llavatarappearancedefines.h
* @brief Various LLAvatarAppearance related definitions
* LLViewerObject
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LLVOAVATAR_DEFINES_H
#define LLVOAVATAR_DEFINES_H
#ifndef LL_AVATARAPPEARANCE_DEFINES_H
#define LL_AVATARAPPEARANCE_DEFINES_H
#include <vector>
#include "llwearable.h"
#include "llviewerjoint.h"
#include "lljointpickname.h"
#include "lldictionary.h"
#include "llwearabletype.h"
#include "lluuid.h"
namespace LLVOAvatarDefines
namespace LLAvatarAppearanceDefines
{
extern const S32 SCRATCH_TEX_WIDTH;
@@ -47,10 +42,11 @@ extern const S32 SCRATCH_TEX_HEIGHT;
extern const S32 IMPOSTOR_PERIOD;
//--------------------------------------------------------------------
// texture entry assignment
// Enums
//--------------------------------------------------------------------
enum ETextureIndex
{
TEX_INVALID = -1,
TEX_HEAD_BODYPAINT = 0,
TEX_UPPER_SHIRT,
TEX_LOWER_PANTS,
@@ -59,9 +55,9 @@ enum ETextureIndex
TEX_UPPER_BODYPAINT,
TEX_LOWER_BODYPAINT,
TEX_LOWER_SHOES,
TEX_HEAD_BAKED, // Pre-composited
TEX_UPPER_BAKED, // Pre-composited
TEX_LOWER_BAKED, // Pre-composited
TEX_HEAD_BAKED, // Pre-composited
TEX_UPPER_BAKED, // Pre-composited
TEX_LOWER_BAKED, // Pre-composited
TEX_EYES_BAKED, // Pre-composited
TEX_LOWER_SOCKS,
TEX_UPPER_JACKET,
@@ -70,7 +66,7 @@ enum ETextureIndex
TEX_UPPER_UNDERSHIRT,
TEX_LOWER_UNDERPANTS,
TEX_SKIRT,
TEX_SKIRT_BAKED, // Pre-composited
TEX_SKIRT_BAKED, // Pre-composited
TEX_HAIR_BAKED, // Pre-composited
TEX_LOWER_ALPHA,
TEX_UPPER_ALPHA,
@@ -81,7 +77,7 @@ enum ETextureIndex
TEX_UPPER_TATTOO,
TEX_LOWER_TATTOO,
TEX_NUM_INDICES
};
};
enum EBakedTextureIndex
{
@@ -117,21 +113,21 @@ typedef std::vector<EMeshIndex> mesh_vec_t;
typedef std::vector<LLWearableType::EType> wearables_vec_t;
//------------------------------------------------------------------------
// LLVOAvatarDictionary
// LLAvatarAppearanceDictionary
//
// Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
// information that is common to all avatars.
//
// This holds const data - it is initialized once and the contents never change after that.
//------------------------------------------------------------------------
class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
{
//--------------------------------------------------------------------
// Constructors and Destructors
//--------------------------------------------------------------------
public:
LLVOAvatarDictionary();
virtual ~LLVOAvatarDictionary();
LLAvatarAppearanceDictionary();
virtual ~LLAvatarAppearanceDictionary();
private:
void createAssociations();
@@ -141,19 +137,19 @@ private:
public:
struct TextureEntry : public LLDictionaryEntry
{
TextureEntry(const std::string &name,
bool is_local_texture,
EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
const std::string &default_image_name = "",
TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml
bool is_local_texture,
EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
const std::string& default_image_name = "",
LLWearableType::EType wearable_type = LLWearableType::WT_INVALID);
const std::string mDefaultImageName;
const std::string mDefaultImageName;
const LLWearableType::EType mWearableType;
// It's either a local texture xor baked
BOOL mIsLocalTexture;
BOOL mIsBakedTexture;
BOOL mIsLocalTexture;
BOOL mIsBakedTexture;
// If it's a local texture, it may be used by a baked texture
BOOL mIsUsedByBakedTexture;
EBakedTextureIndex mBakedTextureIndex;
BOOL mIsUsedByBakedTexture;
EBakedTextureIndex mBakedTextureIndex;
};
struct Textures : public LLDictionary<ETextureIndex, TextureEntry>
@@ -170,22 +166,22 @@ public:
struct MeshEntry : public LLDictionaryEntry
{
MeshEntry(EBakedTextureIndex baked_index,
const std::string &name,
U8 level,
LLViewerJoint::PickName pick);
const std::string &name, // names of mesh types as they are used in avatar_lad.xml
U8 level,
LLJointPickName pick);
// Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml
// Otherwise meshes will be unable to be found, or levels of detail will be ignored
const U8 mLOD;
const EBakedTextureIndex mBakedID;
const LLViewerJoint::PickName mPickName;
const U8 mLOD;
const EBakedTextureIndex mBakedID;
const LLJointPickName mPickName;
};
struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>
{
Meshes();
} mMeshes;
const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
const Meshes& getMeshes() const { return mMeshes; }
MeshEntries();
} mMeshEntries;
const MeshEntry* getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
const MeshEntries& getMeshEntries() const { return mMeshEntries; }
//--------------------------------------------------------------------
// Baked Textures
@@ -204,7 +200,7 @@ public:
const LLUUID mWearablesHashID;
wearables_vec_t mWearables;
};
struct BakedTextures: public LLDictionary<EBakedTextureIndex, BakedEntry>
{
BakedTextures();
@@ -221,14 +217,13 @@ public:
// find a baked texture index based on its name
static EBakedTextureIndex findBakedByRegionName(std::string name);
static const LLUUID getDefaultTextureImageID(ETextureIndex index);
static EBakedTextureIndex findBakedByImageName(std::string name);
// Given a texture entry, determine which wearable type owns it.
static LLWearableType::EType getTEWearableType(ETextureIndex index);
}; // End LLVOAvatarDictionary
}; // End LLAvatarAppearanceDictionary
} // End namespace LLVOAvatarDefines
} // End namespace LLAvatarAppearanceDefines
#endif
#endif //LL_AVATARAPPEARANCE_DEFINES_H

View File

@@ -0,0 +1,326 @@
/**
* @file llavatarjoint.cpp
* @brief Implementation of LLAvatarJoint class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "llavatarjoint.h"
#include "llgl.h"
#include "llrender.h"
#include "llmath.h"
#include "llglheaders.h"
#include "llavatarappearance.h"
const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
BOOL LLAvatarJoint::sDisableLOD = FALSE;
//-----------------------------------------------------------------------------
// LLAvatarJoint()
// Class Constructors
//-----------------------------------------------------------------------------
LLAvatarJoint::LLAvatarJoint() :
LLJoint()
{
init();
}
LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
LLJoint(name, parent)
{
init();
}
LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
LLJoint(joint_num)
{
init();
}
void LLAvatarJoint::init()
{
mValid = FALSE;
mComponents = SC_JOINT | SC_BONE | SC_AXES;
mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
mPickName = PN_DEFAULT;
mVisible = TRUE;
mMeshID = 0;
mIsTransparent = FALSE;
}
//-----------------------------------------------------------------------------
// ~LLAvatarJoint()
// Class Destructor
//-----------------------------------------------------------------------------
LLAvatarJoint::~LLAvatarJoint()
{
}
//--------------------------------------------------------------------
// setValid()
//--------------------------------------------------------------------
void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
{
//----------------------------------------------------------------
// set visibility for this joint
//----------------------------------------------------------------
mValid = valid;
//----------------------------------------------------------------
// set visibility for children
//----------------------------------------------------------------
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
joint->setValid(valid, TRUE);
}
}
}
//--------------------------------------------------------------------
// setSkeletonComponents()
//--------------------------------------------------------------------
void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
{
mComponents = comp;
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setSkeletonComponents(comp, recursive);
}
}
}
void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
{
mVisible = visible;
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
joint->setVisible(visible, recursive);
}
}
}
void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
}
}
void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
}
}
void LLAvatarJoint::updateJointGeometry()
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateJointGeometry();
}
}
BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
{
BOOL lod_changed = FALSE;
BOOL found_lod = FALSE;
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
F32 jointLOD = joint->getLOD();
if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
{
// we've already found a joint to enable, so enable the rest as alternatives
lod_changed |= joint->updateLOD(pixel_area, TRUE);
}
else
{
if (pixel_area >= jointLOD || sDisableLOD)
{
lod_changed |= joint->updateLOD(pixel_area, TRUE);
found_lod = TRUE;
}
else
{
lod_changed |= joint->updateLOD(pixel_area, FALSE);
}
}
}
return lod_changed;
}
void LLAvatarJoint::dump()
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->dump();
}
}
void LLAvatarJoint::setMeshesToChildren()
{
removeAllChildren();
for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
iter != mMeshParts.end(); iter++)
{
addChild((*iter));
}
}
//-----------------------------------------------------------------------------
// LLAvatarJointCollisionVolume()
//-----------------------------------------------------------------------------
LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
{
mUpdateXform = FALSE;
}
/*virtual*/
U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
{
llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
return 0;
}
LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
{
mUpdateXform = TRUE;
LLVector3 result = offset;
result.scaleVec(getScale());
result.rotVec(getWorldRotation());
result += getWorldPosition();
return result;
}
void LLAvatarJointCollisionVolume::renderCollision()
{
updateWorldMatrix();
gGL.pushMatrix();
gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
gGL.diffuseColor3f( 0.f, 0.f, 1.f );
gGL.begin(LLRender::LINES);
LLVector3 v[] =
{
LLVector3(1,0,0),
LLVector3(-1,0,0),
LLVector3(0,1,0),
LLVector3(0,-1,0),
LLVector3(0,0,-1),
LLVector3(0,0,1),
};
//sides
gGL.vertex3fv(v[0].mV);
gGL.vertex3fv(v[2].mV);
gGL.vertex3fv(v[0].mV);
gGL.vertex3fv(v[3].mV);
gGL.vertex3fv(v[1].mV);
gGL.vertex3fv(v[2].mV);
gGL.vertex3fv(v[1].mV);
gGL.vertex3fv(v[3].mV);
//top
gGL.vertex3fv(v[0].mV);
gGL.vertex3fv(v[4].mV);
gGL.vertex3fv(v[1].mV);
gGL.vertex3fv(v[4].mV);
gGL.vertex3fv(v[2].mV);
gGL.vertex3fv(v[4].mV);
gGL.vertex3fv(v[3].mV);
gGL.vertex3fv(v[4].mV);
//bottom
gGL.vertex3fv(v[0].mV);
gGL.vertex3fv(v[5].mV);
gGL.vertex3fv(v[1].mV);
gGL.vertex3fv(v[5].mV);
gGL.vertex3fv(v[2].mV);
gGL.vertex3fv(v[5].mV);
gGL.vertex3fv(v[3].mV);
gGL.vertex3fv(v[5].mV);
gGL.end();
gGL.popMatrix();
}
// End

View File

@@ -0,0 +1,140 @@
/**
* @file llavatarjoint.h
* @brief Implementation of LLAvatarJoint class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLAVATARJOINT_H
#define LL_LLAVATARJOINT_H
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "lljoint.h"
#include "lljointpickname.h"
class LLFace;
class LLAvatarJointMesh;
extern const F32 DEFAULT_AVATAR_JOINT_LOD;
//-----------------------------------------------------------------------------
// class LLViewerJoint
//-----------------------------------------------------------------------------
class LLAvatarJoint :
public LLJoint
{
public:
LLAvatarJoint();
LLAvatarJoint(S32 joint_num);
// *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
virtual ~LLAvatarJoint();
// Gets the validity of this joint
BOOL getValid() { return mValid; }
// Sets the validity of this joint
virtual void setValid( BOOL valid, BOOL recursive=FALSE );
// Returns true if this object is transparent.
// This is used to determine in which order to draw objects.
virtual BOOL isTransparent() { return mIsTransparent; }
// Returns true if this object should inherit scale modifiers from its immediate parent
virtual BOOL inheritScale() { return FALSE; }
enum Components
{
SC_BONE = 1,
SC_JOINT = 2,
SC_AXES = 4
};
// Selects which skeleton components to draw
void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
// Returns which skeleton components are enables for drawing
U32 getSkeletonComponents() { return mComponents; }
// Sets the level of detail for this node as a minimum
// pixel area threshold. If the current pixel area for this
// object is less than the specified threshold, the node is
// not traversed. In addition, if a value is specified (not
// default of 0.0), and the pixel area is larger than the
// specified minimum, the node is rendered, but no other siblings
// of this node under the same parent will be.
F32 getLOD() { return mMinPixelArea; }
void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
void setPickName(LLJointPickName name) { mPickName = name; }
LLJointPickName getPickName() { return mPickName; }
void setVisible( BOOL visible, BOOL recursive );
// Takes meshes in mMeshParts and sets each one as a child joint
void setMeshesToChildren();
// LLViewerJoint interface
virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
virtual void updateJointGeometry();
virtual void dump();
public:
static BOOL sDisableLOD;
avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
void setMeshID( S32 id ) {mMeshID = id;}
protected:
void init();
BOOL mValid;
BOOL mIsTransparent;
U32 mComponents;
F32 mMinPixelArea;
LLJointPickName mPickName;
BOOL mVisible;
S32 mMeshID;
};
class LLAvatarJointCollisionVolume : public LLAvatarJoint
{
public:
LLAvatarJointCollisionVolume();
virtual ~LLAvatarJointCollisionVolume() {};
/*virtual*/ BOOL inheritScale() { return TRUE; }
/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
void renderCollision();
LLVector3 getVolumePos(LLVector3 &offset);
};
#endif // LL_LLAVATARJOINT_H

View File

@@ -0,0 +1,375 @@
/**
* @file LLAvatarJointMesh.cpp
* @brief Implementation of LLAvatarJointMesh class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "linden_common.h"
#include "imageids.h"
#include "llfasttimer.h"
#include "llrender.h"
#include "llavatarjointmesh.h"
#include "llavatarappearance.h"
//#include "llapr.h"
//#include "llbox.h"
//#include "lldrawable.h"
//#include "lldrawpoolavatar.h"
//#include "lldrawpoolbump.h"
//#include "lldynamictexture.h"
//#include "llface.h"
//#include "llgldbg.h"
//#include "llglheaders.h"
#include "lltexlayer.h"
//#include "llviewercamera.h"
//#include "llviewercontrol.h"
//#include "llviewertexturelist.h"
//#include "llsky.h"
//#include "pipeline.h"
//#include "llviewershadermgr.h"
#include "llmath.h"
#include "v4math.h"
#include "m3math.h"
#include "m4math.h"
#include "llmatrix4a.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLAvatarJointMesh::LLSkinJoint
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLSkinJoint
//-----------------------------------------------------------------------------
LLSkinJoint::LLSkinJoint()
{
mJoint = NULL;
}
//-----------------------------------------------------------------------------
// ~LLSkinJoint
//-----------------------------------------------------------------------------
LLSkinJoint::~LLSkinJoint()
{
mJoint = NULL;
}
//-----------------------------------------------------------------------------
// LLSkinJoint::setupSkinJoint()
//-----------------------------------------------------------------------------
BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
{
// find the named joint
mJoint = joint;
if ( !mJoint )
{
llinfos << "Can't find joint" << llendl;
}
// compute the inverse root skin matrix
mRootToJointSkinOffset.clearVec();
LLVector3 rootSkinOffset;
while (joint)
{
rootSkinOffset += joint->getSkinOffset();
joint = (LLAvatarJoint*)joint->getParent();
}
mRootToJointSkinOffset = -rootSkinOffset;
mRootToParentJointSkinOffset = mRootToJointSkinOffset;
mRootToParentJointSkinOffset += mJoint->getSkinOffset();
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLAvatarJointMesh
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
LLColor4 LLAvatarJointMesh::sClothingInnerColor;
//-----------------------------------------------------------------------------
// LLAvatarJointMesh()
//-----------------------------------------------------------------------------
LLAvatarJointMesh::LLAvatarJointMesh()
:
mTexture( NULL ),
mLayerSet( NULL ),
mTestImageName( 0 ),
mFaceIndexCount(0)
{
mColor[0] = 1.0f;
mColor[1] = 1.0f;
mColor[2] = 1.0f;
mColor[3] = 1.0f;
mShiny = 0.0f;
mCullBackFaces = TRUE;
mMesh = NULL;
mNumSkinJoints = 0;
mSkinJoints = NULL;
mFace = NULL;
mMeshID = 0;
mUpdateXform = FALSE;
mValid = FALSE;
mIsTransparent = FALSE;
}
//-----------------------------------------------------------------------------
// ~LLAvatarJointMesh()
// Class Destructor
//-----------------------------------------------------------------------------
LLAvatarJointMesh::~LLAvatarJointMesh()
{
mMesh = NULL;
mTexture = NULL;
freeSkinData();
}
//-----------------------------------------------------------------------------
// LLAvatarJointMesh::allocateSkinData()
//-----------------------------------------------------------------------------
BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints )
{
mSkinJoints = new LLSkinJoint[ numSkinJoints ];
mNumSkinJoints = numSkinJoints;
return TRUE;
}
//-----------------------------------------------------------------------------
// LLAvatarJointMesh::freeSkinData()
//-----------------------------------------------------------------------------
void LLAvatarJointMesh::freeSkinData()
{
mNumSkinJoints = 0;
delete [] mSkinJoints;
mSkinJoints = NULL;
}
//--------------------------------------------------------------------
// LLAvatarJointMesh::getColor()
//--------------------------------------------------------------------
void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
{
*red = mColor[0];
*green = mColor[1];
*blue = mColor[2];
*alpha = mColor[3];
}
//--------------------------------------------------------------------
// LLAvatarJointMesh::setColor()
//--------------------------------------------------------------------
void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
{
mColor[0] = red;
mColor[1] = green;
mColor[2] = blue;
mColor[3] = alpha;
}
void LLAvatarJointMesh::setColor( const LLColor4& color )
{
mColor = color;
}
//--------------------------------------------------------------------
// LLAvatarJointMesh::getTexture()
//--------------------------------------------------------------------
//LLViewerTexture *LLAvatarJointMesh::getTexture()
//{
// return mTexture;
//}
//--------------------------------------------------------------------
// LLAvatarJointMesh::setTexture()
//--------------------------------------------------------------------
void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
{
mTexture = texture;
// texture and dynamic_texture are mutually exclusive
if( texture )
{
mLayerSet = NULL;
//texture->bindTexture(0);
//texture->setClamp(TRUE, TRUE);
}
}
BOOL LLAvatarJointMesh::hasGLTexture() const
{
return mTexture.notNull() && mTexture->hasGLTexture();
}
//--------------------------------------------------------------------
// LLAvatarJointMesh::setLayerSet()
// Sets the shape texture (takes precedence over normal texture)
//--------------------------------------------------------------------
void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
{
mLayerSet = layer_set;
// texture and dynamic_texture are mutually exclusive
if( layer_set )
{
mTexture = NULL;
}
}
BOOL LLAvatarJointMesh::hasComposite() const
{
return (mLayerSet && mLayerSet->hasComposite());
}
//--------------------------------------------------------------------
// LLAvatarJointMesh::getMesh()
//--------------------------------------------------------------------
LLPolyMesh *LLAvatarJointMesh::getMesh()
{
return mMesh;
}
//-----------------------------------------------------------------------------
// LLAvatarJointMesh::setMesh()
//-----------------------------------------------------------------------------
void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
{
// set the mesh pointer
mMesh = mesh;
// release any existing skin joints
freeSkinData();
if ( mMesh == NULL )
{
return;
}
// acquire the transform from the mesh object
setPosition( mMesh->getPosition() );
setRotation( mMesh->getRotation() );
setScale( mMesh->getScale() );
// create skin joints if necessary
if ( mMesh->hasWeights() && !mMesh->isLOD())
{
U32 numJointNames = mMesh->getNumJointNames();
allocateSkinData( numJointNames );
std::string *jointNames = mMesh->getJointNames();
U32 jn;
for (jn = 0; jn < numJointNames; jn++)
{
//llinfos << "Setting up joint " << jointNames[jn] << llendl;
LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
mSkinJoints[jn].setupSkinJoint( joint );
}
}
// setup joint array
if (!mMesh->isLOD())
{
setupJoint((LLAvatarJoint*)getRoot());
}
// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
}
//-----------------------------------------------------------------------------
// setupJoint()
//-----------------------------------------------------------------------------
void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
{
// llinfos << "Mesh: " << getName() << llendl;
// S32 joint_count = 0;
U32 sj;
for (sj=0; sj<mNumSkinJoints; sj++)
{
LLSkinJoint &js = mSkinJoints[sj];
if (js.mJoint != current_joint)
{
continue;
}
// we've found a skinjoint for this joint..
// is the last joint in the array our parent?
if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
{
// ...then just add ourselves
LLAvatarJoint* jointp = js.mJoint;
mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
// joint_count++;
}
// otherwise add our parent and ourselves
else
{
mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
// joint_count++;
mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
// llinfos << "joint " << joint_count << current_joint->getName() << llendl;
// joint_count++;
}
}
// depth-first traversal
for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
iter != current_joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
setupJoint(child_joint);
}
}
// End

View File

@@ -0,0 +1,142 @@
/**
* @file llavatarjointmesh.h
* @brief Declaration of LLAvatarJointMesh class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLAVATARJOINTMESH_H
#define LL_LLAVATARJOINTMESH_H
#include "llavatarjoint.h"
#include "llgltexture.h"
#include "llpolymesh.h"
#include "v4color.h"
class LLDrawable;
class LLFace;
class LLCharacter;
class LLTexLayerSet;
typedef enum e_avatar_render_pass
{
AVATAR_RENDER_PASS_SINGLE,
AVATAR_RENDER_PASS_CLOTHING_INNER,
AVATAR_RENDER_PASS_CLOTHING_OUTER
} EAvatarRenderPass;
class LLSkinJoint
{
public:
LLSkinJoint();
~LLSkinJoint();
BOOL setupSkinJoint( LLAvatarJoint *joint);
LLAvatarJoint *mJoint;
LLVector3 mRootToJointSkinOffset;
LLVector3 mRootToParentJointSkinOffset;
};
//-----------------------------------------------------------------------------
// class LLViewerJointMesh
//-----------------------------------------------------------------------------
class LLAvatarJointMesh : public virtual LLAvatarJoint
{
protected:
LLColor4 mColor; // color value
// LLColor4 mSpecular; // specular color (always white for now)
F32 mShiny; // shiny value
LLPointer<LLGLTexture> mTexture; // ptr to a global texture
LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar
U32 mTestImageName; // handle to a temporary texture for previewing uploads
LLPolyMesh* mMesh; // ptr to a global polymesh
BOOL mCullBackFaces; // true by default
LLFace* mFace; // ptr to a face w/ AGP copy of mesh
U32 mFaceIndexCount;
U32 mNumSkinJoints;
LLSkinJoint* mSkinJoints;
S32 mMeshID;
public:
static BOOL sPipelineRender;
//RN: this is here for testing purposes
static U32 sClothingMaskImageName;
static EAvatarRenderPass sRenderPass;
static LLColor4 sClothingInnerColor;
public:
// Constructor
LLAvatarJointMesh();
// Destructor
virtual ~LLAvatarJointMesh();
// Gets the shape color
void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
// Sets the shape color
void setColor( F32 red, F32 green, F32 blue, F32 alpha );
void setColor( const LLColor4& color );
// Sets the shininess
void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
// Sets the shape texture
void setTexture( LLGLTexture *texture );
BOOL hasGLTexture() const;
void setTestTexture( U32 name ) { mTestImageName = name; }
// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
void setLayerSet( LLTexLayerSet* layer_set );
BOOL hasComposite() const;
// Gets the poly mesh
LLPolyMesh *getMesh();
// Sets the poly mesh
void setMesh( LLPolyMesh *mesh );
// Sets up joint matrix data for rendering
void setupJoint(LLAvatarJoint* current_joint);
// Sets ID for picking
void setMeshID( S32 id ) {mMeshID = id;}
// Gets ID for picking
S32 getMeshID() { return mMeshID; }
void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
private:
// Allocate skin data
BOOL allocateSkinData( U32 numSkinJoints );
// Free skin data
void freeSkinData();
};
#endif // LL_LLAVATARJOINTMESH_H

View File

@@ -24,22 +24,20 @@
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
#include "lldriverparam.h"
#include "llfasttimer.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llagent.h"
#include "llavatarappearance.h"
#include "llwearable.h"
#include "llagentwearables.h"
#include "llwearabledata.h"
//-----------------------------------------------------------------------------
// LLDriverParamInfo
//-----------------------------------------------------------------------------
LLDriverParamInfo::LLDriverParamInfo()
LLDriverParamInfo::LLDriverParamInfo() :
mDriverParam(NULL)
{
}
@@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out)
out << std::endl;
if(isAgentAvatarValid())
if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() &&
mDriverParam->getAvatarAppearance()->isValid())
{
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
{
LLDrivenEntryInfo driven = *iter;
LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
LLViewerVisualParam *param =
(LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);
if (param)
{
param->getInfo()->toStream(out);
@@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out)
}
else
{
llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl;
llwarns << "could not get parameter " << driven.mDrivenID << " from avatar "
<< mDriverParam->getAvatarAppearance()
<< " for driver parameter " << getID() << llendl;
}
out << std::endl;
}
@@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out)
// LLDriverParam
//-----------------------------------------------------------------------------
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
mCurrentDistortionParam( NULL ),
mAvatarp(avatarp),
mWearablep(NULL)
{
mDefaultVec.clear();
}
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
mCurrentDistortionParam( NULL ),
mAvatarp(NULL),
mWearablep(wearablep)
mAvatarAppearance(appearance),
mWearablep(wearable)
{
llassert(mAvatarAppearance);
if (mWearablep)
{
llassert(mAvatarAppearance->isSelf());
}
mDefaultVec.clear();
}
@@ -177,49 +176,22 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
return FALSE;
mInfo = info;
mID = info->mID;
info->mDriverParam = this;
setWeight(getDefaultWeight(), FALSE );
return TRUE;
}
void LLDriverParam::setWearable(LLWearable *wearablep)
{
if (wearablep)
{
mWearablep = wearablep;
mAvatarp = NULL;
}
}
void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
{
if (avatarp)
{
mWearablep = NULL;
mAvatarp = avatarp;
}
}
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
{
LLDriverParam *new_param;
if (wearable)
{
new_param = new LLDriverParam(wearable);
}
else
{
if (mWearablep)
{
new_param = new LLDriverParam(mWearablep);
}
else
{
new_param = new LLDriverParam(mAvatarp);
}
}
llassert(wearable);
LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
// FIXME DRANO this clobbers mWearablep, which means any code
// currently using mWearablep is wrong, or at least untested.
*new_param = *this;
//new_param->mWearablep = wearable;
// new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables.
return new_param;
}
@@ -456,6 +428,20 @@ const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly
return v;
};
S32 LLDriverParam::getDrivenParamsCount() const
{
return mDriven.size();
}
const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const
{
if (0 > index || index >= (S32)mDriven.size())
{
return NULL;
}
return mDriven[index].mParam;
}
//-----------------------------------------------------------------------------
// setAnimationTarget()
//-----------------------------------------------------------------------------
@@ -511,6 +497,7 @@ BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross
if (!found)
{
LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
if (param) param->setParamLocation(this->getParamLocation());
bool push = param && (!only_cross_params || param->getCrossWearable());
if (push)
{
@@ -555,7 +542,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
// Thus this wearable needs to get updates from the driver wearable.
// The call to setVisualParamWeight seems redundant, but is necessary
// as the number of driven wearables has changed since the last update. -Nyx
LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
if (wearable)
{
wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
@@ -623,13 +610,22 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
{
if(isAgentAvatarValid() &&
mWearablep &&
driven->mParam->getCrossWearable() &&
mWearablep->isOnTop())
bool use_self = false;
if(mWearablep &&
mAvatarAppearance->isValid() &&
driven->mParam->getCrossWearable())
{
LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep);
if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
{
use_self = true;
}
}
if (use_self)
{
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
}
else
{

View File

@@ -30,8 +30,8 @@
#include "llviewervisualparam.h"
#include "llwearabletype.h"
class LLPhysicsMotion;
class LLVOAvatar;
class LLAvatarAppearance;
class LLDriverParam;
class LLWearable;
//-----------------------------------------------------------------------------
@@ -71,25 +71,39 @@ public:
protected:
typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
entry_info_list_t mDrivenInfoList;
LLDriverParam* mDriverParam; // backpointer
};
//-----------------------------------------------------------------------------
class LLDriverParam : public LLViewerVisualParam
{
friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
friend class LLPhysicsMotion;
private:
// Hide the default constructor. Force construction with LLAvatarAppearance.
LLDriverParam() {}
public:
LLDriverParam(LLVOAvatar *avatarp);
LLDriverParam(LLWearable *wearablep);
LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
~LLDriverParam();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
// Special: These functions are overridden by child classes
LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; }
// This sets mInfo and calls initialization functions
BOOL setInfo(LLDriverParamInfo *info);
void setWearable(LLWearable *wearablep);
void setAvatar(LLVOAvatar *avatarp);
LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
void updateCrossDrivenParams(LLWearableType::EType driven_type);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
@@ -111,6 +125,9 @@ public:
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
S32 getDrivenParamsCount() const;
const LLViewerVisualParam* getDrivenParam(S32 index) const;
protected:
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
@@ -121,7 +138,7 @@ protected:
entry_list_t mDriven;
LLViewerVisualParam* mCurrentDistortionParam;
// Backlink only; don't make this an LLPointer.
LLVOAvatar* mAvatarp;
LLAvatarAppearance* mAvatarAppearance;
LLWearable* mWearablep;
};

View File

@@ -1,8 +1,8 @@
/**
* @file llhttpclientadepter.h
* @brief
* @file lljointpickname.h
* @brief Defines OpenGL seleciton stack names
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
@@ -24,20 +24,26 @@
* $/LicenseInfo$
*/
#ifndef LL_HTTPCLIENTADAPTER_H
#define LL_HTTPCLIENTADAPTER_H
#include "llhttpclientinterface.h"
#include "llsingleton.h" // LLSingleton<>
#ifndef LL_LLJOINTPICKNAME_H
#define LL_LLJOINTPICKNAME_H
class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter>
class LLAvatarJointMesh;
// Sets the OpenGL selection stack name that is pushed and popped
// with this joint state. The default value indicates that no name
// should be pushed/popped.
enum LLJointPickName
{
public:
virtual ~LLHTTPClientAdapter();
virtual void get(const std::string& url, LLCurl::ResponderPtr responder);
virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers);
virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder);
PN_DEFAULT = -1,
PN_0 = 0,
PN_1 = 1,
PN_2 = 2,
PN_3 = 3,
PN_4 = 4,
PN_5 = 5
};
#endif
typedef std::vector<LLAvatarJointMesh*> avatar_joint_mesh_list_t;
#endif // LL_LLJOINTPICKNAME_H

View File

@@ -23,13 +23,14 @@
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
#include "lllocaltextureobject.h"
#include "llimage.h"
#include "llrender.h"
#include "lltexlayer.h"
#include "llviewertexture.h"
#include "lltextureentry.h"
#include "llgltexture.h"
#include "lluuid.h"
#include "llwearable.h"
@@ -41,7 +42,7 @@ LLLocalTextureObject::LLLocalTextureObject() :
mImage = NULL;
}
LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) :
mIsBakedReady(FALSE),
mDiscard(MAX_DISCARD_LEVEL+1)
{
@@ -77,7 +78,7 @@ LLLocalTextureObject::~LLLocalTextureObject()
{
}
LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
LLGLTexture* LLLocalTextureObject::getImage() const
{
return mImage;
}
@@ -126,7 +127,7 @@ BOOL LLLocalTextureObject::getBakedReady() const
return mIsBakedReady;
}
void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
void LLLocalTextureObject::setImage(LLGLTexture* new_image)
{
mImage = new_image;
}

View File

@@ -29,11 +29,10 @@
#include <boost/shared_ptr.hpp>
#include "llviewertexture.h"
#include "llpointer.h"
#include "llgltexture.h"
class LLUUID;
class LLTexLayer;
class LLTextureEntry;
class LLTexLayerTemplate;
class LLWearable;
@@ -44,11 +43,11 @@ class LLLocalTextureObject
{
public:
LLLocalTextureObject();
LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
LLLocalTextureObject(LLGLTexture* image, const LLUUID& id);
LLLocalTextureObject(const LLLocalTextureObject& lto);
~LLLocalTextureObject();
LLViewerFetchedTexture* getImage() const;
LLGLTexture* getImage() const;
LLTexLayer* getTexLayer(U32 index) const;
LLTexLayer* getTexLayer(const std::string &name);
U32 getNumTexLayers() const;
@@ -56,7 +55,7 @@ public:
S32 getDiscard() const;
BOOL getBakedReady() const;
void setImage(LLViewerFetchedTexture* new_image);
void setImage(LLGLTexture* new_image);
BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
@@ -70,7 +69,7 @@ protected:
private:
LLPointer<LLViewerFetchedTexture> mImage;
LLPointer<LLGLTexture> mImage;
// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
// using shared pointers here only for smart assignment & cleanup
// do NOT create new shared pointers to these objects, or keep pointers to them around

View File

@@ -27,25 +27,24 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
#include "llpolymesh.h"
#include "llfasttimer.h"
#include "llmemory.h"
#include "llviewercontrol.h"
//#include "llviewercontrol.h"
#include "llxmltree.h"
#include "llvoavatar.h"
#include "llwearable.h"
#include "llavatarappearance.h"
//#include "llwearable.h"
#include "lldir.h"
#include "llvolume.h"
#include "llendianswizzle.h"
#include "llpolymesh.h"
#define HEADER_ASCII "Linden Mesh 1.0"
#define HEADER_BINARY "Linden Binary Mesh 1.0"
extern LLControlGroup gSavedSettings; // read only
//extern LLControlGroup gSavedSettings; // read only
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
const std::string &name);
@@ -125,28 +124,28 @@ void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
//-----------------------------------------------------------------------------
void LLPolyMeshSharedData::freeMeshData()
{
if (!mReferenceData)
{
mNumVertices = 0;
if (!mReferenceData)
{
mNumVertices = 0;
delete [] mBaseCoords;
mBaseCoords = NULL;
ll_aligned_free_16(mBaseCoords);
mBaseCoords = NULL;
delete [] mBaseNormals;
mBaseNormals = NULL;
ll_aligned_free_16(mBaseNormals);
mBaseNormals = NULL;
delete [] mBaseBinormals;
mBaseBinormals = NULL;
ll_aligned_free_16(mBaseBinormals);
mBaseBinormals = NULL;
delete [] mTexCoords;
mTexCoords = NULL;
ll_aligned_free_16(mTexCoords);
mTexCoords = NULL;
delete [] mDetailTexCoords;
mDetailTexCoords = NULL;
ll_aligned_free_16(mDetailTexCoords);
mDetailTexCoords = NULL;
delete [] mWeights;
mWeights = NULL;
}
ll_aligned_free_16(mWeights);
mWeights = NULL;
}
mNumFaces = 0;
delete [] mFaces;
@@ -228,14 +227,14 @@ U32 LLPolyMeshSharedData::getNumKB()
//-----------------------------------------------------------------------------
BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
{
U32 i;
mBaseCoords = new LLVector4a[ numVertices ];
mBaseNormals = new LLVector4a[ numVertices ];
mBaseBinormals = new LLVector4a[ numVertices ];
mTexCoords = new LLVector2[ numVertices ];
mDetailTexCoords = new LLVector2[ numVertices ];
mWeights = new F32[ numVertices ];
for (i = 0; i < numVertices; i++)
U32 i;
mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32));
for (i = 0; i < numVertices; i++)
{
mBaseCoords[i].clear();
mBaseNormals[i].clear();
@@ -1492,7 +1491,7 @@ BOOL LLPolyMesh::setSharedFromCurrent()
std::vector< LLCharacter* >::iterator avatar_it;
for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
{
LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
LLAvatarAppearance* avatarp = (LLAvatarAppearance*)*avatar_it;
LLPolyMesh* mesh = avatarp->getMesh(mSharedData);
if (mesh)
{
@@ -1770,246 +1769,4 @@ F32* LLPolyMesh::getWritableWeights() const
return mSharedData->mWeights;
}
//-----------------------------------------------------------------------------
// LLPolySkeletalDistortionInfo()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
{
}
BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
{
llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
if (!LLViewerVisualParamInfo::parseXml(node))
return FALSE;
LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
if (NULL == skeletalParam)
{
llwarns << "Failed to getChildByName(\"param_skeleton\")"
<< llendl;
return FALSE;
}
for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
{
if (bone->hasName("bone"))
{
std::string name;
LLVector3 scale;
LLVector3 pos;
BOOL haspos = FALSE;
static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
if (!bone->getFastAttributeString(name_string, name))
{
llwarns << "No bone name specified for skeletal param." << llendl;
continue;
}
static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
if (!bone->getFastAttributeVector3(scale_string, scale))
{
llwarns << "No scale specified for bone " << name << "." << llendl;
continue;
}
// optional offset deformation (translation)
static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
if (bone->getFastAttributeVector3(offset_string, pos))
{
haspos = TRUE;
}
mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
}
else
{
llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
continue;
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
{
mAvatar = avatarp;
mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
// ~LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
{
}
BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
{
llassert(mInfo == NULL);
if (info->mID < 0)
return FALSE;
mInfo = info;
mID = info->mID;
setWeight(getDefaultWeight(), FALSE );
LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
{
LLPolySkeletalBoneInfo *bone_info = &(*iter);
LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
if (!joint)
{
llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
continue;
}
if (mJointScales.find(joint) != mJointScales.end())
{
llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
}
// store it
mJointScales[joint] = bone_info->mScaleDeformation;
// apply to children that need to inherit it
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
if (child_joint->inheritScale())
{
LLVector3 childDeformation = LLVector3(child_joint->getScale());
childDeformation.scaleVec(bone_info->mScaleDeformation);
mJointScales[child_joint] = childDeformation;
}
}
if (bone_info->mHasPositionDeformation)
{
if (mJointOffsets.find(joint) != mJointOffsets.end())
{
llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
}
mJointOffsets[joint] = bone_info->mPositionDeformation;
}
}
return TRUE;
}
/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
{
LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
*new_param = *this;
return new_param;
}
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
void LLPolySkeletalDistortion::apply( ESex avatar_sex )
{
F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
LLJoint* joint;
joint_vec_map_t::iterator iter;
for (iter = mJointScales.begin();
iter != mJointScales.end();
iter++)
{
joint = iter->first;
LLVector3 newScale = joint->getScale();
LLVector3 scaleDelta = iter->second;
newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
joint->setScale(newScale);
}
for (iter = mJointOffsets.begin();
iter != mJointOffsets.end();
iter++)
{
joint = iter->first;
LLVector3 newPosition = joint->getPosition();
LLVector3 positionDelta = iter->second;
newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
joint->setPosition(newPosition);
}
if (mLastWeight != mCurWeight && !mIsAnimating)
{
mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
}
mLastWeight = mCurWeight;
}
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
cloned_morph_data->mCoords[v] = src_data->mCoords[v];
cloned_morph_data->mNormals[v] = src_data->mNormals[v];
cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
}
return cloned_morph_data;
}
LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
const LLVector3 &direction,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
LLVector4a dir;
dir.load3(direction.mV);
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
cloned_morph_data->mCoords[v] = dir;
cloned_morph_data->mNormals[v].clear();
cloned_morph_data->mBinormals[v].clear();
}
return cloned_morph_data;
}
LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
F32 scale,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
LLVector4a sc;
sc.splat(scale);
LLVector4a nsc;
nsc.set(scale, -scale, scale, scale);
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
if (cloned_morph_data->mCoords[v][1] < 0)
{
cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
}
else
{
cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
}
}
return cloned_morph_data;
}
// End

View File

@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
#ifndef LL_LLPOLYMESH_H
#define LL_LLPOLYMESH_H
#ifndef LL_LLPOLYMESHINTERFACE_H
#define LL_LLPOLYMESHINTERFACE_H
#include <string>
#include <map>
@@ -39,7 +39,7 @@
//#include "lldarray.h"
class LLSkinJoint;
class LLVOAvatar;
class LLAvatarAppearance;
class LLWearable;
//#define USE_STRIPS // Use tri-strips for rendering.
@@ -340,8 +340,8 @@ public:
BOOL isLOD() { return mSharedData && mSharedData->isLOD(); }
void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
LLVOAvatar* getAvatar() { return mAvatarp; }
void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; }
LLAvatarAppearance* getAvatar() { return mAvatarp; }
LLDynamicArray<LLJointRenderData*> mJointRenderData;
@@ -384,77 +384,8 @@ protected:
static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
// Backlink only; don't make this an LLPointer.
LLVOAvatar* mAvatarp;
LLAvatarAppearance* mAvatarp;
};
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformationInfo
// Shared information for LLPolySkeletalDeformations
//-----------------------------------------------------------------------------
struct LLPolySkeletalBoneInfo
{
LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
: mBoneName(name),
mScaleDeformation(scale),
mPositionDeformation(pos),
mHasPositionDeformation(haspos) {}
std::string mBoneName;
LLVector3 mScaleDeformation;
LLVector3 mPositionDeformation;
BOOL mHasPositionDeformation;
};
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
friend class LLPolySkeletalDistortion;
public:
LLPolySkeletalDistortionInfo();
/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList;
};
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
class LLPolySkeletalDistortion : public LLViewerVisualParam
{
public:
LLPolySkeletalDistortion(LLVOAvatar *avatarp);
~LLPolySkeletalDistortion();
// Special: These functions are overridden by child classes
LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
// This sets mInfo and calls initialization functions
BOOL setInfo(LLPolySkeletalDistortionInfo *info);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex sex );
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 0.1f; }
/*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; }
/*virtual*/ F32 getMaxDistortion() { return 0.1f; }
/*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
protected:
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
LLVector4a mDefaultVec;
// Backlink only; don't make this an LLPointer.
LLVOAvatar *mAvatar;
};
#endif // LL_LLPOLYMESH_H
#endif // LL_LLPOLYMESHINTERFACE_H

View File

@@ -27,13 +27,15 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "llviewerprecompiledheaders.h"
#include "llpolymorph.h"
#include "llvoavatar.h"
#include "llwearable.h"
#include "llavatarappearance.h"
#include "llavatarjoint.h"
//#include "llwearable.h"
#include "llxmltree.h"
#include "llendianswizzle.h"
#include "llpolymesh.h"
#include "v2math.h"
//#include "../tools/imdebug/imdebug.h"
@@ -74,9 +76,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
{
const S32 numVertices = mNumIndices;
mCoords = new LLVector4a[numVertices];
mNormals = new LLVector4a[numVertices];
mBinormals = new LLVector4a[numVertices];
mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mTexCoords = new LLVector2[numVertices];
mVertexIndices = new U32[numVertices];
@@ -90,17 +92,12 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
}
}
//-----------------------------------------------------------------------------
// ~LLPolyMorphData()
//-----------------------------------------------------------------------------
LLPolyMorphData::~LLPolyMorphData()
{
delete [] mVertexIndices;
delete [] mCoords;
delete [] mNormals;
delete [] mBinormals;
delete [] mTexCoords;
freeData();
}
//-----------------------------------------------------------------------------
@@ -119,12 +116,17 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
return FALSE;
}
//-------------------------------------------------------------------------
// free any existing data
//-------------------------------------------------------------------------
freeData();
//-------------------------------------------------------------------------
// allocate vertices
//-------------------------------------------------------------------------
mCoords = new LLVector4a[numVertices];
mNormals = new LLVector4a[numVertices];
mBinormals = new LLVector4a[numVertices];
mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mTexCoords = new LLVector2[numVertices];
// Actually, we are allocating more space than we need for the skiplist
mVertexIndices = new U32[numVertices];
@@ -207,6 +209,42 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
return TRUE;
}
//-----------------------------------------------------------------------------
// freeData()
//-----------------------------------------------------------------------------
void LLPolyMorphData::freeData()
{
if (mCoords != NULL)
{
ll_aligned_free_16(mCoords);
mCoords = NULL;
}
if (mNormals != NULL)
{
ll_aligned_free_16(mNormals);
mNormals = NULL;
}
if (mBinormals != NULL)
{
ll_aligned_free_16(mBinormals);
mBinormals = NULL;
}
if (mTexCoords != NULL)
{
delete [] mTexCoords;
mTexCoords = NULL;
}
if (mVertexIndices != NULL)
{
delete [] mVertexIndices;
mVertexIndices = NULL;
}
}
//-----------------------------------------------------------------------------
// LLPolyMesh::saveLLM()
//-----------------------------------------------------------------------------
@@ -354,9 +392,9 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
if (num_significant == 0)
nindices = 1;
LLVector4a* new_coords = new LLVector4a[nindices];
LLVector4a* new_normals = new LLVector4a[nindices];
LLVector4a* new_binormals = new LLVector4a[nindices];
LLVector4a* new_coords = static_cast<LLVector4a*>(ll_aligned_malloc_16(nindices * sizeof(LLVector4a)));
LLVector4a* new_normals = static_cast<LLVector4a*>(ll_aligned_malloc_16(nindices * sizeof(LLVector4a)));
LLVector4a* new_binormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(nindices * sizeof(LLVector4a)));
LLVector2* new_tex_coords = new LLVector2[nindices];
U32* new_vertex_indices = new U32[nindices];
@@ -426,7 +464,7 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
std::vector< LLCharacter* >::iterator avatar_it;
for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
{
LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
LLAvatarAppearance* avatarp = (LLAvatarAppearance*)*avatar_it;
LLPolyMorphTarget* param = (LLPolyMorphTarget*) avatarp->getVisualParam(mName.c_str());
if (!param)
@@ -490,11 +528,7 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
//-------------------------------------------------------------------------
// reallocate vertices
//-------------------------------------------------------------------------
delete [] mVertexIndices;
delete [] mCoords;
delete [] mNormals;
delete [] mBinormals;
delete [] mTexCoords;
freeData();
mVertexIndices = new_vertex_indices;
mCoords = new_coords;
@@ -601,7 +635,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
mID = info->mID;
setWeight(getDefaultWeight(), FALSE );
LLVOAvatar* avatarp = mMesh->getAvatar();
LLAvatarAppearance* avatarp = mMesh->getAvatar();
LLPolyMorphTargetInfo::volume_info_list_t::iterator iter;
for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
{
@@ -781,6 +815,8 @@ F32 LLPolyMorphTarget::getMaxDistortion()
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph");
void LLPolyMorphTarget::apply( ESex avatar_sex )
{
if (!mMorphData || mNumMorphMasksPending > 0)
@@ -788,6 +824,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
return;
}
LLFastTimer t(FTM_APPLY_MORPH_TARGET);
mLastSex = avatar_sex;
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.

View File

@@ -2,31 +2,25 @@
* @file llpolymorph.h
* @brief Implementation of LLPolyMesh class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -38,10 +32,10 @@
#include "llviewervisualparam.h"
class LLAvatarJointCollisionVolume;
class LLPolyMeshSharedData;
class LLVOAvatar;
class LLVector2;
class LLViewerJointCollisionVolume;
class LLAvatarJointCollisionVolume;
class LLWearable;
//-----------------------------------------------------------------------------
@@ -54,6 +48,16 @@ public:
~LLPolyMorphData();
LLPolyMorphData(const LLPolyMorphData &rhs);
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh);
const std::string& getName() { return mName; }
@@ -77,6 +81,9 @@ public:
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
LLPolyMeshSharedData* mMesh;
private:
void freeData();
};
//-----------------------------------------------------------------------------
@@ -114,10 +121,10 @@ struct LLPolyVolumeMorphInfo
struct LLPolyVolumeMorph
{
LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
: mVolume(volume), mScale(scale), mPos(pos) {};
LLViewerJointCollisionVolume* mVolume;
LLAvatarJointCollisionVolume* mVolume;
LLVector3 mScale;
LLVector3 mPos;
};

View File

@@ -0,0 +1,293 @@
/**
* @file llpolyskeletaldistortion.cpp
* @brief Implementation of LLPolySkeletalDistortion classes
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "llpreprocessor.h"
#include "llerrorlegacy.h"
//#include "llcommon.h"
//#include "llmemory.h"
#include "llavatarappearance.h"
#include "llavatarjoint.h"
#include "llpolymorph.h"
//#include "llviewercontrol.h"
//#include "llxmltree.h"
//#include "llvoavatar.h"
//#include "llwearable.h"
//#include "lldir.h"
//#include "llvolume.h"
//#include "llendianswizzle.h"
#include "llpolyskeletaldistortion.h"
//-----------------------------------------------------------------------------
// LLPolySkeletalDistortionInfo()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
{
}
BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
{
llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
if (!LLViewerVisualParamInfo::parseXml(node))
return FALSE;
LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
if (NULL == skeletalParam)
{
llwarns << "Failed to getChildByName(\"param_skeleton\")"
<< llendl;
return FALSE;
}
for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
{
if (bone->hasName("bone"))
{
std::string name;
LLVector3 scale;
LLVector3 pos;
BOOL haspos = FALSE;
static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
if (!bone->getFastAttributeString(name_string, name))
{
llwarns << "No bone name specified for skeletal param." << llendl;
continue;
}
static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
if (!bone->getFastAttributeVector3(scale_string, scale))
{
llwarns << "No scale specified for bone " << name << "." << llendl;
continue;
}
// optional offset deformation (translation)
static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
if (bone->getFastAttributeVector3(offset_string, pos))
{
haspos = TRUE;
}
mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
}
else
{
llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
continue;
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp)
{
mAvatar = avatarp;
mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
// ~LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
{
}
BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
{
llassert(mInfo == NULL);
if (info->mID < 0)
return FALSE;
mInfo = info;
mID = info->mID;
setWeight(getDefaultWeight(), FALSE );
LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
{
LLPolySkeletalBoneInfo *bone_info = &(*iter);
LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
if (!joint)
{
llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
continue;
}
if (mJointScales.find(joint) != mJointScales.end())
{
llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
}
// store it
mJointScales[joint] = bone_info->mScaleDeformation;
// apply to children that need to inherit it
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
if (child_joint->inheritScale())
{
LLVector3 childDeformation = LLVector3(child_joint->getScale());
childDeformation.scaleVec(bone_info->mScaleDeformation);
mJointScales[child_joint] = childDeformation;
}
}
if (bone_info->mHasPositionDeformation)
{
if (mJointOffsets.find(joint) != mJointOffsets.end())
{
llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
}
mJointOffsets[joint] = bone_info->mPositionDeformation;
}
}
return TRUE;
}
/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
{
LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
*new_param = *this;
return new_param;
}
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
void LLPolySkeletalDistortion::apply( ESex avatar_sex )
{
LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
LLJoint* joint;
joint_vec_map_t::iterator iter;
for (iter = mJointScales.begin();
iter != mJointScales.end();
iter++)
{
joint = iter->first;
LLVector3 newScale = joint->getScale();
LLVector3 scaleDelta = iter->second;
newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
joint->setScale(newScale);
}
for (iter = mJointOffsets.begin();
iter != mJointOffsets.end();
iter++)
{
joint = iter->first;
LLVector3 newPosition = joint->getPosition();
LLVector3 positionDelta = iter->second;
newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
joint->setPosition(newPosition);
}
if (mLastWeight != mCurWeight && !mIsAnimating)
{
mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
}
mLastWeight = mCurWeight;
}
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
cloned_morph_data->mCoords[v] = src_data->mCoords[v];
cloned_morph_data->mNormals[v] = src_data->mNormals[v];
cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
}
return cloned_morph_data;
}
LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
const LLVector3 &direction,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
LLVector4a dir;
dir.load3(direction.mV);
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
cloned_morph_data->mCoords[v] = dir;
cloned_morph_data->mNormals[v].clear();
cloned_morph_data->mBinormals[v].clear();
}
return cloned_morph_data;
}
LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
F32 scale,
const std::string &name)
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
LLVector4a sc;
sc.splat(scale);
LLVector4a nsc;
nsc.set(scale, -scale, scale, scale);
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
if (cloned_morph_data->mCoords[v][1] < 0)
{
cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
}
else
{
cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
}
}
return cloned_morph_data;
}
// End

View File

@@ -0,0 +1,130 @@
/**
* @file llpolyskeletaldistortion.h
* @brief Implementation of LLPolyMesh class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLPOLYSKELETALDISTORTION_H
#define LL_LLPOLYSKELETALDISTORTION_H
#include "llcommon.h"
#include <string>
#include <map>
#include "llstl.h"
#include "v3math.h"
#include "v2math.h"
#include "llquaternion.h"
//#include "llpolymorph.h"
#include "lljoint.h"
#include "llviewervisualparam.h"
//#include "lldarray.h"
//class LLSkinJoint;
class LLAvatarAppearance;
//#define USE_STRIPS // Use tri-strips for rendering.
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformationInfo
// Shared information for LLPolySkeletalDeformations
//-----------------------------------------------------------------------------
struct LLPolySkeletalBoneInfo
{
LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
: mBoneName(name),
mScaleDeformation(scale),
mPositionDeformation(pos),
mHasPositionDeformation(haspos) {}
std::string mBoneName;
LLVector3 mScaleDeformation;
LLVector3 mPositionDeformation;
BOOL mHasPositionDeformation;
};
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
friend class LLPolySkeletalDistortion;
public:
LLPolySkeletalDistortionInfo();
/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList;
};
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
class LLPolySkeletalDistortion : public LLViewerVisualParam
{
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLPolySkeletalDistortion(LLAvatarAppearance *avatarp);
~LLPolySkeletalDistortion();
// Special: These functions are overridden by child classes
LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
// This sets mInfo and calls initialization functions
BOOL setInfo(LLPolySkeletalDistortionInfo *info);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex sex );
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 0.1f; }
/*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; }
/*virtual*/ F32 getMaxDistortion() { return 0.1f; }
/*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
protected:
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
LLVector4a mDefaultVec;
// Backlink only; don't make this an LLPointer.
LLAvatarAppearance *mAvatar;
};
#endif // LL_LLPOLYSKELETALDISTORTION_H

View File

@@ -24,20 +24,20 @@
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "linden_common.h"
#include "llavatarappearance.h"
#include "lltexlayer.h"
#include "llvoavatar.h"
#include "llwearable.h"
#include "lltexglobalcolor.h"
class LLWearable;
//-----------------------------------------------------------------------------
// LLTexGlobalColor
//-----------------------------------------------------------------------------
LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar)
LLTexGlobalColor::LLTexGlobalColor(LLAvatarAppearance* appearance)
:
mAvatar(avatar),
mAvatarAppearance(appearance),
mInfo(NULL)
{
}
@@ -91,7 +91,7 @@ const std::string& LLTexGlobalColor::getName() const
// LLTexParamGlobalColor
//-----------------------------------------------------------------------------
LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
LLTexLayerParamColor(tex_global_color->getAvatar()),
LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
mTexGlobalColor(tex_global_color)
{
}
@@ -105,7 +105,7 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
{
mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
mAvatarAppearance->onGlobalColorChanged(mTexGlobalColor, upload_bake);
}
//-----------------------------------------------------------------------------

View File

@@ -1,6 +1,6 @@
/**
* @file lltexglobalcolor.h
* @brief This is global texture color info used by llvoavatar.
* @brief This is global texture color info used by llavatarappearance.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -30,31 +30,31 @@
#include "lltexlayer.h"
#include "lltexlayerparams.h"
class LLVOAvatar;
class LLAvatarAppearance;
class LLWearable;
class LLTexGlobalColorInfo;
class LLTexGlobalColor
{
public:
LLTexGlobalColor( LLVOAvatar* avatar );
LLTexGlobalColor( LLAvatarAppearance* appearance );
~LLTexGlobalColor();
LLTexGlobalColorInfo* getInfo() const { return mInfo; }
// This sets mInfo and calls initialization functions
BOOL setInfo(LLTexGlobalColorInfo *info);
LLVOAvatar* getAvatar() const { return mAvatar; }
LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
LLColor4 getColor() const;
const std::string& getName() const;
private:
param_color_list_t mParamGlobalColorList;
LLVOAvatar* mAvatar; // just backlink, don't LLPointer
LLAvatarAppearance* mAvatarAppearance; // just backlink, don't LLPointer
LLTexGlobalColorInfo *mInfo;
};
// Used by llvoavatar to determine skin/eye/hair color.
// Used by llavatarappearance to determine skin/eye/hair color.
class LLTexGlobalColorInfo
{
friend class LLTexGlobalColor;

View File

@@ -28,14 +28,15 @@
#define LL_LLTEXLAYER_H
#include <deque>
#include "lldynamictexture.h"
#include "llvoavatardefines.h"
#include "llglslshader.h"
#include "llgltexture.h"
#include "llavatarappearancedefines.h"
#include "lltexlayerparams.h"
class LLVOAvatar;
class LLVOAvatarSelf;
class LLAvatarAppearance;
class LLImageTGA;
class LLImageRaw;
class LLLocalTextureObject;
class LLXmlTreeNode;
class LLTexLayerSet;
class LLTexLayerSetInfo;
@@ -50,7 +51,7 @@ class LLViewerVisualParam;
// Interface class to generalize functionality shared by LLTexLayer
// and LLTexLayerTemplate.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLTexLayerInterface
class LLTexLayerInterface
{
public:
enum ERenderPass
@@ -71,6 +72,8 @@ public:
const LLTexLayerInfo* getInfo() const { return mInfo; }
virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
LLWearableType::EType getWearableType() const;
LLAvatarAppearanceDefines::ETextureIndex getLocalTextureIndex() const;
const std::string& getName() const;
const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; }
@@ -88,6 +91,8 @@ public:
ERenderPass getRenderPass() const;
BOOL isVisibilityMask() const;
virtual void asLLSD(LLSD& sd) const {}
protected:
const std::string& getGlobalColor() const;
LLViewerVisualParam* getVisualParamPtr(S32 index) const;
@@ -113,7 +118,7 @@ protected:
class LLTexLayerTemplate : public LLTexLayerInterface
{
public:
LLTexLayerTemplate(LLTexLayerSet* const layer_set);
LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance);
LLTexLayerTemplate(const LLTexLayerTemplate &layer);
/*virtual*/ ~LLTexLayerTemplate();
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
@@ -126,7 +131,9 @@ public:
protected:
U32 updateWearableCache() const;
LLTexLayer* getLayer(U32 i) const;
LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
private:
LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
typedef std::vector<LLWearable*> wearable_cache_t;
mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
};
@@ -160,10 +167,11 @@ public:
void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
LLLocalTextureObject* getLTO() { return mLocalTextureObject; }
/*virtual*/ void asLLSD(LLSD& sd) const;
static void calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
protected:
LLUUID getUUID() const;
private:
typedef std::map<U32, U8*> alpha_cache_t;
alpha_cache_t mAlphaCache;
LLLocalTextureObject* mLocalTextureObject;
@@ -179,8 +187,14 @@ class LLTexLayerSet
{
friend class LLTexLayerSetBuffer;
public:
LLTexLayerSet(LLVOAvatarSelf* const avatar);
~LLTexLayerSet();
LLTexLayerSet(LLAvatarAppearance* const appearance);
virtual ~LLTexLayerSet();
LLTexLayerSetBuffer* getComposite();
const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
virtual void createComposite() = 0;
void destroyComposite();
void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height);
const LLTexLayerSetInfo* getInfo() const { return mInfo; }
BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
@@ -189,45 +203,34 @@ public:
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
BOOL isBodyRegion(const std::string& region) const;
LLTexLayerSetBuffer* getComposite();
const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
void requestUpdate();
void requestUpload();
void cancelUpload();
void updateComposite();
BOOL isLocalTextureDataAvailable() const;
BOOL isLocalTextureDataFinal() const;
void createComposite();
void destroyComposite();
void setUpdatesEnabled(BOOL b);
BOOL getUpdatesEnabled() const { return mUpdatesEnabled; }
void deleteCaches();
void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
BOOL isMorphValid() const;
virtual void requestUpdate() = 0;
void invalidateMorphMasks();
void deleteCaches();
LLTexLayerInterface* findLayerByName(const std::string& name);
void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
void cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable* wearable);
LLVOAvatarSelf* getAvatar() const { return mAvatar; }
LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
const std::string getBodyRegionName() const;
BOOL hasComposite() const { return (mComposite.notNull()); }
LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() const { return mBakedTexIndex; }
void setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
BOOL isVisible() const { return mIsVisible; }
static BOOL sHasCaches;
private:
virtual void asLLSD(LLSD& sd) const;
protected:
typedef std::vector<LLTexLayerInterface *> layer_list_t;
layer_list_t mLayerList;
layer_list_t mMaskLayerList;
LLPointer<LLTexLayerSetBuffer> mComposite;
LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer.
BOOL mUpdatesEnabled;
LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
BOOL mIsVisible;
LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
LLAvatarAppearanceDefines::EBakedTextureIndex mBakedTexIndex;
const LLTexLayerSetInfo* mInfo;
};
@@ -243,8 +246,10 @@ public:
LLTexLayerSetInfo();
~LLTexLayerSetInfo();
BOOL parseXml(LLXmlTreeNode* node);
void createVisualParams(LLVOAvatar *avatar);
private:
void createVisualParams(LLAvatarAppearance *appearance);
S32 getWidth() const { return mWidth; }
S32 getHeight() const { return mHeight; }
protected:
std::string mBodyRegion;
S32 mWidth;
S32 mHeight;
@@ -259,78 +264,27 @@ private:
//
// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLTexLayerSetBuffer : public LLViewerDynamicTexture
class LLTexLayerSetBuffer : public virtual LLRefCount
{
LOG_CLASS(LLTexLayerSetBuffer);
public:
LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
LLTexLayerSetBuffer(LLTexLayerSet* const owner);
virtual ~LLTexLayerSetBuffer();
public:
/*virtual*/ S8 getType() const;
BOOL isInitialized(void) const;
static void dumpTotalByteCount();
const std::string dumpTextureInfo() const;
virtual void restoreGLTexture();
virtual void destroyGLTexture();
protected:
void pushProjection() const;
void popProjection() const;
private:
LLTexLayerSet* const mTexLayerSet;
static S32 sGLByteCount;
virtual void preRenderTexLayerSet();
virtual void midRenderTexLayerSet(BOOL success) {}
virtual void postRenderTexLayerSet(BOOL success);
virtual S32 getCompositeOriginX() const = 0;
virtual S32 getCompositeOriginY() const = 0;
virtual S32 getCompositeWidth() const = 0;
virtual S32 getCompositeHeight() const = 0;
BOOL renderTexLayerSet();
//--------------------------------------------------------------------
// Render
//--------------------------------------------------------------------
public:
/*virtual*/ BOOL needsRender();
protected:
BOOL render(S32 x, S32 y, S32 width, S32 height);
virtual void preRender(BOOL clear_depth);
virtual void postRender(BOOL success);
virtual BOOL render();
//--------------------------------------------------------------------
// Uploads
//--------------------------------------------------------------------
public:
void requestUpload();
void cancelUpload();
BOOL uploadNeeded() const; // We need to upload a new texture
BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
static void onTextureUploadComplete(const LLUUID& uuid,
void* userdata,
S32 result, LLExtStat ext_status);
protected:
BOOL isReadyToUpload() const;
void doUpload(); // Does a read back and upload.
void conditionalRestartUploadTimer();
private:
BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
BOOL mUploadPending; // Whether we have received back the new baked textures
LLUUID mUploadID; // The current upload process (null if none).
LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed.
S32 mUploadFailCount; // Number of consecutive upload failures
LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure.
//--------------------------------------------------------------------
// Updates
//--------------------------------------------------------------------
public:
void requestUpdate();
BOOL requestUpdateImmediate();
protected:
BOOL isReadyToUpdate() const;
void doUpdate();
void restartUpdateTimer();
private:
BOOL mNeedsUpdate; // Whether we need to locally update our baked textures
U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures
LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed.
LLTexLayerSet* const mTexLayerSet;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -342,7 +296,7 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
public:
LLTexLayerStaticImageList();
~LLTexLayerStaticImageList();
LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask);
LLGLTexture* getTexture(const std::string& file_name, BOOL is_mask);
LLImageTGA* getImageTGA(const std::string& file_name);
void deleteCachedImages();
void dumpByteCount() const;
@@ -350,7 +304,7 @@ protected:
BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
private:
LLStringTable mImageNames;
typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
typedef std::map<const char*, LLPointer<LLGLTexture> > texture_map_t;
texture_map_t mStaticImageList;
typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
image_tga_map_t mStaticImageListTGA;
@@ -358,23 +312,4 @@ private:
S32 mTGABytes;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLBakedUploadData
//
// Used by LLTexLayerSetBuffer for a callback.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct LLBakedUploadData
{
LLBakedUploadData(const LLVOAvatarSelf* avatar,
LLTexLayerSet* layerset,
const LLUUID& id,
bool highest_res);
~LLBakedUploadData() {}
const LLUUID mID;
const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer
LLTexLayerSet* mTexLayerSet;
const U64 mStartTime; // for measuring baked texture upload time
const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res
};
#endif // LL_LLTEXLAYER_H

View File

@@ -24,27 +24,27 @@
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
#include "lltexlayerparams.h"
#include "llagentcamera.h"
#include "llavatarappearance.h"
#include "llimagetga.h"
#include "llquantize.h"
#include "lltexlayer.h"
#include "llvoavatarself.h"
#include "lltexturemanagerbridge.h"
#include "llwearable.h"
#include "llui.h"
//-----------------------------------------------------------------------------
// LLTexLayerParam
//-----------------------------------------------------------------------------
LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
mTexLayer(layer),
mAvatar(NULL)
mAvatarAppearance(NULL)
{
if (mTexLayer != NULL)
{
mAvatar = mTexLayer->getTexLayerSet()->getAvatar();
mAvatarAppearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
}
else
{
@@ -52,20 +52,21 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
}
}
LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) :
mTexLayer(NULL)
LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) :
mTexLayer(NULL),
mAvatarAppearance(appearance)
{
mAvatar = avatar;
}
BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar )
{
BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)
{
LLViewerVisualParam::setInfo(info);
if (add_to_avatar)
if (add_to_appearance)
{
mAvatar->addVisualParam( this);
mAvatarAppearance->addVisualParam( this);
this->setParamLocation(mAvatarAppearance->isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
}
return TRUE;
@@ -96,7 +97,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
iter != sInstances.end(); iter++)
{
LLTexLayerParamAlpha* instance = *iter;
LLViewerTexture* tex = instance->mCachedProcessedTexture;
LLGLTexture* tex = instance->mCachedProcessedTexture;
if (tex)
{
S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
@@ -120,8 +121,8 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
sInstances.push_front(this);
}
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) :
LLTexLayerParam(avatar),
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
LLTexLayerParam(appearance),
mCachedProcessedTexture(NULL),
mNeedsCreateTexture(FALSE),
mStaticImageInvalid(FALSE),
@@ -173,13 +174,14 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
{
mCurWeight = new_weight;
if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
if ((mAvatarAppearance->getSex() & getSex()) &&
(mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
{
if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
if (mAvatarAppearance->isValid() && mAvatarAppearance->isEditingAppearance())
{
upload_bake = FALSE;
}
mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
mTexLayer->invalidateMorphMasks();
}
}
@@ -218,11 +220,11 @@ BOOL LLTexLayerParamAlpha::getSkip() const
return TRUE;
}
const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
const LLAvatarAppearance *appearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
{
F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
F32 effective_weight = (appearance->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
if (is_approx_zero(effective_weight))
{
return TRUE;
@@ -230,7 +232,7 @@ BOOL LLTexLayerParamAlpha::getSkip() const
}
LLWearableType::EType type = (LLWearableType::EType)getWearableType();
if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type))
if ((type != LLWearableType::WT_INVALID) && !appearance->isWearingWearableType(type))
{
return TRUE;
}
@@ -239,8 +241,10 @@ BOOL LLTexLayerParamAlpha::getSkip() const
}
static LLFastTimer::DeclareTimer FTM_TEX_LAYER_PARAM_ALPHA("alpha render");
BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
{
LLFastTimer t(FTM_TEX_LAYER_PARAM_ALPHA);
BOOL success = TRUE;
if (!mTexLayer)
@@ -248,7 +252,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
return success;
}
F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatarAppearance()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
if (getSkip())
{
@@ -290,12 +294,12 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
(mCachedProcessedTexture->getHeight() != image_tga_height) ||
(weight_changed))
{
// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
mCachedEffectiveWeight = effective_weight;
if (!mCachedProcessedTexture)
{
mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
llassert(gTextureManagerBridgep);
mCachedProcessedTexture = gTextureManagerBridgep->getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
// We now have something in one of our caches
LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
@@ -308,6 +312,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
mStaticImageRaw = new LLImageRaw;
mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
mNeedsCreateTexture = TRUE;
lldebugs << "Built Cached Alpha: " << info->mStaticImageFileName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << "Domain: " << info->mDomain << " Weight: " << effective_weight << llendl;
}
if (mCachedProcessedTexture)
@@ -332,7 +337,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
// Don't keep the cache for other people's avatars
// (It's not really a "cache" in that case, but the logic is the same)
if (!mAvatar->isSelf())
if (!mAvatarAppearance->isSelf())
{
mCachedProcessedTexture = NULL;
}
@@ -402,8 +407,8 @@ LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
{
}
LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) :
LLTexLayerParam(avatar),
LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) :
LLTexLayerParam(appearance),
mAvgDistortionVec(1.f, 1.f, 1.f)
{
}
@@ -425,7 +430,7 @@ LLColor4 LLTexLayerParamColor::getNetColor() const
llassert(info->mNumColors >= 1);
F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
F32 effective_weight = (mAvatarAppearance && (mAvatarAppearance->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
S32 index_last = info->mNumColors - 1;
F32 scaled_weight = effective_weight * index_last;
@@ -470,12 +475,12 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
return;
}
if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
if ((mAvatarAppearance->getSex() & getSex()) && (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
{
onGlobalColorChanged(upload_bake);
if (mTexLayer)
{
mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
}
}

View File

@@ -27,16 +27,22 @@
#ifndef LL_LLTEXLAYERPARAMS_H
#define LL_LLTEXLAYERPARAMS_H
#include "llpointer.h"
#include "v4color.h"
#include "llviewervisualparam.h"
class LLAvatarAppearance;
class LLImageRaw;
class LLImageTGA;
class LLTexLayer;
class LLTexLayerInterface;
class LLViewerTexture;
class LLVOAvatar;
class LLGLTexture;
class LLWearable;
//Temporary externs
void gl_rect_2d_simple_tex( S32 width, S32 height );
void gl_rect_2d_simple( S32 width, S32 height );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLTexLayerParam
//
@@ -45,13 +51,13 @@ class LLTexLayerParam : public LLViewerVisualParam
{
public:
LLTexLayerParam(LLTexLayerInterface *layer);
LLTexLayerParam(LLVOAvatar *avatar);
/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar );
LLTexLayerParam(LLAvatarAppearance *appearance);
/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
protected:
LLTexLayerInterface* mTexLayer;
LLVOAvatar* mAvatar;
LLAvatarAppearance* mAvatarAppearance;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -62,11 +68,21 @@ class LLTexLayerParamAlpha : public LLTexLayerParam
{
public:
LLTexLayerParamAlpha( LLTexLayerInterface* layer );
LLTexLayerParamAlpha( LLVOAvatar* avatar );
LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
/*virtual*/ ~LLTexLayerParamAlpha();
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex avatar_sex ) {}
@@ -89,7 +105,7 @@ public:
BOOL getMultiplyBlend() const;
private:
LLPointer<LLViewerTexture> mCachedProcessedTexture;
LLPointer<LLGLTexture> mCachedProcessedTexture;
LLPointer<LLImageTGA> mStaticImageTGA;
LLPointer<LLImageRaw> mStaticImageRaw;
BOOL mNeedsCreateTexture;
@@ -140,9 +156,19 @@ public:
};
LLTexLayerParamColor( LLTexLayerInterface* layer );
LLTexLayerParamColor( LLVOAvatar* avatar );
LLTexLayerParamColor( LLAvatarAppearance* appearance );
/* virtual */ ~LLTexLayerParamColor();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
// LLVisualParam Virtual functions

View File

@@ -1,8 +1,8 @@
/**
* @file llhttpclientinterface.h
* @brief
/**
* @file lltexturemanagerbridge.cpp
* @brief Defined a null texture manager bridge. Applications must provide their own bridge implementaton.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
@@ -24,22 +24,10 @@
* $/LicenseInfo$
*/
#ifndef LL_LLHTTPCLIENTINTERFACE_H
#define LL_LLHTTPCLIENTINTERFACE_H
#include "linden_common.h"
#include "llcurl.h"
#include "lltexturemanagerbridge.h"
#include <string>
// Define a null texture manager bridge. Applications must provide their own bridge implementaton.
LLTextureManagerBridge* gTextureManagerBridgep = NULL;
class LLHTTPClientInterface
{
public:
virtual ~LLHTTPClientInterface() {}
virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
};
#endif // LL_LLHTTPCLIENTINTERFACE_H

View File

@@ -0,0 +1,46 @@
/**
* @file lltexturemanagerbridge.h
* @brief Bridge to an application-specific texture manager.
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_TEXTUREMANAGERBRIDGE_H
#define LL_TEXTUREMANAGERBRIDGE_H
#include "llavatarappearancedefines.h"
#include "llpointer.h"
#include "llgltexture.h"
// Abstract bridge interface
class LLTextureManagerBridge
{
public:
virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
};
extern LLTextureManagerBridge* gTextureManagerBridgep;
#endif // LL_TEXTUREMANAGERBRIDGE_H

View File

@@ -2,42 +2,35 @@
* @file llviewervisualparam.cpp
* @brief Implementation of LLViewerVisualParam class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "llviewerprecompiledheaders.h"
#include "linden_common.h"
#include "llviewervisualparam.h"
#include "llxmltree.h"
#include "llui.h"
#include "llwearable.h"
//-----------------------------------------------------------------------------

View File

@@ -0,0 +1,820 @@
/**
* @file llwearable.cpp
* @brief LLWearable class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llavatarappearance.h"
#include "lllocaltextureobject.h"
#include "lltexlayer.h"
#include "lltexturemanagerbridge.h"
#include "llvisualparam.h"
#include "llavatarappearancedefines.h"
#include "llwearable.h"
using namespace LLAvatarAppearanceDefines;
// static
S32 LLWearable::sCurrentDefinitionVersion = 1;
// Private local functions
static std::string terse_F32_to_string(F32 f);
LLWearable::LLWearable() :
mDefinitionVersion(0),
mType(LLWearableType::WT_INVALID)
{
}
// virtual
LLWearable::~LLWearable()
{
}
const std::string& LLWearable::getTypeLabel() const
{
return LLWearableType::getTypeLabel(mType);
}
const std::string& LLWearable::getTypeName() const
{
return LLWearableType::getTypeName(mType);
}
LLAssetType::EType LLWearable::getAssetType() const
{
return LLWearableType::getAssetType(mType);
}
// reX: new function
BOOL LLWearable::FileExportParams( FILE* file ) const
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// parameters
S32 num_parameters = mVisualParamIndexMap.size();
fprintf( file, "parameters %d\n", num_parameters );
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end(); ++iter)
{
S32 param_id = iter->first;
F32 param_weight = iter->second->getWeight();
fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() );
}
return TRUE;
}
// reX: new function
BOOL LLWearable::FileExportTextures( FILE* file ) const
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// texture entries
S32 num_textures = mTEMap.size();
fprintf( file, "textures %d\n", num_textures );
for (te_map_t::const_iterator iter = mTEMap.begin();
iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() );
}
return TRUE;
}
BOOL LLWearable::exportFile(LLFILE* fp) const
{
llofstream ofs(fp);
return exportStream(ofs);
}
// virtual
BOOL LLWearable::exportStream( std::ostream& output_stream ) const
{
if (!output_stream.good()) return FALSE;
// header and version
output_stream << "LLWearable version " << mDefinitionVersion << "\n";
// name
output_stream << mName << "\n";
// description
output_stream << mDescription << "\n";
// permissions
if( !mPermissions.exportStream( output_stream ) )
{
return FALSE;
}
// sale info
if( !mSaleInfo.exportStream( output_stream ) )
{
return FALSE;
}
// wearable type
output_stream << "type " << (S32) getType() << "\n";
// parameters
output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
++iter)
{
S32 param_id = iter->first;
const LLVisualParam* param = iter->second;
F32 param_weight = param->getWeight();
output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";
}
// texture entries
output_stream << "textures " << mTEMap.size() << "\n";
for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
const LLUUID& image_id = iter->second->getID();
output_stream << te << " " << image_id << "\n";
}
return TRUE;
}
void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
{
for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam();
param;
param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
{
if (param->getWearableType() == mType)
{
LLVisualParam *clone_param = param->cloneParam(this);
clone_param->setParamLocation(LOC_UNKNOWN);
clone_param->setParamLocation(LOC_WEARABLE);
addVisualParam(clone_param);
}
}
// resync driver parameters to point to the newly cloned driven parameters
for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();
param_iter != mVisualParamIndexMap.end();
++param_iter)
{
LLVisualParam* param = param_iter->second;
LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;
// need this line to disambiguate between versions of LLCharacter::getVisualParam()
LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam;
param->resetDrivenParams();
if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
{
if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true))
{
llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
continue;
}
}
}
}
void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
{
LLTexLayerSet *layer_set = NULL;
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
if (texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
layer_set = avatarp->getAvatarLayerSet(baked_index);
}
if (layer_set)
{
layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
}
else
{
llerrs << "could not find layerset for LTO in wearable!" << llendl;
}
}
LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
{
llifstream ifs(fp);
return importStream(ifs, avatarp);
}
// virtual
LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
{
// *NOTE: changing the type or size of this buffer will require
// changes in the fscanf() code below.
// We are using a local max buffer size here to avoid issues
// if MAX_STRING size changes.
const U32 PARSE_BUFFER_SIZE = 2048;
char buffer[2048]; /* Flawfinder: ignore */
char uuid_buffer[37]; /* Flawfinder: ignore */
// This data is being generated on the viewer.
// Impose some sane limits on parameter and texture counts.
const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
if(!avatarp)
{
return LLWearable::FAILURE;
}
// read header and version
if (!input_stream.good())
{
llwarns << "Failed to read wearable asset input stream." << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
if ( 1 != sscanf( /* Flawfinder: ignore */
buffer,
"LLWearable version %d\n",
&mDefinitionVersion ) )
{
return LLWearable::BAD_HEADER;
}
// Hack to allow wearables with definition version 24 to still load.
// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
// the extra check for version == 24 can be removed before release, once internal testers
// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
// these wearables get re-saved with version definition 22.
if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
{
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
return LLWearable::FAILURE;
}
// name
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading name" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
mName = buffer;
// description
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading description" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
mDescription = buffer;
// permissions
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading permissions" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 perm_version = -1;
if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
perm_version != 0 )
{
llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
return LLWearable::FAILURE;
}
if( !mPermissions.importStream( input_stream ) )
{
return LLWearable::FAILURE;
}
// sale info
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading sale info" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 sale_info_version = -1;
if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
sale_info_version != 0 )
{
llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
return LLWearable::FAILURE;
}
// Sale info used to contain next owner perm. It is now in the
// permissions. Thus, we read that out, and fix legacy
// objects. It's possible this op would fail, but it should pick
// up the vast majority of the tasks.
BOOL has_perm_mask = FALSE;
U32 perm_mask = 0;
if( !mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask) )
{
return LLWearable::FAILURE;
}
if(has_perm_mask)
{
// fair use fix.
if(!(perm_mask & PERM_COPY))
{
perm_mask |= PERM_TRANSFER;
}
mPermissions.setMaskNext(perm_mask);
}
// wearable type
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading type" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 type = -1;
if ( 1 != sscanf( buffer, "type %d\n", &type ) )
{
llwarns << "Bad Wearable asset: bad type" << llendl;
return LLWearable::FAILURE;
}
if( 0 <= type && type < LLWearableType::WT_COUNT )
{
setType((LLWearableType::EType)type, avatarp);
}
else
{
mType = LLWearableType::WT_COUNT;
llwarns << "Bad Wearable asset: bad type #" << type << llendl;
return LLWearable::FAILURE;
}
// parameters header
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading parameters header" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 num_parameters = -1;
if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
{
llwarns << "Bad Wearable asset: missing parameters block" << llendl;
return LLWearable::FAILURE;
}
if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
{
llwarns << "Bad Wearable asset: too many parameters, "
<< num_parameters << llendl;
return LLWearable::FAILURE;
}
if( num_parameters != mVisualParamIndexMap.size() )
{
llwarns << "Wearable parameter mismatch. Reading in "
<< num_parameters << " from file, but created "
<< mVisualParamIndexMap.size()
<< " from avatar parameters. type: "
<< getType() << llendl;
}
// parameters
S32 i;
for( i = 0; i < num_parameters; i++ )
{
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading parameter #" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 param_id = 0;
F32 param_weight = 0.f;
if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
{
llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
return LLWearable::FAILURE;
}
mSavedVisualParamMap[param_id] = param_weight;
}
// textures header
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading textures header" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 num_textures = -1;
if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
{
llwarns << "Bad Wearable asset: missing textures block" << llendl;
return LLWearable::FAILURE;
}
if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
{
llwarns << "Bad Wearable asset: too many textures, "
<< num_textures << llendl;
return LLWearable::FAILURE;
}
// textures
for( i = 0; i < num_textures; i++ )
{
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading textures #" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 te = 0;
if ( 2 != sscanf( /* Flawfinder: ignore */
buffer,
"%d %36s\n",
&te, uuid_buffer) )
{
llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
return LLWearable::FAILURE;
}
if( !LLUUID::validate( uuid_buffer ) )
{
llwarns << "Bad Wearable asset: bad texture uuid: "
<< uuid_buffer << llendl;
return LLWearable::FAILURE;
}
LLUUID id = LLUUID(uuid_buffer);
LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );
if( mTEMap.find(te) != mTEMap.end() )
{
delete mTEMap[te];
}
if( mSavedTEMap.find(te) != mSavedTEMap.end() )
{
delete mSavedTEMap[te];
}
LLUUID textureid(uuid_buffer);
mTEMap[te] = new LLLocalTextureObject(image, textureid);
mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
createLayers(te, avatarp);
}
// copy all saved param values to working params
revertValues();
return LLWearable::SUCCESS;
}
void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp)
{
mType = type;
createVisualParams(avatarp);
}
LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
{
te_map_t::iterator iter = mTEMap.find(index);
if( iter != mTEMap.end() )
{
LLLocalTextureObject* lto = iter->second;
return lto;
}
return NULL;
}
const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
{
te_map_t::const_iterator iter = mTEMap.find(index);
if( iter != mTEMap.end() )
{
const LLLocalTextureObject* lto = iter->second;
return lto;
}
return NULL;
}
std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
{
std::vector<LLLocalTextureObject*> result;
for(te_map_t::const_iterator iter = mTEMap.begin();
iter != mTEMap.end(); iter++)
{
LLLocalTextureObject* lto = iter->second;
result.push_back(lto);
}
return result;
}
void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
{
if( mTEMap.find(index) != mTEMap.end() )
{
mTEMap.erase(index);
}
mTEMap[index] = new LLLocalTextureObject(lto);
}
void LLWearable::revertValues()
{
// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
//update saved settings so wearable is no longer dirty
// non-driver params first
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && !dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
//then driver params
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
// make sure that saved values are sane
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
LLVisualParam *param = getVisualParam(id);
if( param )
{
mSavedVisualParamMap[id] = param->getWeight();
}
}
syncImages(mSavedTEMap, mTEMap);
}
void LLWearable::saveValues()
{
//update saved settings so wearable is no longer dirty
mSavedVisualParamMap.clear();
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
{
S32 id = iter->first;
LLVisualParam *wearable_param = iter->second;
F32 value = wearable_param->getWeight();
mSavedVisualParamMap[id] = value;
}
// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
syncImages(mTEMap, mSavedTEMap);
}
void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
{
// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = src.find(te);
LLUUID image_id;
LLGLTexture *image = NULL;
LLLocalTextureObject *lto = NULL;
if(iter != src.end())
{
// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
lto = iter->second;
image = lto->getImage();
image_id = lto->getID();
}
else
{
// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
image_id = getDefaultTextureImageID((ETextureIndex) te);
image = gTextureManagerBridgep->getFetchedTexture( image_id );
}
if( dst.find(te) != dst.end() )
{
// there's already an entry in the destination map for the texture. Just update its values.
dst[te]->setImage(image);
dst[te]->setID(image_id);
}
else
{
// no entry found in the destination map, we need to create a new Local Texture Object
dst[te] = new LLLocalTextureObject(image, image_id);
}
if( lto )
{
// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
dst[te]->setBakedReady(lto->getBakedReady());
dst[te]->setDiscard(lto->getDiscard());
}
}
}
}
void LLWearable::destroyTextures()
{
for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mTEMap.clear();
for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mSavedTEMap.clear();
}
void LLWearable::addVisualParam(LLVisualParam *param)
{
if( mVisualParamIndexMap[param->getID()] )
{
delete mVisualParamIndexMap[param->getID()];
}
param->setIsDummy(FALSE);
param->setParamLocation(LOC_WEARABLE);
mVisualParamIndexMap[param->getID()] = param;
mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
}
void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
wearable_param->setWeight(value, upload_bake);
}
else
{
llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
}
F32 LLWearable::getVisualParamWeight(S32 param_index) const
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
return wearable_param->getWeight();
}
else
{
llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
return (F32)-1.0;
}
LLVisualParam* LLWearable::getVisualParam(S32 index) const
{
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
}
void LLWearable::getVisualParams(visual_param_vec_t &list)
{
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
// add all visual params to the passed-in vector
for( ; iter != end; ++iter )
{
list.push_back(iter->second);
}
}
void LLWearable::animateParams(F32 delta, BOOL upload_bake)
{
for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
++iter)
{
LLVisualParam *param = (LLVisualParam*) iter->second;
param->animate(delta, upload_bake);
}
}
LLColor4 LLWearable::getClothesColor(S32 te) const
{
LLColor4 color;
U32 param_name[3];
if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
{
for( U8 index = 0; index < 3; index++ )
{
color.mV[index] = getVisualParamWeight(param_name[index]);
}
}
return color;
}
void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
{
U32 param_name[3];
if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
{
for( U8 index = 0; index < 3; index++ )
{
setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
}
}
}
void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
{
if (!avatarp) return;
// Pull params
for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
{
// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
{
S32 param_id = param->getID();
F32 weight = getVisualParamWeight(param_id);
avatarp->setVisualParamWeight( param_id, weight, FALSE );
}
}
}
std::string terse_F32_to_string(F32 f)
{
std::string r = llformat("%.2f", f);
S32 len = r.length();
// "1.20" -> "1.2"
// "24.00" -> "24."
while (len > 0 && ('0' == r[len - 1]))
{
r.erase(len-1, 1);
len--;
}
if ('.' == r[len - 1])
{
// "24." -> "24"
r.erase(len-1, 1);
}
else if (('-' == r[0]) && ('0' == r[1]))
{
// "-0.59" -> "-.59"
r.erase(1, 1);
}
else if ('0' == r[0])
{
// "0.59" -> ".59"
r.erase(0, 1);
}
return r;
}

View File

@@ -27,48 +27,35 @@
#ifndef LL_LLWEARABLE_H
#define LL_LLWEARABLE_H
#include "lluuid.h"
#include "llstring.h"
#include "llavatarappearancedefines.h"
#include "llextendedstatus.h"
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "llwearabletype.h"
#include "llfile.h"
#include "lllocaltextureobject.h"
class LLViewerInventoryItem;
class LLMD5;
class LLVisualParam;
class LLTexGlobalColorInfo;
class LLTexGlobalColor;
class LLAvatarAppearance;
// Abstract class.
class LLWearable
{
friend class LLWearableList;
//--------------------------------------------------------------------
// Constructors and destructors
//--------------------------------------------------------------------
private:
// Private constructors used by LLWearableList
LLWearable(const LLTransactionID& transactionID);
LLWearable(const LLAssetID& assetID);
public:
LLWearable();
virtual ~LLWearable();
//--------------------------------------------------------------------
// Accessors
//--------------------------------------------------------------------
public:
const LLUUID& getItemID() const;
const LLAssetID& getAssetID() const { return mAssetID; }
const LLTransactionID& getTransactionID() const { return mTransactionID; }
BOOL FileExportParams(FILE* file);
BOOL FileExportTextures(FILE* file);
LLWearableType::EType getType() const { return mType; }
void setType( LLWearableType::EType type );
void setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);
const std::string& getName() const { return mName; }
void setName( const std::string& name ) { mName = name; }
const std::string& getDescription() const { return mDescription; }
@@ -82,39 +69,36 @@ public:
LLAssetType::EType getAssetType() const;
S32 getDefinitionVersion() const { return mDefinitionVersion; }
void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
static S32 getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; }
public:
typedef std::vector<LLVisualParam*> visual_param_vec_t;
BOOL isDirty() const;
BOOL isOldVersion() const;
void writeToAvatar();
void removeFromAvatar( BOOL upload_bake ) { LLWearable::removeFromAvatar( mType, upload_bake ); }
static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );
virtual void writeToAvatar(LLAvatarAppearance* avatarp);
BOOL FileExportParams(FILE* file) const;
BOOL FileExportTextures(FILE* file) const;
enum EImportResult
{
FAILURE = 0,
SUCCESS,
BAD_HEADER
};
BOOL exportFile(LLFILE* file) const;
BOOL importFile(LLFILE* file);
void setParamsToDefaults();
void setTexturesToDefaults();
void saveNewAsset() const;
static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
void copyDataFrom(const LLWearable* src);
EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp );
virtual BOOL exportStream( std::ostream& output_stream ) const;
virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
void setItemID(const LLUUID& item_id);
virtual const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
LLLocalTextureObject* getLocalTextureObject(S32 index);
const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
void setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
void addVisualParam(LLVisualParam *param);
void setVisualParams();
void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
F32 getVisualParamWeight(S32 index) const;
LLVisualParam* getVisualParam(S32 index) const;
@@ -124,27 +108,21 @@ public:
LLColor4 getClothesColor(S32 te) const;
void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
void revertValues();
void saveValues();
void pullCrossWearableValues();
virtual void revertValues();
virtual void saveValues();
BOOL isOnTop() const;
// Something happened that requires the wearable to be updated (e.g. worn/unworn).
virtual void setUpdated() const = 0;
// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
void setLabelUpdated() const;
// Update the baked texture hash.
virtual void addToBakedTextureHash(LLMD5& hash) const = 0;
// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
// not the wearable asset itself.
void refreshName();
private:
protected:
typedef std::map<S32, LLLocalTextureObject*> te_map_t;
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
void createLayers(S32 te);
void createVisualParams();
void syncImages(te_map_t &src, te_map_t &dst);
void destroyTextures();
void destroyTextures();
void createVisualParams(LLAvatarAppearance *avatarp);
void createLayers(S32 te, LLAvatarAppearance *avatarp);
static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
@@ -152,18 +130,16 @@ private:
std::string mDescription;
LLPermissions mPermissions;
LLSaleInfo mSaleInfo;
LLAssetID mAssetID;
LLTransactionID mTransactionID;
LLWearableType::EType mType;
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject
te_map_t mSavedTEMap; // last saved version of TEMap
LLUUID mItemID; // ID of the inventory item in the agent's inventory
};
#endif // LL_LLWEARABLE_H

View File

@@ -0,0 +1,363 @@
/**
* @file llwearabledata.cpp
* @brief LLWearableData class implementation
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llwearabledata.h"
#include "llavatarappearance.h"
#include "llavatarappearancedefines.h"
#include "lldriverparam.h"
#include "llmd5.h"
LLWearableData::LLWearableData() :
mAvatarAppearance(NULL)
{
}
// virtual
LLWearableData::~LLWearableData()
{
}
using namespace LLAvatarAppearanceDefines;
LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index)
{
//llassert_always(index == 0);
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return NULL;
}
wearableentry_vec_t& wearable_vec = wearable_iter->second;
if (index>=wearable_vec.size())
{
return NULL;
}
else
{
return wearable_vec[index];
}
}
void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
{
//llassert_always(index == 0);
LLWearable *old_wearable = getWearable(type,index);
if (!old_wearable)
{
pushWearable(type,wearable);
return;
}
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
llwarns << "invalid type, type " << type << " index " << index << llendl;
return;
}
wearableentry_vec_t& wearable_vec = wearable_iter->second;
if (index>=wearable_vec.size())
{
llwarns << "invalid index, type " << type << " index " << index << llendl;
}
else
{
wearable_vec[index] = wearable;
old_wearable->setUpdated();
const BOOL removed = FALSE;
wearableUpdated(wearable, removed);
}
}
U32 LLWearableData::pushWearable(const LLWearableType::EType type,
LLWearable *wearable)
{
if (wearable == NULL)
{
// no null wearables please!
llwarns << "Null wearable sent for type " << type << llendl;
return MAX_CLOTHING_PER_TYPE;
}
// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
// {
// mWearableDatas[type].push_back(wearable);
// wearableUpdated(wearable);
// checkWearableAgainstInventory(wearable);
// return mWearableDatas[type].size()-1;
// }
// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) )
{
// Don't add the same wearable twice
U32 idxWearable = getWearableIndex(wearable);
//RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere*
if (MAX_CLOTHING_PER_TYPE == idxWearable)
{
mWearableDatas[type].push_back(wearable);
idxWearable = mWearableDatas[type].size() - 1;
}
const BOOL removed = FALSE;
wearableUpdated(wearable, removed);
return idxWearable;
// [/RLVa:KB]
}
return MAX_CLOTHING_PER_TYPE;
}
// virtual
void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed)
{
wearable->setUpdated();
// FIXME DRANO avoid updating params via wearables when rendering server-baked appearance.
#if 0
if (mAvatarAppearance->isUsingServerBakes() && !mAvatarAppearance->isUsingLocalAppearance())
{
return;
}
#endif
if (!removed)
{
pullCrossWearableValues(wearable->getType());
}
}
void LLWearableData::popWearable(LLWearable *wearable)
{
if (wearable == NULL)
{
// nothing to do here. move along.
return;
}
U32 index = getWearableIndex(wearable);
const LLWearableType::EType type = wearable->getType();
if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
{
popWearable(type, index);
}
}
void LLWearableData::popWearable(const LLWearableType::EType type, U32 index)
{
//llassert_always(index == 0);
LLWearable *wearable = getWearable(type, index);
if (wearable)
{
mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
const BOOL removed = TRUE;
wearableUpdated(wearable, removed);
}
}
bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b)
{
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return false;
}
wearableentry_vec_t& wearable_vec = wearable_iter->second;
if (0 > index_a || index_a >= wearable_vec.size()) return false;
if (0 > index_b || index_b >= wearable_vec.size()) return false;
LLWearable* wearable = wearable_vec[index_a];
wearable_vec[index_a] = wearable_vec[index_b];
wearable_vec[index_b] = wearable;
return true;
}
void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type)
{
llassert(mAvatarAppearance);
// scan through all of the avatar's visual parameters
for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam();
param;
param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam())
{
if( param )
{
LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
if(driver_param)
{
// parameter is a driver parameter, have it update its cross-driven params
driver_param->updateCrossDrivenParams(type);
}
}
}
}
U32 LLWearableData::getWearableIndex(const LLWearable *wearable) const
{
if (wearable == NULL)
{
return MAX_CLOTHING_PER_TYPE;
}
const LLWearableType::EType type = wearable->getType();
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
llwarns << "tried to get wearable index with an invalid type!" << llendl;
return MAX_CLOTHING_PER_TYPE;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
for(U32 index = 0; index < wearable_vec.size(); index++)
{
if (wearable_vec[index] == wearable)
{
return index;
}
}
return MAX_CLOTHING_PER_TYPE;
}
BOOL LLWearableData::isOnTop(LLWearable* wearable) const
{
if (!wearable) return FALSE;
const LLWearableType::EType type = wearable->getType();
return ( getTopWearable(type) == wearable );
}
const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
{
//llassert_always(index == 0);
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return NULL;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
if (index>=wearable_vec.size())
{
return NULL;
}
else
{
return wearable_vec[index];
}
}
LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
{
U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
}
const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
{
U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
}
LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
{
if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
}
const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
{
if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
}
U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
{
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return 0;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
return wearable_vec.size();
}
U32 LLWearableData::getWearableCount(const U32 tex_index) const
{
const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
return getWearableCount(wearable_type);
}
LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
{
LLUUID hash_id;
bool hash_computed = false;
LLMD5 hash;
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
const LLWearableType::EType baked_type = baked_dict->mWearables[i];
const U32 num_wearables = getWearableCount(baked_type);
for (U32 index = 0; index < num_wearables; ++index)
{
const LLWearable* wearable = getWearable(baked_type,index);
if (wearable)
{
wearable->addToBakedTextureHash(hash);
hash_computed = true;
}
}
}
if (hash_computed)
{
hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
if (!generate_valid_hash)
{
invalidateBakedTextureHash(hash);
}
hash.finalize();
hash.raw_digest(hash_id.mData);
}
return hash_id;
}

View File

@@ -0,0 +1,106 @@
/**
* @file llwearabledata.h
* @brief LLWearableData class header file
*
* $LicenseInfo:firstyear=20012license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_WEARABLEDATA_H
#define LL_WEARABLEDATA_H
#include "llavatarappearancedefines.h"
#include "llwearable.h"
#include "llerror.h"
class LLAvatarAppearance;
class LLWearableData
{
// *TODO: Figure out why this is causing compile error.
//LOG_CLASS(LLWearableData);
//--------------------------------------------------------------------
// Constructors / destructors / Initializers
//--------------------------------------------------------------------
public:
LLWearableData();
virtual ~LLWearableData();
void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; }
protected:
//--------------------------------------------------------------------
// Accessors
//--------------------------------------------------------------------
public:
LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
LLWearable* getTopWearable(const LLWearableType::EType type);
const LLWearable* getTopWearable(const LLWearableType::EType type) const;
LLWearable* getBottomWearable(const LLWearableType::EType type);
const LLWearable* getBottomWearable(const LLWearableType::EType type) const;
U32 getWearableCount(const LLWearableType::EType type) const;
U32 getWearableCount(const U32 tex_index) const;
U32 getWearableIndex(const LLWearable *wearable) const;
BOOL isOnTop(LLWearable* wearable) const;
static const U32 MAX_CLOTHING_PER_TYPE = 5;
//--------------------------------------------------------------------
// Setters
//--------------------------------------------------------------------
protected:
// Low-level data structure setter - public access is via setWearableItem, etc.
void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable);
virtual void wearableUpdated(LLWearable *wearable, BOOL removed) = 0;
void popWearable(LLWearable *wearable);
void popWearable(const LLWearableType::EType type, U32 index);
bool swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b);
private:
void pullCrossWearableValues(const LLWearableType::EType type);
//--------------------------------------------------------------------
// Server Communication
//--------------------------------------------------------------------
public:
LLUUID computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
BOOL generate_valid_hash = TRUE);
protected:
virtual void invalidateBakedTextureHash(LLMD5& hash) const = 0;
//--------------------------------------------------------------------
// Member variables
//--------------------------------------------------------------------
protected:
LLAvatarAppearance* mAvatarAppearance;
typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
wearableentry_map_t mWearableDatas;
};
#endif // LL_WEARABLEDATA_H

Some files were not shown because too many files have changed in this diff Show More