Thursday, June 26, 2008

About straight and premultiplied channels


Practical advice for developers
(from DVD-HQ.info)




This section is aimed mainly at software developers, but regular users should read it too, because it shows how simple it is to deal with these issues from a programming point of view.




It might sound a bit self-righteous to write an article telling Photoshop's or 3dsmax's programmers how to do their job but... well, someone has to, because it's pretty obvious they aren't going to get it right by themselves (both are up to version 9, and are still lacking basic alpha channel conversion abilities).




First, here are the formulas to convert between matted and non-matted alpha. They can deal with any matte colour and are easy to implement for any colour depth and in any language. The variables used in the formulas are:




Cm = Component (matted)

Cu = Component (unmatted)

Cb = Component (background / matte colour)

a = Alpha

amax = Maximum possible alpha value (ex., 1.0)




All values are assumed to vary between 0.0 and 1.0 (for 8-bit files this would be 0-255 and for 16-bit files it would be 0-65535; remember to divide by the scale if you use anything other than 0.0-1.0).




To convert from unmatted alpha to matted alpha:




Cm = ( Cu ∙ a ) + [ Cb ∙ ( amax - a ) ]




To convert from matted alpha to straight (unmatted) alpha:





If a = 0, then Cu = Cm

Else, Cu = [ Cm - Cb ∙ ( amax - a ) ] / a




The formulas should be applied once to each colour component (ex.: R, G and B) of each pixel.




Those formulas are enough to add support for alpha channel conversion (with any matte colour) to any application. The software can then either cache a "working format" version of the image (generally meaning a straight-alpha version) or it can perform the conversion whenever it needs to read a pixel's colour channel values. There is really no excuse for not including this basic ability in a professional-level application.




The second issue is how to determine the kind of alpha channel used by a file that the user has just imported. One solution is to simply ask the user, but that's a pretty poor solution; users have more important things to worry about. So let's look at how software can determine the type of alpha channel and, if it turns out to be a matted alpha channel, how it can determine the background colour.




First we look for a pixel that is 100% transparent (0% opaque). If one exists, store its RGB values. Look for another pixel that is 100% transparent. Compare its RGB values with the ones previously stored. Repeat until the end of the file. If all pixels with 0% opacity have the same RGB values, it's almost guaranteed that that colour is the one used for the matte (if indeed there is a matte). If the colour varies, there's a good chance that we're looking at a straight-alpha file, or that the file uses some sort of really weird encoding (like the background bitmap example given above).




Now, even if all 100% transparent pixels have exactly the same colour, the file might still use "straight" alpha, so it's time to take the "background" RGB values we found above, plug them into the matted / unmatted conversion formulas and see if they make sense.




No pixel can have less of the matte colour in its RGB values than its alpha value would allow. For example, a colour channel in a pixel that is only 10% opaque cannot deviate more than 10% from the same channel of the matte colour.




If this condition isn't met by every pixel in the file, then there is no matte. If it is met by every pixel in the file, there's a very good chance that there is a matte, using the background colour we determined earlier.




There are other ways to make these decisions, some of which are simpler, faster, and will also get it right most of the time (for example, the program might analyse only a few pixels, rather than every pixel in the image).




Software should perform these tests when a file is first imported, and use the results to pre-fill the source format (or "footage interpretation") settings. This means that, in 99% of cases, the user will only need to click "ok".




If the tests are inconclusive (ex., because there are no transparent pixels in the file), then the software should ask the user to make the choice.




In any case, the user should always be given the option to toggle the type of alpha channel (between straight and matted), to pick the matte colour (manually or from the image) or to have the software "guess" the alpha channel type and matte colour again. These options should be available at any moment; not just when the file is first imported. If the software uses working proxies, a change of source format settings would cause the file to be re-imported.



(end of quote from DVD-HQ.info © Rui del-Negro 2008)

Friday, June 20, 2008

AS3 Flash 3D Engine Aletrnativa Platforms Drops A Nuke - Isometric and FPS

Alternativa Platform,

http://blog.alternativaplatform.com/en/2008/04/18/alternativa3d-5-m1/

previously Alternativa Game, launched their Alternativa Platform milestone 1 and really one demo would have been enough but there are some great demos there that literally put them what appears a couple laps up on the 3d FPS style engine in Flash.

The engine is highly optimized and smooth, heavy on the processor, but using the ‘t’ key you can see some nice revealing triangle rendering. Also, playing with the field of view adds for some nice game effects. (try jumping on the fans in the half-life like room in the first demo)

iPhone and Flash

http://www.crunchgear.com/2008/06/17/adobe-already-has-iphone-version-of-flash-running-on-emulator/


Adobe already has a version of Flash for the iPhone running on emulation software, and would, fingers crossed, be able to bring that over to the phone itself if Apple allowed it. That’s what Adobe said yesterday at its Q2 conference call. Or:

We have a version that’s working on the emulation. This is still on the computer and you know, we have to continue to move it from a test environment onto the device and continue to make it work. So we are pleased with the internal progress that we’ve made to date.

But will Apple allow Flash for the iPhone? Steve Jobs has claimed in the past that the mobile version of Flash—presumably what Adobe would be porting over to the iPhone—isn’t powerful enough for use on the nimble and elegant iPhone. Integration with Safari?

This leaves Adobe, if it wants a piece of that sweet, sweet iPhone market, with a few options. It could simply release a stand-alone Flash application on the upcoming App Store, but that would be cumbersome to say the least. One of the big reason why Flash is so popular is because it “just works” in a browser. No having to download Hulu videos to your hard drive in order to view them, for example.

Adobe could also, somehow, convince Apple to let it release a plugin for Safari. That’d be the most seamless for consumers.

Adobe has always take advantage of QuicktTime API and now QTKit so there is really no reason why Flash won't be fast on the iPhone

XMP Metadata, XFL and Flash = Complete End To End Solution

XFL

Since its inception, the Flash authoring tool has stored documents in a binary source-file called .fla. Historically, interchanging source with the Flash authoring tool has been virtually impossible for third-party software because the specification for .fla has never been public. But things are changing in the next version of Flash. Flash CS4 will be able to export *and* import a new source format called XFL. An XFL file is a .zip file that contains the source material for a Flash document. Within the .zip file resides an XML file describing the structure of the document and a folder with the document's assets (graphics, sounds, etc). The exact details of the XFL format are not yet available, but Richard assures me that Adobe intends to document them publicly, allowing third-party tools to import and export XFL.

So in theory, you might one day edit the images of an XFL file directly in Photoshop without disturbing the timeline information also contained in that file. Or you might be able to import a page from a word processing document into a Flash presentation.

But perhaps even more exciting is the potential for the smaller, grass-roots community. Being XML-based, the new XFL format should be fairly easy to understand and generate. That means any small tool company, web agency, or even independent developer will be able to create a purpose-built authoring tool that can output XFL. Of course, the XFL file would then need to be opened in the Flash authoring tool for final .swf export. But a .jsfl script should be able to ease the workflow between an XFL-generating tool and the Flash-authoring .swf-compilation process.

The natural next step in the evolution of XFL authoring would be to take the Flash authoring tool out of the equation altogether. If Adobe were to offer a command-line XFL-to-SWF compiler along with XFL, nearly any decent programmer would be able to create a .swf-authoring tool, even in ActionScript. The Flash developer community itself would finally be able to create its own custom Flash-authoring tools. I wonder who would be the first to nostalgically make Flash 4 for AIR in ActionScript?

XFL might not have the instant appeal of inverse kinematics, but it could eventually prove to be the feature in Flash CS4 that has the greatest impact on the Flash industry. After all, its name has an "X' in it.

http://www.moock.org/blog/archives/000269.html

XMP

http://www.adobe.com/products/xmp/indepth.html

FLASH AS3 AND VIDEO for WebAnalytics

http://blog.ickydime.com/2008/05/flash-analytics-deep-linking-and-seo.html

You may be interested to read more about interactive video in Flash CS4 as well

http://younsi.blogspot.com/2008/12/interactive-video-in-flash-using-f4v.html

Thursday, June 05, 2008

how to disable intellisense

For those few folks who work with huge source code more than 500 000 line of code and have big project you might want to disable intellisense. Why because
If I try to debug flash while intellisense process is running in the background, it crashes Visual Studio 2005....which force me to wait for intellisense to be complete when i launch my project or anytime intellisense has decided to start processing things again...
Not sure what is the advantage of intellisense... but for those who want to disable it :

In VS 2005 it can be done by renaming or deleting the following file:
\VC\vcpackages\feacp.dll

Or

You can also control IntelliSense through macros, allowing you to enable/disable IntelliSense without restarting VS or renaming files. See this blog article for the macro details: http://blogs.msdn.com/vcblog/archive/2007/11/19/controlling-intellisense-through-macros.aspx

Thursday, April 10, 2008

Pros and cons of automatic update

Pros and cons of automatic update


Lately Microsoft has decided to push Silverlight on Vista SP1 and will certainly do the same things with Microsoft XP SP3. Nothing wrong about that. I have no objection with Automatic update at all since it is a great way to increase user experience but... only if the user has the choice... By combining all there fix in a Service pack they just find a way to update there platform.... When you install a software you can always see the software through the Add Remove Program for instance this is a good practice for stand alone runtime such as Visual Studio Runtime, .Net, Flash Player Active X Control, Air Runtime. But why Microsoft don't give this Option when user install the Service Pack.... Why not offering some component selection to the end user instead of installing a bunch of file with no report of what was really installed. Apple on Mac OSX offer this feature right(give the user a choice ). What i recommend is not to use automatic update or service Pack but rather check for available update and pick the one you really need or want !

Finally what i like with semi automatic update is not to seat in the tray icon and use my CPU but just be invoked by the application who need the service of the updater one time, ask the user.

Rebooting an XP machine and have to wait for udpates is not OPT-IN at ALL !

Tuesday, April 08, 2008

According to University of Utah researchers, using a larger monitor could save you 2.5 hours per day.

This study below suggests that your wall LCD would do wonders in the office. I hear people turn them on the side, for a portrait display, and they can look up and down the monitor at multiple documents.

According to University of Utah researchers, using a larger monitor could save you 2.5 hours per day.

Specifically, test subjects completed everyday tasks like editing documents and massaging spreadsheets 52% faster when using a 24-inch monitor than they did with an 18-incher.

http://www.fourhourworkweek.com/blog/2008/03/15/size-does-matter-bigger-monitors-save-25-hours-a-day/

How to add automatic updater to a null soft installer and the pros and cons of automatic updates

I really think that when it comes to windows installer the most convenient and easy to use installer suite available on the market is nullsoft installer.
To build an installer you only need to write a UTF-8 script using your favorites editor. When it comes to automatic update i really like a software written by a smart guy in Netherland. The updater can be purchase from http://www.catenalogic.com/

Once you get the updater you need to hook the updater into your installer.
To do so you need to provide a way to check for update from the start menu
using a shortcut towards the updater.exe. Your application should also execute the updater as well once in a while (periodic perdiod) or during each startup.

Here is what you need to add to your null soft script to provide a complete end to end update solution to you application.

First you need to compress the updater files and custom graphics such as top banner and left bitmap. Be carefull, the size of the graphics element are very important. One pixel off and you will see the default graphics instead.

!define CLIENT_VERSION "1.0"
!define CLIENT_NAME "MyHelloWorld Sample Application"
!define PRODUCT_NAME "${CLIENT_NAME}"
!define PRODUCT_VERSION "1.0.0.0"
!define SETUP_FILE "setup_1_0.exe"

!define APP_FILE1 "..\files\HelloWorld.exe"
!define UPDATER_FILE1 "..\files\updater.exe"
!define UPDATER_FILE2 "..\files\updaterbanner.bmp"
!define UPDATER_FILE3 "..\files\updaterleft.bmp"


Inside the Installer section of your script
you need to add script code to uncompress and copy the updater files
inside the target program file folder for your application. The one choosen
by the user or set by default under Program Files.

;script start

SetOverwrite ifnewer

CreateDirectory "$PROGRAMFILES\MyApp"

SetOutPath "$PROGRAMFILES\MyApp"

;HelloWorld.exe application file
File "${APP_FILE1}"

;UPDATER FILES TO EXTRACT
File "${UPDATER_FILE1}"
File "${UPDATER_FILE2}"
File "${UPDATER_FILE3}"

;you need to generate and update the settings.ini file
;used by the updater.exe so that the updater will know where to download
;the XML file on the update server. The updater will compare your
;application version set in the ini with the one available on the remote
;server. Because this call is self contain in the installer once you will
;uninstall and install a new version it will automatically update the up to
;date settings.ini

;Update Updater INI file with installation application path and product version
FileOpen $1 "$INSTDIR\settings.ini" w
;FileSeek $1 0 END $INI_SIZE
FileWrite $1 "[UPDATER]$\r$\n"
FileWrite $1 "runmode=full$\r$\n"
FileWrite $1 "logolarge=updaterleft.bmp$\r$\n"
FileWrite $1 "logosmall=updaterbanner.bmp$\r$\n"
FileWrite $1 "customnotification=false$\r$\n"
FileWrite $1 "[UPDATEINFO]$\r$\n"
FileWrite $1 "URL=http://www.yourwebserverforupdate.com/download/HelloWorld/full/update.xml$\r$\n"

;as you see the update.xml will provide a way for updater to get http path
;for update along with command (action) to execute in a chronological order.
;I will post a sample XML file in an other article.

FileWrite $1 "servertimeout=2000$\r$\n"
FileWrite $1 "[APPLICATION]$\r$\n"

StrCpy $KEY "name="
FileWrite $1 $KEY
StrCpy $VALUE "${PRODUCT_NAME}"
FileWrite $1 $VALUE
FileWrite $1 "$\r$\n"

StrCpy $KEY "version="
FileWrite $1 $KEY
StrCpy $VALUE ${CLIENT_VERSION}
FileWrite $1 $VALUE
FileWrite $1 "$\r$\n"

StrCpy $KEY "location="
FileWrite $1 $KEY
StrCpy $VALUE $INSTDIR\HelloWorld.exe
FileWrite $1 $VALUE
FileWrite $1 "$\r$\n"

FileWrite $1 "[PROXY]$\r$\n"
FileWrite $1 "type=autodetect$\r$\n"

FileClose $1

;last things you need to do is to create a shortcut.
;Te cool things with nullsoft when you create a shortcut is that
;it will use the last SetOutPath call as the working directory for your
;shortcut. Alternatively you can specify the path of the settings.ini

StrCpy $STARTMENU_FOLDER "MyHelloWorldApplication"

SetOutPath "$PROGRAMFILES\HelloWorld"
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Check for update.lnk" "$INSTDIR\updater.exe"

In your application code you will launch updater.exe from your application folder.
You can also read a registry key to get a custom path. This registry key will be set by the installer itself.



Finally what i like with semi automatic update is not to seat in the tray icon and use my CPU but just be invoked by the application who need the service of the updater one time, ask the user.



Hope you will find this Null Soft Updater Script for catenalogic useful !

Monday, March 17, 2008

Microsoft has licensed Flash Lite

Microsoft Corp. has licensed Adobe Systems Inc.'s software that lets cell phone users view online videos and other files, the companies said Monday.

Redmond, Wash.-based Microsoft (NASDAQ:MSFT) will distribute San Jose-based Adobe's (NASDAQ:ADBE) Flash Lite and Reader programs through cell phones that use its Windows Mobile software.

Financial terms of the deal were not disclosed, but the programs will be free for users.

Adobe said that more than half a billion mobile devices have shipped with Flash preinstalled, indicating 150 percent growth year over year.

Friday, February 22, 2008

Adobe Media Player

Adobe media player using AIR is out and the user experience is really cool
particully when hooked to a Plasma or LCD TV screen.
Everyone can enjoy playback of H264 and of course HD.

http://labs.adobe.com/technologies/mediaplayer/install/

For a full experience i recommend a Wireless Keyboard such as Apple
http://www.apple.com/keyboard/ or microsoft Wireless Entertainment Desktop 8000

Finally for those who want to encode MPEG2 HD content i recommend the On Air Solution USB adapter

Friday, January 25, 2008

Wurlf and Flash Lite

http://wurfl.admob.com/apache2-default/ts/flashlite/

How to detect Mobile device hitting your Web Server in PHP

by Andrea Trasatti

http://wurfl.sourceforge.net/index.php

PHP is a great platform for WAP development. Thousands of developers worldwide love PHP for its performance and for the semplicity of its model.
It should come as no surprise that some PHP developer quickly built the tools to tap the WURFL power from PHP.

One easy way to play with the WURFL, is to use what I call the "WURFL PHP Library". The package includes the library and some support files such as a readme (I STRONGLY SUGGEST EVERYONE TO READ IT), check_wurfl.php that will let you quickly read all the capabilities of a selected device and update_cache.php which will be better described later.

* wurfl_parser.php: parse the xml and put it in an Array and the other to work with the data collected. Before starting, make sure you have compiled PHP properly ( http://www.php.net/manual/en/ref.xml.php ), wurfl_parser.php uses the basic XML functions implemented compiling with expat.
* wurfl_class.php: this script lets you access the data in the wurfl array (see previous bullet) in an object-oriented fashion.
* wurfl_config.php: with the growing number of possible configurations in the PHP library, I am now introducing a single file for configuration. This should hopefully make it clearer where you need to configure the scripts and maybe also make it easier to integrate it with your central configuration files (if your application has any)


wurfl_parser.php

wurfl_parser.php: This is a VERY simple XML parser that reads WURFL and puts all the needed data into an array. Considering the time the parser was taking to parse the XML, I thought that using some kind of caching mechanism was probably a good idea. This will be discussed more later.
The generated Array is an associative array that looks like this:

$wurfl["devices"]["ericsson_generic"]["fall_back"]="generic";

The first key is "devices". Other possible values such as authors and contributors are probably not so interesting to you.

The second key is the UNIQUE ID assigned to each user agent. All other keys are related to the attributes or groups and capabilities of the device.

Of course, this may seem not so flexible in practice, since devices tell us their user-agent strings, not their WURFL IDs.
This is solved thanks to an additional array called $wurfl_agents, which is simply an associative array of user agents and the relative unique id. This array makes your life much simpler (and your search much faster). $wurfl_agents is cached too.
Let's look at a concrete example. Someone visits you site with, say, a Siemens S45 (user agent: "SIE-S45/24 UP.Browser/5.0"). In order to find the device ID, you would normally be required to cycle most of the $wurfl array and retrieve the ID, before you can look up the actual capabilities.
Thanks to $wurfl_agent, this is as simple as:

if ( in_array($id, $wurfl_agents) ) {
echo "The ID $id is known
\n";
}

Example to search an ID knowing the user agent:

$wurfl_user_agents = array_keys($wurfl_agents);
while ( $x = each($wurfl_user_agents) ) {
if ( $x[1] == $user_agent ) {
return $wurfl_agents($x[1]);
}
}


wurfl_class.php

wurfl_class.php was created to make our life simpler. Once we had the data ready in an array, we needed an easy way to access it and some methods to manipulate it. By looking closely at what had been done with the Java API, I reproduced many of those useful methods in PHP.

The class loads the parser automatically. To load the parser a defined must be set appropriately in the config file.

The class is initialized calling the constructor, wurfl_class and passing two variables that may be empty. The former is the full XML parsed (like the parser does) and the latter is the array of user agents and id's as generated by the parser. Pass two empty variables (or nothing) if you want them to be filled (when needed) or the real values if you already have them. The class will check the values and the cache files (if enabled) and decide what to do. Also check your configuration, because the behaviour will change.
Use the public method GetDeviceCapabilitiesFromAgent() passing the user agent to make the class search for the best fit and fill the object's properties. Once again, what the class does depends on your configuration, if you enabled cache files and so on.
Once you have instantiated the object and passed a user agent you may use all the class' methods.
Here is a list of properties:

$wurfl_class->_wurfl is the WURFL array (all of it)

$wurfl_class->_wurfl_agents is the associative array made of the user agents
and unique id's

$wurfl_class->user_agent the visitor's user agent

$wurfl_class->wurfl_agent the WURFL's best fitting user agent

$wurfl_class->id the corresponding id

$wurfl_class->GUI true if the device supports Openwave's GUI
extensions

$wurfl_class->browser_is_wap true if the device is WAP capable. It is here
only for legacy support, you should use the
is_wireless_device capability from WURFL.
browser_is_wap now has the same value as the
capability, when found. If you want to take full
advantage of this capability you should download
the web patch from the WURFL site or CVS!
$wurfl_class->capabilities the array of device's capabilities

Note: PHP (up to version 4.3) does not have any distinction between private and public methods. In the wurfl_class implementation, I named all private methods with a leading underscore to distinguish them from public methods without the underscore. If you are interested in knowing the details, just open the class, there are beautiful JAVADOC-like comments for each variable and method.
These libraries don't require register_globals anymore (from version 2 and up), but will not work with versions before 4.1.

wurfl_class($wurfl, $wurfl_agents) is the constructor. Built to work
best with the wurfl_parser.

GetDeviceCapabilitiesFromAgent($ua) given a user agent it will search WURFL
for the best fit

getDeviceCapability($capability) given a capability it will tell you the
value. Remember that capabilities might be string,
integer or boolean.

wurfl_config.php

The scope of this file is straight forward, modify it at your wish to configure the library to act as you like it best.
Please check the paragraph about caching for more info about cache files.
Here is a quick explanation of all the fields:

WURFL_CONFIG boolean, this is set to true by default, it's used as a simple
check to make sure the configuration was included. Add this to your
configuration files if you won't use wurfl_config.php, otherwise just
leave it as it is

DATADIR string, where all data is stored (wurfl.xml, cache file, logs, etc)

WURFL_FILE string, full path and filename of wurfl.xml

WURFL_PARSER_FILE string, full path and filename of wurfl_parser.php

WURFL_CLASS_FILE string, full path and filename of wurfl_class.php

WURFL_USE_CACHE boolean, true if you want to use a cache file (strongly
suggested). If only this parameter is set to true will be used
cache.php.

WURFL_USE_MULTICACHE boolean, true if you want to use Multicache files
instead of a single BIG cache file (cache.php)

MULTICACHE_DIR string, used only if you enabled Multicache, defines where
the cache files will be stored. WARNING: while cache.php will grow
in size but remain a single file, here the files will grow in
number. Expect more than 5000 tiny files.

MULTICACHE_SUFFIX string, suffix for the files generated using Multicache.
Useful if you use a caching system and don't want to load your
shared memory with a ton of tiny files.

CACHE_FILE string, with full path and filename of the cache file to use
(refreshed when a new WURFL is found, if WURFL_CACHE_AUTOUPDATE is
set to true)

WURFL_CACHE_AUTOUPDATE boolean, tells the class to automatically update the
cached files with a new XML is found. This is NOT suggested when
using MULICACHE because of the high number of files to be updated.
Race conditions are highly possible to happen. The use of
update_cache.php is strongly suggested for production
environments

WURFL_PATCH_FILE string, optional patch file for WURFL

WURFL_AGENT2ID_FILE string, used by wurfl_class.php. Used only when
WURFL_USE_CACHE is set to true

MAX_UA_CACHE integer, max number of user agents to store in
WURFL_AGENT2ID_FILE. Too high limits might give the opposite effect.

WURFL_LOG_FILE string, defines full path and filename for logging

LOG_LEVEL integer, desired logging level. Use the same constants as for PHP
logging

WURFL_AUTOLOAD boolean, true if you want the XML to be loaded at every
startup. If not, the XML will be loaded when needed.


Caching

Considering how slow PHP can be when parsing a big XML file, caching was a must.
Currently there are two caching systems. The older is activated when setting WURFL_USE_CACHE to true and uses DATADIR to store its files. The concept is quite simple, dump the array generated by the parsers in a big file, by default called cache.php (set by the define CACHE_FILE). In this file we also store the array called $wurfl_agents and a timestamp, useful to check if a new XML was deployed.
This system is very simple in its concept and worked well for quite some time. Considering the big size that cache.php was reaching it became a need (and in fact I always strongly suggested it) to use a caching system at PHP-level, such as Zend Accelerator, Turck cache, APC 2.0. Using such tools lets you store the cache file (cache.php) into shared memory and provides really good performances from the third hit on (first hit the XML is parsed: slow, second hit the cache is stored in shared memory: slow, third hit and on the cache is read from the shared memory: fast!).

The new caching system was dubbed "multicache" because instead of generating a single big cache file it generates 1 cache file for every device in WURFL. For this reason you will need to create a directory for this (or at least this is suggested) because the library will generate about 6000 tiny files when this feature is activated.
To activate the multicache system you will need to set WURFL_USE_CACHE to true.
CACHE_FILE will still be used, but the file will only contain the array $wurfl_agents and the timestamp.
Also set WURFL_USE_MULTICACHE to true, set the appropriate path for MULTICACHE_DIR, an absolute path is suggested. Don't forget the ending slash (for example '/tmp/cache/multicache/').
MULTICACHE_SUFFIX should be left unchanged in most cases. This will define the extension of the tiny files. You might want to set some strange extension if you want to avoid that those files are cached in shared memory by any PHP-cache, for example. Change it only if you know what you're doing!
The multicache system provides a MUCH faster data retrival, files are smaller and so it will take a way less time to read them. This will also mean a higher I/O on your system, consider returning to the older cache system if you have problems. Generating many tiny files also involves possible race conditions if a new XML is deployed and the library is configured to update automatically the cache. Read on for more info.

If WURFL_CACHE_AUTOUPDATE is set to true the library (specifically wurfl_class.php) will check the timestamp in cache.php against the file mtime of wurfl.xml. If the XML is newer than the cache it is reloaded. This is not suggested for production environments, if you have many concurrent hits you might have more than one process trying to refresh the same cache wasting a lot of resources. If you would like to avoid this you can set the automatic update to false and use the 'ad hoc' script called update_cache.php. This script was created to be called from command line (or a hidden URL if you'd like, but the command line is suggested when available) and force a cache update. This way the cache update will be prepared and the file will be changed at the very last second saving a lot of resources and having a single process do it. On sites with MANY hits you might also consider preparing the cache files on a separated system and moving them to the production server at once. There isn't a sccript to do this automatically at this time, but the new update_cache.php is already a step in that direction.

When setting WURFL_USE_CACHE to true you also enable another simple caching system (active both when using standard cache and multicache). When a user agent hits your site, this will most likely hit it again a few times. It would be stupid to search for all its capabilities at every second hit. For this reason we store the user agent and its capabilities in a file named after the value set in WURFL_AGENT2ID_FILE, this will make every second hit A LOT faster.
Storing all the user agents hitting your site will end up having a second full cache file and the benefit would reach zero. For this reason you can define a limit of user agents stored using MAX_UA_CACHE. The "perfect" value will change depending on your server's performances on the variety of user agents visiting your site and so on. A good number is between 30 and 50. I suggest you to start with 30 and maybe check the logs and see how often the cache is cleaned of the elder user agents and how often a user agent that is still visiting your site is cleaned and researched.

It's a direct consequence of the cache system that you will not need to read the entire XML and parse it every time you start the wurfl object. You may still want to force this for debug reasons for example. You can do this setting to true the define named WURFL_AUTOLOAD. If you are using any of the caching systems, I suggest you to disable this. If you're not using any cache, the XML will be loaded anyway, so just set this to true, if you'd like.


Logging

While logging is out of the scope of the WURFL PHP Libraries and I suggest you to integrate the libraries with your logging system (if you have any), a basic logging feature is included. This should work fine on Linux, Solaris and Windows.
Logging is done on a file as configured with WURFL_LOG_FILE. The log level is defined following the PHP contants and using the define named LOG_LEVEL. It used to be buggy in previous releases, check out how it has changed and it is now supposed to work properly. When set with the highest level the library might generate a log of logs.
Logs should anyway give you all the info you might need. This is a sample log when set at the highest detail level:

[LuckyTitan.local 327][constructor] Class Initiated
[LuckyTitan.local 327][GetDeviceCapabilitiesFromAgent] searching for SonyEricssonZ600/R601
[LuckyTitan.local 327][_cacheIsValid] cache file is outdated
[LuckyTitan.local 327][GetDeviceCapabilitiesFromAgent] cache enabled, WURFL is not loaded, now loading
[LuckyTitan.local 327][GetDeviceCapabilitiesFromAgent] loading WURFL from XML
[LuckyTitan.local 327][parse] No XML patch file defined
[LuckyTitan.local 327][GetDeviceCapabilitiesFromAgent] Searching in the agent database
[LuckyTitan.local 327][_GetFullCapabilities] searching for sonyericsson_z600_ver1_subr601
[LuckyTitan.local 327][_GetDeviceCapabilitiesFromId] reading id:sonyericsson_z600_ver1_subr601
[LuckyTitan.local 327][_GetDeviceCapabilitiesFromId] I have it in wurfl_agents cache, done

Wednesday, December 19, 2007

How to detect if Visual Studio 2005 SP1 is installed on Windows

If you don't need to be specific about a particular Visual Studio 2005 SKU, you can detect SP1 for a particular written language (for VSTS and TFS) or for a particular project language (for Express SKUs) using an older registry key under,

HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{PatchCode}

You can find the {PatchCode} in the .msp file. In Windows 2003 and earlier platforms, you'll see this as the Revision number property in the properties Summary tab in Windows Explorer. In all cases, you can query the Summary Information stream or open the .msp file in Orca, then click the View -> Summary Information menu item.

For the English Visual Studio 2005 Service Pack 1 for Standard, Professional, and Team editions (VS80sp1-KB926601-X86-ENU) an example of the registry key above follows.

HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{D93F9C7C-AB57-44C8-BAD6-1494674BCAF7}

You can also determine the service pack level of a more general, larger scope by reading a REG_DWORD registry value named SP from under,

HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\[ProductFamily]\Servicing\8.0

…and for a specific language SKU using a sub-key,

HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\[ProductFamily]\Servicing\8.0\[ProductEdition]\[ProductLanguage]

Product families are pretty broad in scope, and include for "Whidbey":

URT (.NET Framework, once known as the Universal Runtime)
VB (Microsoft Visual Basic 2005 Express)
VC (Microsoft Visual C++ 2005 Express)
VCS (Microsoft Visual C# 2005 Express)
VJS (Microsoft Visual J# 2005 Express)
VNS (Microsoft Visual Web Developer 2005 Express)
VS (Visual Studio 2005 Standard, Professional, Team Suite, etc.)
VSTF (Visual Studio 2005 Team Foundation Services)
An example using the English Visual Studio 2005 Team Suite Service Pack 1 of the registry keys above follows. Under each key you would find a registry value named SP set to 1.

HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\VS\Servicing\8.0
HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\VS\Servicing\8.0\VSTS\1033

Visual Studio 2005 Express SKUs will always use the ProductEdition of EXP, so you can combine the ProductFamily values documented above with EXP to form registry keys like the following, for Visual C# 2005 Express.

HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\VCS\Servicing\8.0
HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\VCS\Servicing\8.0\EXP\1033

Sunday, December 16, 2007

Locking header control in MFC to prevent the column to be resized

The way to prevent sizing is to eat this notification (without passing it to the header control), but as with many other Windows® messages and notifications, HDN_BEGINTRACK comes in two flavors: HDN_BEGINTRACKW (wide-character, Unicode) and HDN_BEGINTRACKA (ANSI). The "neuter" symbol is #defined to one or the other of these, based on the value of UNICODE defined in your project, as shown here:

// From commctrl.h
#ifdef UNICODE
#define HDN_BEGINTRACK HDN_BEGINTRACKW
#else
#define HDN_BEGINTRACK HDN_BEGINTRACKA
#endif


So when you implement a handler for HDN_BEGINTRACK, you're actually implementing it for HDN_BEGINTRACKA or HDN_BEGINTRACKW, depending on the value of UNICODE. But which message does the header control actually send? Remember, the header control is part of Windows, one of the common controls in comctl32.dll. Since the DLL is already compiled into executable code, changing the value of UNICODE in your project has absolutely no effect on its operation. How does the header control know which flavor of notification to send—A or W?

The answer lies in an oft-forgotten message, WM_NOTIFYFORMAT. When a control is first created, it sends a message to its parent, in effect asking, "do you want ANSI or Unicode notifications?" The parent responds with NFR_ANSI or NFR_UNICODE. If the parent doesn't handle WM_NOTIFYFORMAT, the Windows DefWindowProc responds based on the preference of the parent window or dialog itself. The default is Unicode. So I suspect the reason you had no luck trapping HDN_BEGINTRACK is that you compiled an ANSI program without handling WM_NOTIFYFORMAT. Your application is looking for HDN_BEGINTRACKA (ANSI) while the header control is sending HDN_BEGINTRACKW (Unicode).

One way to fix the problem is to implement a WM_NOTIFYFORMAT handler for your list control, one that returns NFR_ANSI. When I tried this, the header control did indeed send HDN_BEGINTRACKA and I was able to prevent sizing. But using NFR_ANSI broke other features. For example, the list control no longer repaints its columns while sizing.

A simpler, more reliable way to prevent sizing header columns is to implement handlers for both HDN_BEGINTRACKA and HDN_BEGINTRACKW. This not only obviates the need to process WM_NOTIFYFORMAT, it lets your code work in both ANSI and Unicode modes.



The header control sends HDN_XXX notifications to the parent (list control) window, but when using MFC you can use message reflection to handle the notifications in the header itself. Since the "lockable columns" feature is more a property of the header than the list control, this is the approach I chose. If you're not using MFC, you'll have to handle these notifications in the list control. To do message reflection, you can use ON_NOTIFY_REFLECT in your header control's message map or simply override the virtual function OnChildNotify, as shown here:

BOOL CLockableHeader::OnChildNotify(
UINT msg, WPARAM wp, LPARAM lp, LRESULT* pRes)
{
NMHDR& nmh = *(NMHDR*)lp;
if (nmh.code==HDN_BEGINTRACKW || nmg.code==HDN_BEGINTRACKA)
return *pRes=TRUE;
•••
}


Since OnChildNotify is virtual, there's no need for message map entries. All you have to do is implement it. In any given application, the header will send one or the other, not both. Either way, CLockableHeader eats the notification—that is, returns TRUE (handled) without passing on to the default header control. CLockableHeader controls locking through a flag m_bLocked which the app can set by calling CLockableHeader::Lock.

If you're going to prevent sizing, you should also disable the size cursor. Otherwise users may think your app is either broken or lame. Fortunately, it's trivial:

BOOL
CLockableHeader::OnSetCursor(
CWnd* pWnd, UINT nHit, UINT msg)
{
return m_bLocked ? TRUE :
CHeaderCtrl::OnSetCursor(pWnd, nHit, msg);
}


In other words: if the columns are locked, OnSetCursor returns TRUE without setting the cursor; otherwise, let the header control do its size cursor thing. Now when the columns are locked, Windows displays its standard arrow cursor instead of displaying the left-right sizing cursor.

Once you've implemented your custom header control by deriving from CHeaderCtrl, how do you get Windows to use it? The same way you would for any dialog control, by subclassing. The right place is in the parent window's OnCreate handler:

// CMyView is derived from CListView
int CMyView::OnCreate(LPCREATESTRUCT lpcs)
{
VERIFY(CListView::OnCreate(lpcs)==0);
return m_header.SubclassDlgItem(0,this) ? 0 : -1;
}


This works because the header control always has ID = 0. With all this in place, the only thing left to do is implement the command and UI update handlers for the View | Lock Columns command.

Sunday, December 02, 2007

How lucky you are if you read this text

Docteur Phillip M Harter, Professeur à l'école de Médecine de l'Université de Stanford .

Si on pouvait réduire la population du monde en un village de 100 personnes tout en maintenant les proportions de tous les peuples existants sur la Terre, ce village serait ainsi composé :

57 asiatiques,

21 européens,

14 américains (Nord, Centre et Sud)

8 africains.

Il y aurait :

52 femmes et 48 hommes

30 blancs et 70 non blancs

30 chrétiens et 70 non chrétiens

89 hétérosexuels et 11 homosexuels

6 personnes posséderaient 59% de la richesse totale et tous les 6 seraient américains

80 vivraient dans des maisons vétustes

70 seraient analphabètes

50 souffriraient de malnutrition

1 serait en train de mourir

1 serait en train de naître

1 posséderait un ordinateur

1 (oui, un seulement) aurait un diplôme universitaire

Si on considère le monde de cette manière, le besoin d'accepter et de comprendre devient évident.

Prenez en considération aussi ceci :

Si vous vous êtes levé ce matin avec plus de santé que de maladie, vous êtes plus chanceux que le million de personnes qui ne verra pas la semaine prochaine.

Si vous n'avez jamais été dans le danger d'une bataille, la solitude de l'emprisonnement, l'agonie de la torture, l'étau de la faim, vous êtes mieux que 500 millions de personnes.

Si vous pouvez aller à l'église ou dans un temple sans peur d'être menacé, torturé ou tué, vous avez plus de chance que 3 milliards de personnes.

Si vous avez de la nourriture dans votre réfrigérateur, des habits sur vous, un toit sur votre tête et un endroit pour dormir, vous êtes plus riche que 75% des habitants de la Planète.

Si vous avez de l'argent à la banque, dans votre portefeuille ou de la monnaie dans une petite boite, vous faite partie des 8% les plus privilégiés du monde.

Si vos parents sont encore vivants et toujours mariés, vous êtes des personnes réellement rares.

Si, enfin, vous lisez ce message, vous venez de recevoir un double cadeau parce que quelqu'un a pensé à vous et parce que vous ne faites pas partie des deux milliards de personnes qui ne savent pas lire...

Monday, November 26, 2007

How to create a def file for a dll

you can still create a def file using the output from the objdump program (from the MinGW distribution). Here's an example.

objdump -p mydll.dll > mydll.fil

Search for "[Ordinal/Name Pointer] Table" in mydll.fil and use the list of functions following it to create your def file.

Wednesday, November 21, 2007

Upload Video to Youtube

I am finally on the verge to integrate a youtube uploader tool to one of my side project. I just need to figure out how to log to gmail instead of youtube since there is two ways to authenticate with youtube.

About youtube :

When you upload a video to YouTube, it automatically converts it to a flash video file (.flv) with specific settings (see below, standard column). The contrast of the video is increased and video noise is suppressed. YouTube appears to respect the framerate of the uploaded file; Framerates will varie between 15 (minimum framerate to tell it is a video...), 24 frames (pal) and 30 frames per second (ntsc with no drop frame). It is hard to tell how long you have to wait for the video to be available but it is pretty fast !!. Once the video has been uploaded you can log to your account and from there you can check the status of your video. Usually you will see Uploaded (processing, please wait).


Video Profile

standard recommended possible
file extension : .flv (flash video)
total bitrate : ~320 kbits/sec 804.7 kbits/sec 2147.2 kbits/sec
audio codec : MPEG layer 3 (MP3)
audio format : Mono, 22.050 kHz Stereo, 44.100 kHz Stereo, 44.100 kHz
audio bitrate : ~67 kpbs/sec 128 kpbs/sec 128 kpbs/sec
video codec : Sorenson Spark (H.263)
video format : 320 x 240 px, 15-30 fps 320 x 240 px, 29.97 fps 640 x 480 px, 29.97 fps
video bitrate : ~250 kbps/sec 677.7 kbps/sec 2019.2 kbps/sec

You can save your own .flv files and upload them to YouTube. You can encode video with higher bitrates and resolution than YouTube compresses with. The only limitations I can tell are that the file must be under 100 MB and you must use the Sorenson Spark video codec and MP3 audio codec.

Monday, November 19, 2007

How to take advantage of Silverlight Marker to create hypervideo

Interesting article from Jesse Liberty also i worked on Hypervideo back in 1999.... Silverlight is finally well suited to turn HD video into interactive sequences.

http://silverlight.net/blogs/jesseliberty/archive/2007/10/24/hypervideo-2.aspx

Wednesday, November 14, 2007

silent install of the VC 8.0 runtime (vcredist) packages

if you have downloaded the standalone VC 8.0 redistributable packages, you will need to modify the command lines slightly. The following command lines can be used to install the original release of the standalone VC 8.0 redistributable packages:

For x86: vcredist_x86.exe /q:a /c:"VCREDI~1.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
For x64: vcredist_x64.exe /q:a /c:"VCREDI~2.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
For ia64: vcredist_ia64.exe /q:a /c:"VCREDI~3.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
The following command lines can be used to install the Visual Studio 2005 SP1 release of the standalone VC 8.0 redistributable packages:

For x86: vcredist_x86.exe /q:a /c:"VCREDI~3.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
For x64: vcredist_x64.exe /q:a /c:"VCREDI~2.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
For ia64: vcredist_ia64.exe /q:a /c:"VCREDI~1.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
If you would like to install the VC runtime packages in unattended mode (which will show a small progress bar but not require any user interaction), you can change the /qn switch above to /qb. If you would like the progress bar to not show a cancel button, then you can change the /qn switch above to /qb!

Some folks ask me what vcredist.msi..
Iy means that you want to extract the embedded msi from the self exe package and be able to run msiexec which is used to install the package. msiexec is the Microsoft Installer runtime.
MSI is the prefered format for microsoft installer. Installshield and Visual Studio 2005 and higher can generate MSI. Using the msiexec command. You can even log all the installer session to a file and you can verify and explore the content of the MSI using ORCA in order to look at the installer sequence, string table and in some cases embedded Visual Basic Script. Yes Visual Basic is not dead. Still used and convnient enough for scripting installer code :)

If you want to install the runtime from a Null Soft Installer NSI script with minimal UI and progress bar, here is what you want to do

;extract selft exe to temp
SetOutPath "$TEMP"
; uncompress
File "${RUNTIME_VCREDIST}"



;-------------------------------
; Test if Visual Studio Redistributables 2005+ SP1 installed
; Returns -1 if there is no VC redistributables intstalled
Function CheckVCRedist
Push $R0
ClearErrors
ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7299052b-02a4-4627-81f2-1818da5d550d}" "Version"

; if VS 2005+ redist SP1 not installed, install it
IfErrors 0 VSRedistInstalled
StrCpy $R0 "-1"

VSRedistInstalled:
Exch $R0
FunctionEnd


Section "Installer Sections" SecDummy
SetOverwrite ifnewer
Call CheckVCRedist

;IntCmp $0 5 is5 lessthan5 morethan5
IntCmp $R0 -1 noVCRuntime noVCRuntime VCRuntime
;force install
; IntCmp $R0 -1 noVCRuntime noVCRuntime noVCRuntime

noVCRuntime:


;extract VCRuntime to Temp
SetOutPath "$TEMP"
File "${RUNTIME_VCREDIST}"

;/qn for complete silent install
;/qb small progress dialog but does not require any user interaction
;StrCpy $VC_RUNTIME "$\"$TEMP\vcredist_x86.exe$\" /q:a /c:$\"VCREDI~3.EXE /q:a /c:$\"$\"msiexec /i vcredist.msi /qb!$\""
StrCpy $VC_RUNTIME "$\"$TEMP\vcredist_x86.exe$\" /q:a"

;MessageBox MB_ICONINFORMATION 'Need to install VCRuntime {$R0} {$VC_RUNTIME}'

ExecWait '$VC_RUNTIME' $0
;MessageBox MB_ICONINFORMATION 'Return Code {$0}'
;IntCmp $0 0 done

;MessageBox MB_ICONINFORMATION 'install complete'

Delete "$TEMP\vcredist_x86.exe"

Goto VCRuntime

VCRuntime:

SectionEnd


http://blogs.msdn.com/astebner/archive/2007/02/07/update-regarding-silent-install-of-the-vc-8-0-runtime-vcredist-packages.aspx

Sunday, November 11, 2007